summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Source/C')
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/BrotliCompress.c587
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/GNUmakefile41
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/Makefile48
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BasePeCoff.c1469
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.c74
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.h61
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.c2191
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.h469
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Compress.h82
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.c313
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.h41
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.c1014
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.h159
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiCompress.c1591
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.c902
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.h164
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c1775
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBufferLib.h163
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.c927
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.h189
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/GNUmakefile33
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile36
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile.kmk63
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.c251
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.h105
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.c548
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.h209
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.c295
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.h133
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.c205
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.h120
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.c695
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.h220
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.c779
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.h185
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLib.h213
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLoaderEx.c334
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.c1429
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.h104
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.c413
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.h244
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/TianoCompress.c1746
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/WinNtInclude.h78
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePath.c194
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathFromText.c3524
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathUtilities.c868
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/GNUmakefile24
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/Makefile18
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c292
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h439
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.c1712
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.h353
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/GNUmakefile15
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GNUmakefile93
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GNUmakefile15
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GenCrc32.c361
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GNUmakefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GenFfs.c1120
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GNUmakefile23
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFv.c696
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.c4432
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.h402
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.c1177
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.h19
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.c1668
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.h19
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.c245
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.h81
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GNUmakefile23
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.c3255
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.h50
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile18
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile.kmk49
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf32.h252
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf64.h254
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf_common.h1045
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GNUmakefile23
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GenSec.c1818
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile18
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/AArch64/ProcessorBind.h148
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Arm/ProcessorBind.h147
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BaseTypes.h318
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BuildVersion.h9
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/MdeModuleHii.h233
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareFile.h350
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h157
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiBaseTypes.h168
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiCapsule.h26
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h1680
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiMultiPhase.h226
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/VariableFormat.h44
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h35
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PcAnsi.h52
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h39
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Ia32/ProcessorBind.h155
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi.h117
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi1_0.h285
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi2_0.h520
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi3_0.h668
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h56
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/EfiPci.h51
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h39
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/PeImage.h768
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci22.h536
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci23.h18
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci30.h38
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePath.h1404
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h288
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h187
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h145
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/HiiFramework.h944
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/UgaDraw.h161
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/RiscV64/ProcessorBind.h85
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/X64/ProcessorBind.h185
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/GNUmakefile27
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt3
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaCompress.c406
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaF86Compress.bat26
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile37
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile.kmk58
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c286
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h87
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c176
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h375
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h27
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c460
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h51
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra.h64
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c82
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h33
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h336
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c1127
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h121
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c853
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h101
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzHash.h57
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c1185
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h234
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c2976
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h76
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Precomp.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c95
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h72
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt446
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt357
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile69
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile.kmk54
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat40
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.py166
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/app.makefile22
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/footer.makefile30
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/header.makefile137
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/lib.makefile14
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.app28
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.common62
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.lib25
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.rule20
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/EfiCompressor.c206
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/Makefile18
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py37
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/GNUmakefile15
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.c2795
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.h431
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/EfiVfr.h44
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/GNUmakefile80
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile50
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile.kmk155
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_131.txt522
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133.txt2448
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt3666
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_SUMMARY.txt2049
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/KNOWN_PROBLEMS.txt241
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/MPW_Read_Me21
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/Makefile15
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.bcc184
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.msvc189
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/README159
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/RIGHTS26
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrDDK.mak233
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrMS.mak239
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrPPC.mak101
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/README19
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.1209
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.c3574
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.g2587
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.r787
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr1.txt264
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/bits.c1025
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/build.c813
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpcycles.c67
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpnode.c423
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/egman.c328
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/err.c538
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fcache.c123
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset.c1555
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset2.c2250
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c4797
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/generic.h286
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/globals.c484
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.c224
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.h73
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/lex.c878
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/main.c1747
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile225
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile.cygwin219
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile196
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/misc.c1864
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mode.h12
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mrhoist.c3030
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/parser.dlg1387
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/pred.c821
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/proto.h857
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/scan.c5735
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/stdpccts.h31
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/syn.h390
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/tokens.h246
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgDDK.mak121
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgMS.mak126
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgPPC.mak84
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/automata.c353
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.179
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.h250
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.r270
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg1.txt132
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_a.c1414
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.c970
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.g616
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/err.c99
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/main.c281
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile164
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile.cygwin157
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile163
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/mode.h4
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/output.c865
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/parser.dlg398
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c217
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/stdpccts.h26
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/support.c240
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/tokens.h133
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.cpp871
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.h376
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.cpp256
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.h122
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtr.h88
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtrImpl.h90
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AToken.h325
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.cpp374
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.h109
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenStream.h51
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.cpp100
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.h53
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLG_stream_input.h98
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexer.h194
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.cpp302
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.h202
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PBlackBox.h134
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.cpp684
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.h143
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/SList.h72
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/antlr.h807
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.c345
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.h121
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charbuf.h46
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.c58
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.h48
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/config.h1
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgauto.h504
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgdef.h128
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/err.h1173
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/int.h37
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_assert.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_iostream.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_istream.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_setjmp.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdarg.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdio.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdlib.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_string.h10
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcctscfg.h359
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcnames.bat11
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/slist.cpp116
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.ps473
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.txt186
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/makefile.old66
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk.c1063
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk_old.c762
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/makefile29
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/makefile19
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.c586
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.h30
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/test.c19
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.c816
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.h121
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/sym.c402
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/template.h41
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp941
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.h108
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.cpp297
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.h107
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp2457
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.h2776
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrSyntax.g5708
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp3921
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h538
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/GNUmakefile17
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile16
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile.kmk45
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.c2440
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.h31
321 files changed, 158311 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/BrotliCompress.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/BrotliCompress.c
new file mode 100644
index 00000000..e32b0c6b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/BrotliCompress.c
@@ -0,0 +1,587 @@
+/** @file
+ BrotliCompress Compress/Decompress tool (BrotliCompress)
+
+ Copyright (c) 2020, ByoSoft Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* Command line interface for Brotli library. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include "./brotli/c/common/constants.h"
+#include "./brotli/c/common/version.h"
+#include <brotli/decode.h>
+#include <brotli/encode.h>
+
+#if !defined(_WIN32)
+#include <unistd.h>
+#include <utime.h>
+#else
+#include <io.h>
+#include <share.h>
+#include <sys/utime.h>
+
+#if !defined(__MINGW32__)
+#define STDIN_FILENO _fileno(stdin)
+#define STDOUT_FILENO _fileno(stdout)
+#define S_IRUSR S_IREAD
+#define S_IWUSR S_IWRITE
+#endif
+
+#define fopen ms_fopen
+#define open ms_open
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#define fseek _fseeki64
+#define ftell _ftelli64
+#endif
+
+static FILE* ms_fopen(const char* FileName, const char* Mode) {
+ FILE* Result;
+ Result = NULL;
+ fopen_s(&Result, FileName, Mode);
+ return Result;
+}
+
+static int ms_open(const char* FileName, int Oflag, int Pmode) {
+ int Result;
+ Result = -1;
+ _sopen_s(&Result, FileName, Oflag | O_BINARY, _SH_DENYNO, Pmode);
+ return Result;
+}
+#endif /* WIN32 */
+
+
+#ifndef _MAX_PATH
+#define _MAX_PATH 500
+#endif
+
+#define DEFAULT_LGWIN 22
+#define DECODE_HEADER_SIZE 0x10
+#define GAP_MEM_BLOCK 0x1000
+size_t ScratchBufferSize = 0;
+static const size_t kFileBufferSize = 1 << 19;
+
+static void Version(void) {
+ int Major;
+ int Minor;
+ int Patch;
+ Major = BROTLI_VERSION >> 24;
+ Minor = (BROTLI_VERSION >> 12) & 0xFFF;
+ Patch = BROTLI_VERSION & 0xFFF;
+ printf("BrotliCompress %d.%d.%d\n", Major, Minor, Patch);
+}
+
+static void Usage() {
+ printf("Usage: %s [OPTION]... [FILE]...\n", __FILE__);
+ printf(
+"Options:\n"
+" -e, --compress compress\n"
+" -d, --decompress decompress\n"
+" -h, --help display this help and exit\n");
+ printf(
+" -o FILE, --output=FILE output file (only if 1 input file)\n");
+ printf(
+" -g NUM, --gap=NUM scratch memory gap level (1-16)\n");
+ printf(
+" -q NUM, --quality=NUM compression level (%d-%d)\n",
+ BROTLI_MIN_QUALITY, BROTLI_MAX_QUALITY);
+ printf(
+" -v, --version display version and exit\n");
+}
+
+static int64_t FileSize(const char* Path) {
+ FILE *FileHandle;
+ int64_t RetVal;
+ FileHandle = fopen(Path, "rb");
+
+ if (FileHandle == NULL) {
+ printf ("Failed to open file [%s]\n", Path);
+ return -1;
+ }
+ if (fseek(FileHandle, 0L, SEEK_END) != 0) {
+ printf ("Failed to seek file [%s]\n", Path);
+ fclose(FileHandle);
+ return -1;
+ }
+ RetVal = ftell(FileHandle);
+ if (fclose(FileHandle) != 0) {
+ printf ("Failed to close file [%s]\n", Path);
+ return -1;
+ }
+ return RetVal;
+}
+
+static BROTLI_BOOL HasMoreInput(FILE *FileHandle) {
+ return feof(FileHandle) ? BROTLI_FALSE : BROTLI_TRUE;
+}
+
+int OpenFiles(char *InputFile, FILE **InHandle, char *OutputFile, FILE **OutHandle) {
+ *InHandle = NULL;
+ *OutHandle = NULL;
+ *InHandle = fopen(InputFile, "rb");
+ if (*InHandle == NULL) {
+ printf("Failed to open input file [%s]\n", InputFile);
+ return BROTLI_FALSE;
+ }
+
+ *OutHandle = fopen(OutputFile, "wb+");
+ if (*OutHandle == NULL) {
+ printf("Failed to open output file [%s]\n", OutputFile);
+ fclose(*InHandle);
+ return BROTLI_FALSE;
+ }
+ return BROTLI_TRUE;
+}
+
+int CompressFile(char *InputFile, uint8_t *InputBuffer, char *OutputFile, uint8_t *OutputBuffer, int Quality, int Gap) {
+ int64_t InputFileSize;
+ FILE *InputFileHandle;
+ FILE *OutputFileHandle;
+ BrotliEncoderState *EncodeState;
+ uint32_t LgWin;
+ BROTLI_BOOL IsEof;
+ size_t AvailableIn;
+ const uint8_t *NextIn;
+ size_t AvailableOut;
+ uint8_t *NextOut;
+ uint8_t *Input;
+ uint8_t *Output;
+ size_t TotalOut;
+ size_t OutSize;
+ uint32_t SizeHint;
+ BROTLI_BOOL IsOk;
+ AvailableIn = 0;
+ IsEof = BROTLI_FALSE;
+ Input = InputBuffer;
+ Output = OutputBuffer;
+ IsOk = BROTLI_TRUE;
+ LgWin = DEFAULT_LGWIN;
+
+ InputFileSize = FileSize(InputFile);
+
+ IsOk = OpenFiles(InputFile, &InputFileHandle, OutputFile, &OutputFileHandle);
+ if (!IsOk) {
+ return IsOk;
+ }
+
+ fseek (OutputFileHandle, DECODE_HEADER_SIZE, SEEK_SET);
+
+ EncodeState = BrotliEncoderCreateInstance(NULL, NULL, NULL);
+ if (!EncodeState) {
+ printf("Out of memory\n");
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ BrotliEncoderSetParameter(EncodeState, BROTLI_PARAM_QUALITY, (uint32_t)Quality);
+
+ if (InputFileSize >= 0) {
+ LgWin = BROTLI_MIN_WINDOW_BITS;
+ while (BROTLI_MAX_BACKWARD_LIMIT(LgWin) < InputFileSize) {
+ LgWin++;
+ if (LgWin == BROTLI_MAX_WINDOW_BITS) {
+ break;
+ }
+ }
+ }
+ BrotliEncoderSetParameter(EncodeState, BROTLI_PARAM_LGWIN, LgWin);
+ if (InputFileSize > 0) {
+ SizeHint = InputFileSize < (1 << 30)? (uint32_t)InputFileSize : (1u << 30);
+ BrotliEncoderSetParameter(EncodeState, BROTLI_PARAM_SIZE_HINT, SizeHint);
+ }
+
+ AvailableIn = 0;
+ NextIn = NULL;
+ AvailableOut = kFileBufferSize;
+ NextOut = Output;
+ for (;;) {
+ if (AvailableIn == 0 && !IsEof) {
+ AvailableIn = fread(Input, 1, kFileBufferSize, InputFileHandle);
+ NextIn = Input;
+ if (ferror(InputFileHandle)) {
+ printf("Failed to read input [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ IsEof = !HasMoreInput(InputFileHandle);
+ }
+
+ if (!IsEof){
+ do{
+ if (!BrotliEncoderCompressStream(EncodeState,
+ BROTLI_OPERATION_FLUSH,
+ &AvailableIn, &NextIn, &AvailableOut, &NextOut, &TotalOut)) {
+ printf("Failed to compress data [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ OutSize = (size_t)(NextOut - Output);
+ if (OutSize > 0) {
+ fwrite(Output, 1, OutSize, OutputFileHandle);
+ if (ferror(OutputFileHandle)) {
+ printf("Failed to write output [%s]\n", OutputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ }
+ NextOut = Output;
+ AvailableOut = kFileBufferSize;
+ }
+ while (AvailableIn > 0 || BrotliEncoderHasMoreOutput(EncodeState));
+ }
+ else{
+ do{
+ if (!BrotliEncoderCompressStream(EncodeState,
+ BROTLI_OPERATION_FINISH,
+ &AvailableIn, &NextIn, &AvailableOut, &NextOut, &TotalOut)) {
+ printf("Failed to compress data [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ OutSize = (size_t)(NextOut - Output);
+ if (OutSize > 0) {
+ fwrite(Output, 1, OutSize, OutputFileHandle);
+ if (ferror(OutputFileHandle)) {
+ printf("Failed to write output [%s]\n", OutputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ }
+ NextOut = Output;
+ AvailableOut = kFileBufferSize;
+ }
+ while (AvailableIn > 0 || BrotliEncoderHasMoreOutput(EncodeState));
+ }
+ if (BrotliEncoderIsFinished(EncodeState)){
+ break;
+ }
+ }
+
+Finish:
+ if (EncodeState) {
+ BrotliEncoderDestroyInstance(EncodeState);
+ }
+ if (InputFileHandle) {
+ fclose(InputFileHandle);
+ }
+ if (OutputFileHandle) {
+ fclose(OutputFileHandle);
+ }
+ return IsOk;
+}
+
+/* Default BrotliAllocFunc */
+void* BrotliAllocFunc(void* Opaque, size_t Size) {
+ *(size_t *)Opaque = *(size_t *) Opaque + Size;
+ return malloc(Size);
+}
+
+/* Default BrotliFreeFunc */
+void BrotliFreeFunc(void* Opaque, void* Address) {
+ free(Address);
+}
+
+int DecompressFile(char *InputFile, uint8_t *InputBuffer, char *OutputFile, uint8_t *OutputBuffer, int Quality, int Gap) {
+ FILE *InputFileHandle;
+ FILE *OutputFileHandle;
+ BrotliDecoderState *DecoderState;
+ BrotliDecoderResult Result;
+ size_t AvailableIn;
+ const uint8_t *NextIn;
+ size_t AvailableOut;
+ uint8_t *NextOut;
+ uint8_t *Input;
+ uint8_t *Output;
+ size_t OutSize;
+ BROTLI_BOOL IsOk;
+ AvailableIn = 0;
+ Input = InputBuffer;
+ Output = OutputBuffer;
+ IsOk = BROTLI_TRUE;
+
+ IsOk = OpenFiles(InputFile, &InputFileHandle, OutputFile, &OutputFileHandle);
+ if (!IsOk) {
+ return IsOk;
+ }
+ fseek(InputFileHandle, DECODE_HEADER_SIZE, SEEK_SET);
+
+ DecoderState = BrotliDecoderCreateInstance(BrotliAllocFunc, BrotliFreeFunc, &ScratchBufferSize);
+ if (!DecoderState) {
+ printf("Out of memory\n");
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ /* This allows decoding "large-window" streams. Though it creates
+ fragmentation (new builds decode streams that old builds don't),
+ it is better from used experience perspective. */
+ BrotliDecoderSetParameter(DecoderState, BROTLI_DECODER_PARAM_LARGE_WINDOW, 1u);
+
+ AvailableIn = 0;
+ NextIn = NULL;
+ AvailableOut = kFileBufferSize;
+ NextOut = Output;
+ Result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
+ for (;;) {
+ if (Result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
+ if (!HasMoreInput(InputFileHandle)) {
+ printf("Corrupt input [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ AvailableIn = fread(Input, 1, kFileBufferSize, InputFileHandle);
+ NextIn = Input;
+ if (ferror(InputFileHandle)) {
+ printf("Failed to read input [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ } else if (Result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
+ OutSize = (size_t) (NextOut - Output);
+ if (OutSize > 0) {
+ fwrite(Output, 1, OutSize, OutputFileHandle);
+ if (ferror(OutputFileHandle)) {
+ printf("Failed to write output [%s]\n", OutputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ }
+ AvailableOut = kFileBufferSize;
+ NextOut = Output;
+ } else if (Result == BROTLI_DECODER_RESULT_SUCCESS) {
+ OutSize = (size_t) (NextOut - Output);
+ if (OutSize > 0) {
+ fwrite(Output, 1, OutSize, OutputFileHandle);
+ if (ferror(OutputFileHandle)) {
+ printf("Failed to write output [%s]\n", OutputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ }
+ AvailableOut = 0;
+ if (AvailableIn != 0 || HasMoreInput(InputFileHandle)) {
+ printf("Corrupt input [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ } else {
+ printf("Corrupt input [%s]\n", InputFile);
+ IsOk = BROTLI_FALSE;
+ goto Finish;
+ }
+ if (!HasMoreInput(InputFileHandle) && Result == BROTLI_DECODER_RESULT_SUCCESS ) {
+ break;
+ }
+ Result = BrotliDecoderDecompressStream(DecoderState, &AvailableIn, &NextIn, &AvailableOut, &NextOut, 0);
+ }
+Finish:
+ if (DecoderState) {
+ BrotliDecoderDestroyInstance(DecoderState);
+ }
+ if (InputFileHandle) {
+ fclose(InputFileHandle);
+ }
+ if (OutputFileHandle) {
+ fclose(OutputFileHandle);
+ }
+ return IsOk;
+}
+
+int main(int argc, char** argv) {
+ BROTLI_BOOL CompressBool;
+ BROTLI_BOOL DecompressBool;
+ char *OutputFile;
+ char *InputFile;
+ char OutputTmpFile[_MAX_PATH];
+ FILE *OutputHandle;
+ int Quality;
+ int Gap;
+ int OutputFileLength;
+ int InputFileLength;
+ int Ret;
+ size_t InputFileSize;
+ uint8_t *Buffer;
+ uint8_t *InputBuffer;
+ uint8_t *OutputBuffer;
+ int64_t Size;
+
+ InputFile = NULL;
+ OutputFile = NULL;
+ CompressBool = BROTLI_FALSE;
+ DecompressBool = BROTLI_FALSE;
+ //
+ //Set default Quality and Gap
+ //
+ Quality = 9;
+ Gap = 1;
+ InputFileSize = 0;
+ Ret = 0;
+
+ if (argc < 2) {
+ Usage();
+ return 1;
+ }
+ if (strcmp(argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0 ) {
+ Usage();
+ return 0;
+ }
+ if (strcmp(argv[1], "-v") == 0 || strcmp (argv[1], "--version") == 0 ) {
+ Version();
+ return 0;
+ }
+ while (argc > 1) {
+ if (strcmp(argv[1], "-e") == 0 || strcmp(argv[1], "--compress") == 0 ) {
+ CompressBool = BROTLI_TRUE;
+ if (DecompressBool) {
+ printf("Can't use -e/--compress with -d/--decompess on the same time\n");
+ return 1;
+ }
+ argc--;
+ argv++;
+ continue;
+ }
+ if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--decompress") == 0 ) {
+ DecompressBool = BROTLI_TRUE;
+ if (CompressBool) {
+ printf("Can't use -e/--compress with -d/--decompess on the same time\n");
+ return 1;
+ }
+ argc--;
+ argv++;
+ continue;
+ }
+ if (strcmp(argv[1], "-o") == 0 || strncmp(argv[1], "--output", 8) == 0) {
+ if (strcmp(argv[1], "-o") == 0) {
+ OutputFileLength = strlen(argv[2]);
+ if (OutputFileLength > _MAX_PATH) {
+ printf ("The file path %s is too long\n", argv[2]);
+ return 1;
+ }
+ OutputFile = argv[2];
+ if (OutputFile == NULL) {
+ fprintf(stderr, "Input file can't be null\n");
+ return 1;
+ }
+ argc--;
+ argv++;
+ } else {
+ OutputFileLength = strlen(argv[1] - 9);
+ OutputFile = (char *)argv[1] + 9;
+ }
+ argc--;
+ argv++;
+ continue;
+ }
+ if (strcmp(argv[1], "-q") == 0 || strncmp(argv[1], "--quality", 9) == 0) {
+ if (strcmp(argv[1], "-q") == 0) {
+ Quality = strtol(argv[2], NULL, 16);
+ argc--;
+ argv++;
+ } else {
+ Quality = strtol((char *)argv[1] + 10, NULL, 16);
+ }
+ argc--;
+ argv++;
+ continue;
+ }
+ if (strcmp(argv[1], "-g") == 0 || strncmp(argv[1], "--gap", 5) == 0) {
+ if (strcmp(argv[1], "-g") == 0) {
+ Gap = strtol(argv[2], NULL, 16);
+ argc--;
+ argv++;
+ } else {
+ Gap = strtol((char *)argv[1] + 6, NULL, 16);
+ }
+ argc--;
+ argv++;
+ continue;
+ }
+ if (argc > 1) {
+ InputFileLength = strlen(argv[1]);
+ if (InputFileLength > _MAX_PATH - 1) {
+ printf ("The file path %s is too long\n", argv[2]);
+ return 1;
+ }
+ InputFile = argv[1];
+ if (InputFile == NULL) {
+ printf("Input file can't be null\n");
+ return 1;
+ }
+ argc--;
+ argv++;
+ }
+ }
+
+ Buffer = (uint8_t*)malloc(kFileBufferSize * 2);
+ if (!Buffer) {
+ printf("Out of memory\n");
+ goto Finish;
+ }
+ memset(Buffer, 0, kFileBufferSize*2);
+ InputBuffer = Buffer;
+ OutputBuffer = Buffer + kFileBufferSize;
+ if (CompressBool) {
+ //
+ // Compress file
+ //
+ Ret = CompressFile(InputFile, InputBuffer, OutputFile, OutputBuffer, Quality, Gap);
+ if (!Ret) {
+ printf ("Failed to compress file [%s]\n", InputFile);
+ goto Finish;
+ }
+ //
+ // Decompress file for get Outputfile size
+ //
+ strcpy (OutputTmpFile, OutputFile);
+ if (strlen(InputFile) + strlen(".tmp") < _MAX_PATH) {
+ strcat(OutputTmpFile, ".tmp");
+ } else {
+ printf ("Output file path is too long[%s]\n", OutputFile);
+ Ret = BROTLI_FALSE;
+ goto Finish;
+ }
+ memset(Buffer, 0, kFileBufferSize*2);
+ Ret = DecompressFile(OutputFile, InputBuffer, OutputTmpFile, OutputBuffer, Quality, Gap);
+ if (!Ret) {
+ printf ("Failed to decompress file [%s]\n", OutputFile);
+ goto Finish;
+ }
+ remove (OutputTmpFile);
+
+ //
+ // fill decoder header
+ //
+ InputFileSize = FileSize(InputFile);
+ Size = (int64_t)InputFileSize;
+ OutputHandle = fopen(OutputFile, "rb+"); /* open output_path file and add in head info */
+ fwrite(&Size, 1, sizeof(int64_t), OutputHandle);
+ ScratchBufferSize += Gap * GAP_MEM_BLOCK; /* there is a memory gap between IA32 and X64 environment*/
+ ScratchBufferSize += kFileBufferSize * 2;
+ Size = (int64_t) ScratchBufferSize;
+ fwrite(&Size, 1, sizeof(int64_t), OutputHandle);
+ if (fclose(OutputHandle) != 0) {
+ printf("Failed to close output file [%s]\n", OutputFile);
+ Ret = BROTLI_FALSE;
+ goto Finish;
+ }
+ } else {
+ Ret = DecompressFile(InputFile, InputBuffer, OutputFile, OutputBuffer, Quality, Gap);
+ if (!Ret) {
+ printf ("Failed to decompress file [%s]\n", InputFile);
+ goto Finish;
+ }
+ }
+ Finish:
+ if (Buffer != NULL) {
+ free (Buffer);
+ }
+ return !Ret;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/GNUmakefile
new file mode 100644
index 00000000..1a1c1bb6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/GNUmakefile
@@ -0,0 +1,41 @@
+## @file
+# GNU/Linux makefile for 'Brotli' module build.
+#
+# Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = BrotliCompress
+
+OBJECTS = \
+ BrotliCompress.o \
+ brotli/c/common/dictionary.o \
+ brotli/c/common/transform.o \
+ brotli/c/dec/bit_reader.o \
+ brotli/c/dec/decode.o \
+ brotli/c/dec/huffman.o \
+ brotli/c/dec/state.o \
+ brotli/c/enc/backward_references.o \
+ brotli/c/enc/backward_references_hq.o \
+ brotli/c/enc/bit_cost.o \
+ brotli/c/enc/block_splitter.o \
+ brotli/c/enc/brotli_bit_stream.o \
+ brotli/c/enc/cluster.o \
+ brotli/c/enc/compress_fragment.o \
+ brotli/c/enc/compress_fragment_two_pass.o \
+ brotli/c/enc/dictionary_hash.o \
+ brotli/c/enc/encode.o \
+ brotli/c/enc/encoder_dict.o \
+ brotli/c/enc/entropy_encode.o \
+ brotli/c/enc/histogram.o \
+ brotli/c/enc/literal_cost.o \
+ brotli/c/enc/memory.o \
+ brotli/c/enc/metablock.o \
+ brotli/c/enc/static_dict.o \
+ brotli/c/enc/utf8_util.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+TOOL_INCLUDE = -I ./brotli/c/include
+LIBS += -lm
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/Makefile
new file mode 100644
index 00000000..30d329b6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/BrotliCompress/Makefile
@@ -0,0 +1,48 @@
+## @file
+# Windows makefile for 'Brotli' module build.
+#
+# Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+INC = -I .\brotli\c\include $(INC)
+CFLAGS = $(CFLAGS) /W2
+
+APPNAME = BrotliCompress
+
+#LIBS = $(LIB_PATH)\Common.lib
+
+COMMON_OBJ = brotli\c\common\dictionary.obj brotli\c\common\transform.obj
+DEC_OBJ = \
+ brotli\c\dec\bit_reader.obj \
+ brotli\c\dec\decode.obj \
+ brotli\c\dec\huffman.obj \
+ brotli\c\dec\state.obj
+ENC_OBJ = \
+ brotli\c\enc\backward_references.obj \
+ brotli\c\enc\backward_references_hq.obj \
+ brotli\c\enc\bit_cost.obj \
+ brotli\c\enc\block_splitter.obj \
+ brotli\c\enc\brotli_bit_stream.obj \
+ brotli\c\enc\cluster.obj \
+ brotli\c\enc\compress_fragment.obj \
+ brotli\c\enc\compress_fragment_two_pass.obj \
+ brotli\c\enc\dictionary_hash.obj \
+ brotli\c\enc\encode.obj \
+ brotli\c\enc\encoder_dict.obj \
+ brotli\c\enc\entropy_encode.obj \
+ brotli\c\enc\histogram.obj \
+ brotli\c\enc\literal_cost.obj \
+ brotli\c\enc\memory.obj \
+ brotli\c\enc\metablock.obj \
+ brotli\c\enc\static_dict.obj \
+ brotli\c\enc\utf8_util.obj
+
+OBJECTS = \
+ BrotliCompress.obj \
+ $(COMMON_OBJ) \
+ $(DEC_OBJ) \
+ $(ENC_OBJ)
+
+!INCLUDE ..\Makefiles\ms.app
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BasePeCoff.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BasePeCoff.c
new file mode 100644
index 00000000..154f737f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BasePeCoff.c
@@ -0,0 +1,1469 @@
+/** @file
+
+ Functions to get info and load PE/COFF image.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Common/UefiBaseTypes.h>
+#include <CommonLib.h>
+#include <IndustryStandard/PeImage.h>
+#include "PeCoffLib.h"
+
+typedef union {
+ VOID *Header;
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;
+} EFI_IMAGE_OPTIONAL_HEADER_POINTER;
+
+STATIC
+RETURN_STATUS
+PeCoffLoaderGetPeHeader (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ OUT EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr,
+ OUT EFI_TE_IMAGE_HEADER **TeHdr
+ );
+
+STATIC
+RETURN_STATUS
+PeCoffLoaderCheckImageType (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr,
+ IN EFI_TE_IMAGE_HEADER *TeHdr
+ );
+
+STATIC
+VOID *
+PeCoffLoaderImageAddress (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN UINTN Address
+ );
+
+RETURN_STATUS
+PeCoffLoaderRelocateIa32Image (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ );
+
+
+RETURN_STATUS
+PeCoffLoaderRelocateArmImage (
+ IN UINT16 **Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ );
+
+RETURN_STATUS
+PeCoffLoaderRelocateRiscVImage (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ );
+
+STATIC
+RETURN_STATUS
+PeCoffLoaderGetPeHeader (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ OUT EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr,
+ OUT EFI_TE_IMAGE_HEADER **TeHdr
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the PE or TE Header from a PE/COFF or TE image
+
+Arguments:
+
+ ImageContext - The context of the image being loaded
+
+ PeHdr - The buffer in which to return the PE header
+
+ TeHdr - The buffer in which to return the TE header
+
+Returns:
+
+ RETURN_SUCCESS if the PE or TE Header is read,
+ Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.
+
+--*/
+{
+ RETURN_STATUS Status;
+ EFI_IMAGE_DOS_HEADER DosHdr;
+ UINTN Size;
+
+ ImageContext->IsTeImage = FALSE;
+ //
+ // Read the DOS image headers
+ //
+ Size = sizeof (EFI_IMAGE_DOS_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ 0,
+ &Size,
+ &DosHdr
+ );
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ ImageContext->PeCoffHeaderOffset = 0;
+ if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;
+ }
+ //
+ // Get the PE/COFF Header pointer
+ //
+ *PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
+ if ((*PeHdr)->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ //
+ // Check the PE/COFF Header Signature. If not, then try to get a TE header
+ //
+ *TeHdr = (EFI_TE_IMAGE_HEADER *)*PeHdr;
+ if ((*TeHdr)->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ return RETURN_UNSUPPORTED;
+ }
+ ImageContext->IsTeImage = TRUE;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+STATIC
+RETURN_STATUS
+PeCoffLoaderCheckImageType (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr,
+ IN EFI_TE_IMAGE_HEADER *TeHdr
+ )
+/*++
+
+Routine Description:
+
+ Checks the PE or TE header of a PE/COFF or TE image to determine if it supported
+
+Arguments:
+
+ ImageContext - The context of the image being loaded
+
+ PeHdr - The buffer in which to return the PE header
+
+ TeHdr - The buffer in which to return the TE header
+
+Returns:
+
+ RETURN_SUCCESS if the PE/COFF or TE image is supported
+ RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported.
+
+--*/
+{
+ //
+ // See if the machine type is supported.
+ // We support a native machine type (IA-32/Itanium-based)
+ //
+ if (ImageContext->IsTeImage == FALSE) {
+ ImageContext->Machine = PeHdr->Pe32.FileHeader.Machine;
+ } else {
+ ImageContext->Machine = TeHdr->Machine;
+ }
+
+ if (ImageContext->Machine != EFI_IMAGE_MACHINE_IA32 && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_X64 && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) {
+ if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {
+ //
+ // There are two types of ARM images. Pure ARM and ARM/Thumb.
+ // If we see the ARM say it is the ARM/Thumb so there is only
+ // a single machine type we need to check for ARM.
+ //
+ ImageContext->Machine = EFI_IMAGE_MACHINE_ARMT;
+ if (ImageContext->IsTeImage == FALSE) {
+ PeHdr->Pe32.FileHeader.Machine = ImageContext->Machine;
+ } else {
+ TeHdr->Machine = ImageContext->Machine;
+ }
+
+ } else {
+ //
+ // unsupported PeImage machine type
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ }
+
+ //
+ // See if the image type is supported. We support EFI Applications,
+ // EFI Boot Service Drivers, EFI Runtime Drivers and EFI SAL Drivers.
+ //
+ if (ImageContext->IsTeImage == FALSE) {
+ ImageContext->ImageType = PeHdr->Pe32.OptionalHeader.Subsystem;
+ } else {
+ ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);
+ }
+
+ if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \
+ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \
+ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \
+ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) {
+ //
+ // unsupported PeImage subsystem type
+ //
+ return RETURN_UNSUPPORTED;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderGetImageInfo (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Retrieves information on a PE/COFF image
+
+Arguments:
+
+ This - Calling context
+ ImageContext - The context of the image being loaded
+
+Returns:
+
+ RETURN_SUCCESS - The information on the PE/COFF image was collected.
+ RETURN_INVALID_PARAMETER - ImageContext is NULL.
+ RETURN_UNSUPPORTED - The PE/COFF image is not supported.
+ Otherwise - The error status from reading the PE/COFF image using the
+ ImageContext->ImageRead() function
+
+--*/
+{
+ RETURN_STATUS Status;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
+ EFI_TE_IMAGE_HEADER *TeHdr;
+ EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;
+ UINTN Size;
+ UINTN Index;
+ UINTN DebugDirectoryEntryRva;
+ UINTN DebugDirectoryEntryFileOffset;
+ UINTN SectionHeaderOffset;
+ EFI_IMAGE_SECTION_HEADER SectionHeader;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;
+ EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;
+
+ PeHdr = NULL;
+ TeHdr = NULL;
+ DebugDirectoryEntry = NULL;
+ DebugDirectoryEntryRva = 0;
+
+ if (NULL == ImageContext) {
+ return RETURN_INVALID_PARAMETER;
+ }
+ //
+ // Assume success
+ //
+ ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
+
+ Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Verify machine type
+ //
+ Status = PeCoffLoaderCheckImageType (ImageContext, PeHdr, TeHdr);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+ OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader);
+
+ //
+ // Retrieve the base address of the image
+ //
+ if (!(ImageContext->IsTeImage)) {
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional32->ImageBase;
+ } else {
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional64->ImageBase;
+ }
+ } else {
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr->ImageBase + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
+ }
+ //
+ // Initialize the alternate destination address to 0 indicating that it
+ // should not be used.
+ //
+ ImageContext->DestinationAddress = 0;
+
+ //
+ // Initialize the codeview pointer.
+ //
+ ImageContext->CodeView = NULL;
+ ImageContext->PdbPointer = NULL;
+
+ //
+ // Three cases with regards to relocations:
+ // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable
+ // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable
+ // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but
+ // has no base relocs to apply
+ // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.
+ //
+ // Look at the file header to determine if relocations have been stripped, and
+ // save this info in the image context for later use.
+ //
+ if ((!(ImageContext->IsTeImage)) && ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {
+ ImageContext->RelocationsStripped = TRUE;
+ } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0) && (TeHdr->DataDirectory[0].VirtualAddress == 0)) {
+ ImageContext->RelocationsStripped = TRUE;
+ } else {
+ ImageContext->RelocationsStripped = FALSE;
+ }
+
+ if (!(ImageContext->IsTeImage)) {
+
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ ImageContext->ImageSize = (UINT64) OptionHeader.Optional32->SizeOfImage;
+ ImageContext->SectionAlignment = OptionHeader.Optional32->SectionAlignment;
+ ImageContext->SizeOfHeaders = OptionHeader.Optional32->SizeOfHeaders;
+
+ //
+ // Modify ImageSize to contain .PDB file name if required and initialize
+ // PdbRVA field...
+ //
+ if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
+ }
+ } else {
+ ImageContext->ImageSize = (UINT64) OptionHeader.Optional64->SizeOfImage;
+ ImageContext->SectionAlignment = OptionHeader.Optional64->SectionAlignment;
+ ImageContext->SizeOfHeaders = OptionHeader.Optional64->SizeOfHeaders;
+
+ //
+ // Modify ImageSize to contain .PDB file name if required and initialize
+ // PdbRVA field...
+ //
+ if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
+ }
+ }
+
+ if (DebugDirectoryEntryRva != 0) {
+ //
+ // Determine the file offset of the debug directory... This means we walk
+ // the sections to find which section contains the RVA of the debug
+ // directory
+ //
+ DebugDirectoryEntryFileOffset = 0;
+
+ SectionHeaderOffset = (UINTN)(
+ ImageContext->PeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ PeHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {
+ //
+ // Read section header from file
+ //
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ SectionHeaderOffset,
+ &Size,
+ &SectionHeader
+ );
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
+ DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
+ DebugDirectoryEntryFileOffset =
+ DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;
+ break;
+ }
+
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+ }
+
+ if (DebugDirectoryEntryFileOffset != 0) {
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {
+ //
+ // Read next debug directory entry
+ //
+ Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugDirectoryEntryFileOffset + Index,
+ &Size,
+ &DebugEntry
+ );
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
+ if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
+ ImageContext->ImageSize += DebugEntry.SizeOfData;
+ }
+
+ return RETURN_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ ImageContext->ImageSize = 0;
+ ImageContext->SectionAlignment = 4096;
+ ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr->BaseOfCode - (UINTN) TeHdr->StrippedSize;
+
+ DebugDirectoryEntry = &TeHdr->DataDirectory[1];
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
+ SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));
+
+ DebugDirectoryEntryFileOffset = 0;
+
+ for (Index = 0; Index < TeHdr->NumberOfSections;) {
+ //
+ // Read section header from file
+ //
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ SectionHeaderOffset,
+ &Size,
+ &SectionHeader
+ );
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
+ DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
+ DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -
+ SectionHeader.VirtualAddress +
+ SectionHeader.PointerToRawData +
+ sizeof (EFI_TE_IMAGE_HEADER) -
+ TeHdr->StrippedSize;
+
+ //
+ // File offset of the debug directory was found, if this is not the last
+ // section, then skip to the last section for calculating the image size.
+ //
+ if (Index < (UINTN) TeHdr->NumberOfSections - 1) {
+ SectionHeaderOffset += (TeHdr->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);
+ Index = TeHdr->NumberOfSections - 1;
+ continue;
+ }
+ }
+
+ //
+ // In Te image header there is not a field to describe the ImageSize.
+ // Actually, the ImageSize equals the RVA plus the VirtualSize of
+ // the last section mapped into memory (Must be rounded up to
+ // a multiple of Section Alignment). Per the PE/COFF specification, the
+ // section headers in the Section Table must appear in order of the RVA
+ // values for the corresponding sections. So the ImageSize can be determined
+ // by the RVA and the VirtualSize of the last section header in the
+ // Section Table.
+ //
+ if ((++Index) == (UINTN) TeHdr->NumberOfSections) {
+ ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +
+ ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);
+ }
+
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+ }
+
+ if (DebugDirectoryEntryFileOffset != 0) {
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {
+ //
+ // Read next debug directory entry
+ //
+ Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugDirectoryEntryFileOffset,
+ &Size,
+ &DebugEntry
+ );
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
+ return RETURN_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return RETURN_SUCCESS;
+}
+
+STATIC
+VOID *
+PeCoffLoaderImageAddress (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN UINTN Address
+ )
+/*++
+
+Routine Description:
+
+ Converts an image address to the loaded address
+
+Arguments:
+
+ ImageContext - The context of the image being loaded
+
+ Address - The address to be converted to the loaded address
+
+Returns:
+
+ NULL if the address can not be converted, otherwise, the converted address
+
+--*/
+{
+ if (Address >= ImageContext->ImageSize) {
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+ return NULL;
+ }
+
+ return (UINT8 *) ((UINTN) ImageContext->ImageAddress + Address);
+}
+
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderRelocateImage (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Relocates a PE/COFF image in memory
+
+Arguments:
+
+ This - Calling context
+
+ ImageContext - Contains information on the loaded image to relocate
+
+Returns:
+
+ RETURN_SUCCESS if the PE/COFF image was relocated
+ RETURN_LOAD_ERROR if the image is not a valid PE/COFF image
+ RETURN_UNSUPPORTED not support
+
+--*/
+{
+ RETURN_STATUS Status;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
+ EFI_TE_IMAGE_HEADER *TeHdr;
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;
+ UINT64 Adjust;
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
+ UINT16 *Reloc;
+ UINT16 *RelocEnd;
+ CHAR8 *Fixup;
+ CHAR8 *FixupBase;
+ UINT16 *F16;
+ UINT32 *F32;
+ UINT64 *F64;
+ CHAR8 *FixupData;
+ PHYSICAL_ADDRESS BaseAddress;
+ UINT16 MachineType;
+ EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;
+
+ PeHdr = NULL;
+ TeHdr = NULL;
+ //
+ // Assume success
+ //
+ ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
+
+ //
+ // If there are no relocation entries, then we are done
+ //
+ if (ImageContext->RelocationsStripped) {
+ return RETURN_SUCCESS;
+ }
+
+ //
+ // Use DestinationAddress field of ImageContext as the relocation address even if it is 0.
+ //
+ BaseAddress = ImageContext->DestinationAddress;
+
+ if (!(ImageContext->IsTeImage)) {
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN)ImageContext->ImageAddress +
+ ImageContext->PeCoffHeaderOffset);
+ OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader);
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ Adjust = (UINT64) BaseAddress - OptionHeader.Optional32->ImageBase;
+ OptionHeader.Optional32->ImageBase = (UINT32) BaseAddress;
+ MachineType = ImageContext->Machine;
+ //
+ // Find the relocation block
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ RelocDir = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
+ RelocBaseEnd = PeCoffLoaderImageAddress (
+ ImageContext,
+ RelocDir->VirtualAddress + RelocDir->Size - 1
+ );
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
+ } else {
+ //
+ // Set base and end to bypass processing below.
+ //
+ RelocBase = RelocBaseEnd = 0;
+ }
+ } else {
+ //
+ // Set base and end to bypass processing below.
+ //
+ RelocBase = RelocBaseEnd = 0;
+ }
+ } else {
+ Adjust = (UINT64) BaseAddress - OptionHeader.Optional64->ImageBase;
+ OptionHeader.Optional64->ImageBase = BaseAddress;
+ MachineType = ImageContext->Machine;
+ //
+ // Find the relocation block
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ RelocDir = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
+ RelocBaseEnd = PeCoffLoaderImageAddress (
+ ImageContext,
+ RelocDir->VirtualAddress + RelocDir->Size - 1
+ );
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
+ } else {
+ //
+ // Set base and end to bypass processing below.
+ //
+ RelocBase = RelocBaseEnd = 0;
+ }
+ } else {
+ //
+ // Set base and end to bypass processing below.
+ //
+ RelocBase = RelocBaseEnd = 0;
+ }
+ }
+ } else {
+ TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);
+ Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase);
+ TeHdr->ImageBase = (UINT64) (BaseAddress);
+ MachineType = TeHdr->Machine;
+
+ //
+ // Find the relocation block
+ //
+ RelocDir = &TeHdr->DataDirectory[0];
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(
+ ImageContext->ImageAddress +
+ RelocDir->VirtualAddress +
+ sizeof(EFI_TE_IMAGE_HEADER) -
+ TeHdr->StrippedSize
+ );
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);
+ }
+
+ //
+ // Run the relocation information and apply the fixups
+ //
+ FixupData = ImageContext->FixupData;
+ while (RelocBase < RelocBaseEnd) {
+
+ Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
+ RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
+ if (!(ImageContext->IsTeImage)) {
+ FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
+ if (FixupBase == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
+ } else {
+ FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
+ RelocBase->VirtualAddress +
+ sizeof(EFI_TE_IMAGE_HEADER) -
+ TeHdr->StrippedSize
+ );
+ }
+
+ if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||
+ (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress +
+ (UINTN)ImageContext->ImageSize)) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
+
+ //
+ // Run this relocation record
+ //
+ while (Reloc < RelocEnd) {
+
+ Fixup = FixupBase + (*Reloc & 0xFFF);
+ switch ((*Reloc) >> 12) {
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGH:
+ F16 = (UINT16 *) Fixup;
+ *F16 = (UINT16) (*F16 + ((UINT16) ((UINT32) Adjust >> 16)));
+ if (FixupData != NULL) {
+ *(UINT16 *) FixupData = *F16;
+ FixupData = FixupData + sizeof (UINT16);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_LOW:
+ F16 = (UINT16 *) Fixup;
+ *F16 = (UINT16) (*F16 + (UINT16) Adjust);
+ if (FixupData != NULL) {
+ *(UINT16 *) FixupData = *F16;
+ FixupData = FixupData + sizeof (UINT16);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHLOW:
+ F32 = (UINT32 *) Fixup;
+ *F32 = *F32 + (UINT32) Adjust;
+ if (FixupData != NULL) {
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
+ *(UINT32 *) FixupData = *F32;
+ FixupData = FixupData + sizeof (UINT32);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_DIR64:
+ F64 = (UINT64 *) Fixup;
+ *F64 = *F64 + (UINT64) Adjust;
+ if (FixupData != NULL) {
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64));
+ *(UINT64 *) FixupData = *F64;
+ FixupData = FixupData + sizeof (UINT64);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHADJ:
+ //
+ // Return the same EFI_UNSUPPORTED return code as
+ // PeCoffLoaderRelocateImageEx() returns if it does not recognize
+ // the relocation type.
+ //
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_UNSUPPORTED;
+
+ default:
+ switch (MachineType) {
+ case EFI_IMAGE_MACHINE_IA32:
+ Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust);
+ break;
+ case EFI_IMAGE_MACHINE_ARMT:
+ Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);
+ break;
+ case EFI_IMAGE_MACHINE_RISCV64:
+ Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);
+ break;
+ default:
+ Status = RETURN_UNSUPPORTED;
+ break;
+ }
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return Status;
+ }
+ }
+
+ //
+ // Next relocation record
+ //
+ Reloc += 1;
+ }
+
+ //
+ // Next reloc block
+ //
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderLoadImage (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Loads a PE/COFF image into memory
+
+Arguments:
+
+ This - Calling context
+
+ ImageContext - Contains information on image to load into memory
+
+Returns:
+
+ RETURN_SUCCESS if the PE/COFF image was loaded
+ RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer
+ RETURN_LOAD_ERROR if the image is a runtime driver with no relocations
+ RETURN_INVALID_PARAMETER if the image address is invalid
+
+--*/
+{
+ RETURN_STATUS Status;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
+ EFI_TE_IMAGE_HEADER *TeHdr;
+ PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;
+ EFI_IMAGE_SECTION_HEADER *FirstSection;
+ EFI_IMAGE_SECTION_HEADER *Section;
+ UINTN NumberOfSections;
+ UINTN Index;
+ CHAR8 *Base;
+ CHAR8 *End;
+ CHAR8 *MaxEnd;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN Size;
+ UINT32 TempDebugEntryRva;
+ EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;
+
+ PeHdr = NULL;
+ TeHdr = NULL;
+ OptionHeader.Header = NULL;
+ //
+ // Assume success
+ //
+ ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
+
+ //
+ // Copy the provided context info into our local version, get what we
+ // can from the original image, and then use that to make sure everything
+ // is legit.
+ //
+ CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+
+ Status = PeCoffLoaderGetImageInfo (&CheckContext);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure there is enough allocated space for the image being loaded
+ //
+ if (ImageContext->ImageSize < CheckContext.ImageSize) {
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // If there's no relocations, then make sure it's not a runtime driver,
+ // and that it's being loaded at the linked address.
+ //
+ if (CheckContext.RelocationsStripped) {
+ //
+ // If the image does not contain relocations and it is a runtime driver
+ // then return an error.
+ //
+ if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
+ return RETURN_LOAD_ERROR;
+ }
+ //
+ // If the image does not contain relocations, and the requested load address
+ // is not the linked address, then return an error.
+ //
+ if (CheckContext.ImageAddress != ImageContext->ImageAddress) {
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+ return RETURN_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Make sure the allocated space has the proper section alignment
+ //
+ if (!(ImageContext->IsTeImage)) {
+ if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;
+ return RETURN_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Read the entire PE/COFF or TE header into memory
+ //
+ if (!(ImageContext->IsTeImage)) {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ 0,
+ &ImageContext->SizeOfHeaders,
+ (VOID *) (UINTN) ImageContext->ImageAddress
+ );
+
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)
+ ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
+
+ OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader);
+
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN)ImageContext->ImageAddress +
+ ImageContext->PeCoffHeaderOffset +
+ sizeof(UINT32) +
+ sizeof(EFI_IMAGE_FILE_HEADER) +
+ PeHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+ NumberOfSections = (UINTN) (PeHdr->Pe32.FileHeader.NumberOfSections);
+ } else {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ 0,
+ &ImageContext->SizeOfHeaders,
+ (VOID *) (UINTN) ImageContext->ImageAddress
+ );
+
+ TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);
+
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN)ImageContext->ImageAddress +
+ sizeof(EFI_TE_IMAGE_HEADER)
+ );
+ NumberOfSections = (UINTN) (TeHdr->NumberOfSections);
+
+ }
+
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return RETURN_LOAD_ERROR;
+ }
+
+ //
+ // Load each section of the image
+ //
+ Section = FirstSection;
+ for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {
+
+ //
+ // Compute sections address
+ //
+ Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);
+ End = PeCoffLoaderImageAddress (
+ ImageContext,
+ Section->VirtualAddress + Section->Misc.VirtualSize - 1
+ );
+
+ //
+ // If the base start or end address resolved to 0, then fail.
+ //
+ if ((Base == NULL) || (End == NULL)) {
+ ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;
+ return RETURN_LOAD_ERROR;
+ }
+
+
+ if (ImageContext->IsTeImage) {
+ Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);
+ End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);
+ }
+
+ if (End > MaxEnd) {
+ MaxEnd = End;
+ }
+
+ //
+ // Read the section
+ //
+ Size = (UINTN) Section->Misc.VirtualSize;
+ if ((Size == 0) || (Size > Section->SizeOfRawData)) {
+ Size = (UINTN) Section->SizeOfRawData;
+ }
+
+ if (Section->SizeOfRawData) {
+ if (!(ImageContext->IsTeImage)) {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ Section->PointerToRawData,
+ &Size,
+ Base
+ );
+ } else {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,
+ &Size,
+ Base
+ );
+ }
+
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+ }
+
+ //
+ // If raw size is less then virt size, zero fill the remaining
+ //
+
+ if (Size < Section->Misc.VirtualSize) {
+ ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);
+ }
+
+ //
+ // Next Section
+ //
+ Section += 1;
+ }
+
+ //
+ // Get image's entry point
+ //
+ if (!(ImageContext->IsTeImage)) {
+ ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (
+ ImageContext,
+ PeHdr->Pe32.OptionalHeader.AddressOfEntryPoint
+ );
+ } else {
+ ImageContext->EntryPoint = (UINTN)ImageContext->ImageAddress +
+ (UINTN)TeHdr->AddressOfEntryPoint +
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
+ (UINTN) TeHdr->StrippedSize;
+ }
+
+ //
+ // Determine the size of the fixup data
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ if (!(ImageContext->IsTeImage)) {
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
+ &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ } else {
+ ImageContext->FixupDataSize = 0;
+ }
+ } else {
+ if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
+ &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ } else {
+ ImageContext->FixupDataSize = 0;
+ }
+ }
+ } else {
+ DirectoryEntry = &TeHdr->DataDirectory[0];
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ }
+ //
+ // Consumer must allocate a buffer for the relocation fixup log.
+ // Only used for runtime drivers.
+ //
+ ImageContext->FixupData = NULL;
+
+ //
+ // Load the Codeview info if present
+ //
+ if (ImageContext->DebugDirectoryEntryRva != 0) {
+ if (!(ImageContext->IsTeImage)) {
+ DebugEntry = PeCoffLoaderImageAddress (
+ ImageContext,
+ ImageContext->DebugDirectoryEntryRva
+ );
+ } else {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
+ ImageContext->ImageAddress +
+ ImageContext->DebugDirectoryEntryRva +
+ sizeof(EFI_TE_IMAGE_HEADER) -
+ TeHdr->StrippedSize
+ );
+ }
+
+ if (DebugEntry != NULL) {
+ TempDebugEntryRva = DebugEntry->RVA;
+ if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
+ Section--;
+ if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {
+ TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
+ } else {
+ TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
+ }
+ }
+
+ if (TempDebugEntryRva != 0) {
+ if (!(ImageContext->IsTeImage)) {
+ ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);
+ } else {
+ ImageContext->CodeView = (VOID *)(
+ (UINTN)ImageContext->ImageAddress +
+ (UINTN)TempDebugEntryRva +
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
+ (UINTN) TeHdr->StrippedSize
+ );
+ }
+
+ if (ImageContext->CodeView == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return RETURN_LOAD_ERROR;
+ }
+
+ if (DebugEntry->RVA == 0) {
+ Size = DebugEntry->SizeOfData;
+ if (!(ImageContext->IsTeImage)) {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugEntry->FileOffset,
+ &Size,
+ ImageContext->CodeView
+ );
+ } else {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,
+ &Size,
+ ImageContext->CodeView
+ );
+ //
+ // Should we apply fix up to this field according to the size difference between PE and TE?
+ // Because now we maintain TE header fields unfixed, this field will also remain as they are
+ // in original PE image.
+ //
+ }
+
+ if (RETURN_ERROR (Status)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ return RETURN_LOAD_ERROR;
+ }
+
+ DebugEntry->RVA = TempDebugEntryRva;
+ }
+
+ switch (*(UINT32 *) ImageContext->CodeView) {
+ case CODEVIEW_SIGNATURE_NB10:
+ ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_MTOC:
+ ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Returns a pointer to the PDB file name for a raw PE/COFF image that is not
+ loaded into system memory with the PE/COFF Loader Library functions.
+
+ Returns the PDB file name for the PE/COFF image specified by Pe32Data. If
+ the PE/COFF image specified by Pe32Data is not a valid, then NULL is
+ returned. If the PE/COFF image specified by Pe32Data does not contain a
+ debug directory entry, then NULL is returned. If the debug directory entry
+ in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
+ then NULL is returned.
+ If Pe32Data is NULL, then return NULL.
+
+ @param Pe32Data Pointer to the PE/COFF image that is loaded in system
+ memory.
+
+ @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
+ if it cannot be retrieved.
+
+**/
+VOID *
+EFIAPI
+PeCoffLoaderGetPdbPointer (
+ IN VOID *Pe32Data
+ )
+{
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN DirCount;
+ VOID *CodeViewEntryPointer;
+ INTN TEImageAdjust;
+ UINT32 NumberOfRvaAndSizes;
+ UINT16 Magic;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ UINT32 Index, Index1;
+
+ if (Pe32Data == NULL) {
+ return NULL;
+ }
+
+ TEImageAdjust = 0;
+ DirectoryEntry = NULL;
+ DebugEntry = NULL;
+ NumberOfRvaAndSizes = 0;
+ Index = 0;
+ Index1 = 0;
+ SectionHeader = NULL;
+
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (EFI_IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header.
+ //
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base.
+ //
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
+ }
+
+ if (EFI_TE_IMAGE_HEADER_SIGNATURE == Hdr.Te->Signature) {
+ if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+ DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
+
+ //
+ // Get the DebugEntry offset in the raw data image.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (Hdr.Te + 1);
+ Index = Hdr.Te->NumberOfSections;
+ for (Index1 = 0; Index1 < Index; Index1 ++) {
+ if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) &&
+ (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +
+ DirectoryEntry->VirtualAddress -
+ SectionHeader [Index1].VirtualAddress +
+ SectionHeader [Index1].PointerToRawData +
+ TEImageAdjust);
+ break;
+ }
+ }
+ }
+ } else if (EFI_IMAGE_NT_SIGNATURE == Hdr.Pe32->Signature) {
+ //
+ // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
+ // It is due to backward-compatibility, for some system might
+ // generate PE32+ image with PE32 Magic.
+ //
+ switch (Hdr.Pe32->FileHeader.Machine) {
+ case EFI_IMAGE_MACHINE_IA32:
+ case EFI_IMAGE_MACHINE_ARMT:
+ //
+ // Assume PE32 image with IA32 Machine field.
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EFI_IMAGE_MACHINE_X64:
+ //
+ // Assume PE32+ image with X64 Machine field
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ default:
+ //
+ // For unknown Machine field, use Magic in optional Header
+ //
+ Magic = Hdr.Pe32->OptionalHeader.Magic;
+ }
+
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINT8 *) Hdr.Pe32 +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader
+ );
+ Index = Hdr.Pe32->FileHeader.NumberOfSections;
+
+ if (EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC == Magic) {
+ //
+ // Use PE32 offset get Debug Directory Entry
+ //
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ //
+ // Use PE32+ offset get Debug Directory Entry
+ //
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ }
+
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG || DirectoryEntry->VirtualAddress == 0) {
+ DirectoryEntry = NULL;
+ DebugEntry = NULL;
+ } else {
+ //
+ // Get the DebugEntry offset in the raw data image.
+ //
+ for (Index1 = 0; Index1 < Index; Index1 ++) {
+ if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) &&
+ (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (
+ (UINTN) Pe32Data +
+ DirectoryEntry->VirtualAddress -
+ SectionHeader[Index1].VirtualAddress +
+ SectionHeader[Index1].PointerToRawData);
+ break;
+ }
+ }
+ }
+ } else {
+ return NULL;
+ }
+
+ if (NULL == DebugEntry || NULL == DirectoryEntry) {
+ return NULL;
+ }
+
+ //
+ // Scan the directory to find the debug entry.
+ //
+ for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
+ if (EFI_IMAGE_DEBUG_TYPE_CODEVIEW == DebugEntry->Type) {
+ if (DebugEntry->SizeOfData > 0) {
+ //
+ // Get the DebugEntry offset in the raw data image.
+ //
+ CodeViewEntryPointer = NULL;
+ for (Index1 = 0; Index1 < Index; Index1 ++) {
+ if ((DebugEntry->RVA >= SectionHeader[Index1].VirtualAddress) &&
+ (DebugEntry->RVA < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {
+ CodeViewEntryPointer = (VOID *) (
+ ((UINTN)Pe32Data) +
+ (UINTN) DebugEntry->RVA -
+ SectionHeader[Index1].VirtualAddress +
+ SectionHeader[Index1].PointerToRawData +
+ (UINTN)TEImageAdjust);
+ break;
+ }
+ }
+ if (Index1 >= Index) {
+ //
+ // Can't find CodeViewEntryPointer in raw PE/COFF image.
+ //
+ continue;
+ }
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));
+ case CODEVIEW_SIGNATURE_RSDS:
+ return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));
+ case CODEVIEW_SIGNATURE_MTOC:
+ return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderGetEntryPoint (
+ IN VOID *Pe32Data,
+ OUT VOID **EntryPoint,
+ OUT VOID **BaseOfImage
+ )
+{
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header.
+ //
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base.
+ //
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
+ }
+
+ //
+ // Calculate the entry point relative to the start of the image.
+ // AddressOfEntryPoint is common for PE32 & PE32+
+ //
+ if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ *BaseOfImage = (VOID *)(UINTN)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
+ *EntryPoint = (VOID *)((UINTN)*BaseOfImage + (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
+ return RETURN_SUCCESS;
+ } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
+ *EntryPoint = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint;
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.ImageBase;
+ } else {
+ *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32Plus->OptionalHeader.ImageBase;
+ }
+ *EntryPoint = (VOID *)(UINTN)((UINTN)*EntryPoint + (UINTN)*BaseOfImage);
+ return RETURN_SUCCESS;
+ }
+
+ return RETURN_UNSUPPORTED;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.c
new file mode 100644
index 00000000..507b70aa
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.c
@@ -0,0 +1,74 @@
+/** @file
+Binder function implementations for ANSI C libraries.
+
+Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BinderFuncs.h"
+#include "CommonLib.h"
+#include <stdlib.h>
+#include <string.h>
+
+//
+// Binder Function Implementations
+//
+
+VOID *
+CommonLibBinderAllocate (
+ IN UINTN Size
+ )
+{
+ return (VOID *) malloc (Size);
+}
+
+VOID
+CommonLibBinderFree (
+ IN VOID *Pointer
+ )
+{
+ free (Pointer);
+}
+
+VOID
+CommonLibBinderCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+{
+ memmove (Destination, Source, Length);
+}
+
+VOID
+CommonLibBinderSetMem (
+ IN VOID *Destination,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ memset (Destination, Value, Length);
+}
+
+INTN
+CommonLibBinderCompareMem (
+ IN VOID *MemOne,
+ IN VOID *MemTwo,
+ IN UINTN Length
+ )
+{
+ return memcmp (MemOne, MemTwo, Length);
+}
+
+BOOLEAN
+CommonLibBinderCompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ )
+{
+ return CompareGuid (Guid1, Guid2) ? FALSE : TRUE;
+}
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.h
new file mode 100644
index 00000000..accd22d1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/BinderFuncs.h
@@ -0,0 +1,61 @@
+/** @file
+Prototypes for binder functions that allow common code to be written which then
+links to implementation of these functions which is appropriate for the specific
+environment that they are running under.
+
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BinderFuncs_h_INCLUDED
+#define BinderFuncs_h_INCLUDED
+
+#include "Common/UefiBaseTypes.h"
+
+//
+// Binder Function Prototypes
+//
+// These binding functions must be implemented externally as appropriate for
+// the environment that the code will be running under.
+//
+
+VOID *
+CommonLibBinderAllocate (
+ IN UINTN Size
+ );
+
+VOID
+CommonLibBinderFree (
+ IN VOID *Pointer
+ );
+
+VOID
+CommonLibBinderCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ );
+
+VOID
+CommonLibBinderSetMem (
+ IN VOID *Destination,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+INTN
+CommonLibBinderCompareMem (
+ IN VOID *MemOne,
+ IN VOID *MemTwo,
+ IN UINTN Length
+ );
+
+BOOLEAN
+CommonLibBinderCompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ );
+
+#endif // #ifndef CommonLibs_h_INCLUDED
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.c
new file mode 100644
index 00000000..ecda9d70
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.c
@@ -0,0 +1,2191 @@
+/** @file
+Common basic Library Functions
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef __GNUC__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+
+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
+ do { \
+ ASSERT (Expression); \
+ if (!(Expression)) { \
+ return Status; \
+ } \
+ } while (FALSE)
+
+VOID
+PeiZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ Set Buffer to zero for Size bytes.
+
+Arguments:
+
+ Buffer - Memory to set.
+
+ Size - Number of bytes to set
+
+Returns:
+
+ None
+
+--*/
+{
+ INT8 *Ptr;
+
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+VOID
+PeiCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+
+ Destination8 = Destination;
+ Source8 = Source;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+}
+
+VOID
+ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+{
+ PeiZeroMem (Buffer, Size);
+}
+
+VOID
+CopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+{
+ PeiCopyMem (Destination, Source, Length);
+}
+
+INTN
+CompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ )
+/*++
+
+Routine Description:
+
+ Compares to GUIDs
+
+Arguments:
+
+ Guid1 - guid to compare
+ Guid2 - guid to compare
+
+Returns:
+ = 0 if Guid1 == Guid2
+ != 0 if Guid1 != Guid2
+
+--*/
+{
+ INT32 *g1;
+ INT32 *g2;
+ INT32 r;
+
+ //
+ // Compare 32 bits at a time
+ //
+ g1 = (INT32 *) Guid1;
+ g2 = (INT32 *) Guid2;
+
+ r = g1[0] - g2[0];
+ r |= g1[1] - g2[1];
+ r |= g1[2] - g2[2];
+ r |= g1[3] - g2[3];
+
+ return r;
+}
+
+
+EFI_STATUS
+GetFileImage (
+ IN CHAR8 *InputFileName,
+ OUT CHAR8 **InputFileImage,
+ OUT UINT32 *BytesRead
+ )
+/*++
+
+Routine Description:
+
+ This function opens a file and reads it into a memory buffer. The function
+ will allocate the memory buffer and returns the size of the buffer.
+
+Arguments:
+
+ InputFileName The name of the file to read.
+ InputFileImage A pointer to the memory buffer.
+ BytesRead The size of the memory buffer.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED An error occurred.
+ EFI_OUT_OF_RESOURCES No resource to complete operations.
+
+--*/
+{
+ FILE *InputFile;
+ UINT32 FileSize;
+
+ //
+ // Verify input parameters.
+ //
+ if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Open the file and copy contents into a memory buffer.
+ //
+ //
+ // Open the file
+ //
+ InputFile = fopen (LongFilePath (InputFileName), "rb");
+ if (InputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening the input file", InputFileName);
+ return EFI_ABORTED;
+ }
+ //
+ // Go to the end so that we can determine the file size
+ //
+ if (fseek (InputFile, 0, SEEK_END)) {
+ Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
+ fclose (InputFile);
+ return EFI_ABORTED;
+ }
+ //
+ // Get the file size
+ //
+ FileSize = ftell (InputFile);
+ if (FileSize == -1) {
+ Error (NULL, 0, 0003, "Error parsing the input file", InputFileName);
+ fclose (InputFile);
+ return EFI_ABORTED;
+ }
+ //
+ // Allocate a buffer
+ //
+ *InputFileImage = malloc (FileSize);
+ if (*InputFileImage == NULL) {
+ fclose (InputFile);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Reset to the beginning of the file
+ //
+ if (fseek (InputFile, 0, SEEK_SET)) {
+ Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
+ fclose (InputFile);
+ free (*InputFileImage);
+ *InputFileImage = NULL;
+ return EFI_ABORTED;
+ }
+ //
+ // Read all of the file contents.
+ //
+ *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);
+ if (*BytesRead != sizeof (UINT8) * FileSize) {
+ Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
+ fclose (InputFile);
+ free (*InputFileImage);
+ *InputFileImage = NULL;
+ return EFI_ABORTED;
+ }
+ //
+ // Close the file
+ //
+ fclose (InputFile);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PutFileImage (
+ IN CHAR8 *OutputFileName,
+ IN CHAR8 *OutputFileImage,
+ IN UINT32 BytesToWrite
+ )
+/*++
+
+Routine Description:
+
+ This function opens a file and writes OutputFileImage into the file.
+
+Arguments:
+
+ OutputFileName The name of the file to write.
+ OutputFileImage A pointer to the memory buffer.
+ BytesToWrite The size of the memory buffer.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED An error occurred.
+ EFI_OUT_OF_RESOURCES No resource to complete operations.
+
+--*/
+{
+ FILE *OutputFile;
+ UINT32 BytesWrote;
+
+ //
+ // Verify input parameters.
+ //
+ if (OutputFileName == NULL || strlen (OutputFileName) == 0 || OutputFileImage == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Open the file and copy contents into a memory buffer.
+ //
+ //
+ // Open the file
+ //
+ OutputFile = fopen (LongFilePath (OutputFileName), "wb");
+ if (OutputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening the output file", OutputFileName);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Write all of the file contents.
+ //
+ BytesWrote = fwrite (OutputFileImage, sizeof (UINT8), BytesToWrite, OutputFile);
+ if (BytesWrote != sizeof (UINT8) * BytesToWrite) {
+ Error (NULL, 0, 0002, "Error writing the output file", OutputFileName);
+ fclose (OutputFile);
+ return EFI_ABORTED;
+ }
+ //
+ // Close the file
+ //
+ fclose (OutputFile);
+
+ return EFI_SUCCESS;
+}
+
+UINT8
+CalculateChecksum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ This function calculates the value needed for a valid UINT8 checksum
+
+Arguments:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Returns:
+
+ The 8 bit checksum value needed.
+
+--*/
+{
+ return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));
+}
+
+UINT8
+CalculateSum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description::
+
+ This function calculates the UINT8 sum for the requested region.
+
+Arguments:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Returns:
+
+ The 8 bit checksum value needed.
+
+--*/
+{
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+
+ //
+ // Perform the byte sum for buffer
+ //
+ for (Index = 0; Index < Size; Index++) {
+ Sum = (UINT8) (Sum + Buffer[Index]);
+ }
+
+ return Sum;
+}
+
+UINT16
+CalculateChecksum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description::
+
+ This function calculates the value needed for a valid UINT16 checksum
+
+Arguments:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Returns:
+
+ The 16 bit checksum value needed.
+
+--*/
+{
+ return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));
+}
+
+UINT16
+CalculateSum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ This function calculates the UINT16 sum for the requested region.
+
+Arguments:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Returns:
+
+ The 16 bit checksum
+
+--*/
+{
+ UINTN Index;
+ UINT16 Sum;
+
+ Sum = 0;
+
+ //
+ // Perform the word sum for buffer
+ //
+ for (Index = 0; Index < Size; Index++) {
+ Sum = (UINT16) (Sum + Buffer[Index]);
+ }
+
+ return (UINT16) Sum;
+}
+
+EFI_STATUS
+PrintGuid (
+ IN EFI_GUID *Guid
+ )
+/*++
+
+Routine Description:
+
+ This function prints a GUID to STDOUT.
+
+Arguments:
+
+ Guid Pointer to a GUID to print.
+
+Returns:
+
+ EFI_SUCCESS The GUID was printed.
+ EFI_INVALID_PARAMETER The input was NULL.
+
+--*/
+{
+ if (Guid == NULL) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ printf (
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+ (unsigned) Guid->Data1,
+ Guid->Data2,
+ Guid->Data3,
+ Guid->Data4[0],
+ Guid->Data4[1],
+ Guid->Data4[2],
+ Guid->Data4[3],
+ Guid->Data4[4],
+ Guid->Data4[5],
+ Guid->Data4[6],
+ Guid->Data4[7]
+ );
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PrintGuidToBuffer (
+ IN EFI_GUID *Guid,
+ IN OUT UINT8 *Buffer,
+ IN UINT32 BufferLen,
+ IN BOOLEAN Uppercase
+ )
+/*++
+
+Routine Description:
+
+ This function prints a GUID to a buffer
+
+Arguments:
+
+ Guid - Pointer to a GUID to print.
+ Buffer - Pointer to a user-provided buffer to print to
+ BufferLen - Size of the Buffer
+ Uppercase - If use upper case.
+
+Returns:
+
+ EFI_SUCCESS The GUID was printed.
+ EFI_INVALID_PARAMETER The input was NULL.
+ EFI_BUFFER_TOO_SMALL The input buffer was not big enough
+
+--*/
+{
+ if (Guid == NULL) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (Uppercase) {
+ sprintf (
+ (CHAR8 *)Buffer,
+ "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ (unsigned) Guid->Data1,
+ Guid->Data2,
+ Guid->Data3,
+ Guid->Data4[0],
+ Guid->Data4[1],
+ Guid->Data4[2],
+ Guid->Data4[3],
+ Guid->Data4[4],
+ Guid->Data4[5],
+ Guid->Data4[6],
+ Guid->Data4[7]
+ );
+ } else {
+ sprintf (
+ (CHAR8 *)Buffer,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (unsigned) Guid->Data1,
+ Guid->Data2,
+ Guid->Data3,
+ Guid->Data4[0],
+ Guid->Data4[1],
+ Guid->Data4[2],
+ Guid->Data4[3],
+ Guid->Data4[4],
+ Guid->Data4[5],
+ Guid->Data4[6],
+ Guid->Data4[7]
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+#ifdef __GNUC__
+
+size_t _filelength(int fd)
+{
+ struct stat stat_buf;
+ fstat(fd, &stat_buf);
+ return stat_buf.st_size;
+}
+
+#ifndef __CYGWIN__
+char *strlwr(char *s)
+{
+ char *p = s;
+ for(;*s;s++) {
+ *s = tolower(*s);
+ }
+ return p;
+}
+#endif
+#endif
+
+#define WINDOWS_EXTENSION_PATH "\\\\?\\"
+#define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
+
+//
+// Global data to store full file path. It is not required to be free.
+//
+CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH];
+
+CHAR8 *
+LongFilePath (
+ IN CHAR8 *FileName
+ )
+/*++
+
+Routine Description:
+ Convert FileName to the long file path, which can support larger than 260 length.
+
+Arguments:
+ FileName - FileName.
+
+Returns:
+ LongFilePath A pointer to the converted long file path.
+
+--*/
+{
+#ifdef __GNUC__
+ //
+ // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
+ // unix has no limitation on file path. Just return FileName.
+ //
+ return FileName;
+#else
+ CHAR8 *RootPath;
+ CHAR8 *PathPointer;
+ CHAR8 *NextPointer;
+
+ PathPointer = (CHAR8 *) FileName;
+
+ if (FileName != NULL) {
+ //
+ // Add the extension string first to support long file path.
+ //
+ mCommonLibFullPath[0] = 0;
+ strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH);
+
+ if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') {
+ //
+ // network path like \\server\share to \\?\UNC\server\share
+ //
+ strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH);
+ FileName ++;
+ } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) {
+ //
+ // Relative file path. Convert it to absolute path.
+ //
+ RootPath = getcwd (NULL, 0);
+ if (RootPath != NULL) {
+ if (strlen (mCommonLibFullPath) + strlen (RootPath) > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
+ free (RootPath);
+ return NULL;
+ }
+ strncat (mCommonLibFullPath, RootPath, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+ if (FileName[0] != '\\' && FileName[0] != '/') {
+ if (strlen (mCommonLibFullPath) + 1 > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
+ free (RootPath);
+ return NULL;
+ }
+ //
+ // Attach directory separator
+ //
+ strncat (mCommonLibFullPath, "\\", MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+ }
+ free (RootPath);
+ }
+ }
+
+ //
+ // Construct the full file path
+ //
+ if (strlen (mCommonLibFullPath) + strlen (FileName) > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName);
+ return NULL;
+ }
+ strncat (mCommonLibFullPath, FileName, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+
+ //
+ // Convert directory separator '/' to '\\'
+ //
+ PathPointer = (CHAR8 *) mCommonLibFullPath;
+ do {
+ if (*PathPointer == '/') {
+ *PathPointer = '\\';
+ }
+ } while (*PathPointer ++ != '\0');
+
+ //
+ // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
+ //
+ if ((PathPointer = strstr (mCommonLibFullPath, ":\\\\")) != NULL) {
+ *(PathPointer + 2) = '\0';
+ strncat (mCommonLibFullPath, PathPointer + 3, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+ }
+
+ //
+ // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
+ //
+ while ((PathPointer = strstr (mCommonLibFullPath, ".\\")) != NULL) {
+ *PathPointer = '\0';
+ strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+ }
+
+ //
+ // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
+ //
+ while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) {
+ *PathPointer = '\0';
+ strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+ }
+
+ //
+ // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
+ //
+ while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) {
+ NextPointer = PathPointer + 3;
+ do {
+ PathPointer --;
+ } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\');
+
+ if (*PathPointer == '\\') {
+ //
+ // Skip one directory
+ //
+ *PathPointer = '\0';
+ strncat (mCommonLibFullPath, NextPointer, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
+ } else {
+ //
+ // No directory is found. Just break.
+ //
+ break;
+ }
+ }
+
+ PathPointer = mCommonLibFullPath;
+ }
+
+ return PathPointer;
+#endif
+}
+
+CHAR16
+InternalCharToUpper (
+ CHAR16 Char
+ )
+{
+ if (Char >= L'a' && Char <= L'z') {
+ return (CHAR16) (Char - (L'a' - L'A'));
+ }
+
+ return Char;
+}
+
+UINTN
+StrnLenS (
+ CONST CHAR16 *String,
+ UINTN MaxSize
+ )
+{
+ UINTN Length;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
+ //
+ if ((String == NULL) || (MaxSize == 0)) {
+ return 0;
+ }
+
+ Length = 0;
+ while (String[Length] != 0) {
+ if (Length >= MaxSize - 1) {
+ return MaxSize;
+ }
+ Length++;
+ }
+ return Length;
+}
+
+
+VOID *
+InternalAllocatePool (
+ UINTN AllocationSize
+ )
+{
+ VOID * Memory;
+
+ Memory = malloc(AllocationSize);
+ ASSERT(Memory != NULL);
+ return Memory;
+}
+
+
+VOID *
+InternalReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ )
+{
+ VOID *NewBuffer;
+
+ NewBuffer = AllocateZeroPool (NewSize);
+ if (NewBuffer != NULL && OldBuffer != NULL) {
+ memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
+ free(OldBuffer);
+ }
+ return NewBuffer;
+}
+
+VOID *
+ReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ )
+{
+ return InternalReallocatePool (OldSize, NewSize, OldBuffer);
+}
+
+/**
+ Returns the length of a Null-terminated Unicode string.
+
+ This function returns the number of Unicode characters in the Null-terminated
+ Unicode string specified by String.
+
+ If String is NULL, then ASSERT().
+ If String is not aligned on a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the
+ Null-terminator, then ASSERT().
+
+ @param String A pointer to a Null-terminated Unicode string.
+
+ @return The length of String.
+
+**/
+UINTN
+StrLen (
+ CONST CHAR16 *String
+ )
+{
+ UINTN Length;
+
+ ASSERT (String != NULL);
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ for (Length = 0; *String != L'\0'; String++, Length++) {
+ //
+ // If PcdMaximumUnicodeStringLength is not zero,
+ // length should not more than PcdMaximumUnicodeStringLength
+ //
+ }
+ return Length;
+}
+
+BOOLEAN
+InternalSafeStringIsOverlap (
+ IN VOID *Base1,
+ IN UINTN Size1,
+ IN VOID *Base2,
+ IN UINTN Size2
+ )
+{
+ if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
+ (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOLEAN
+InternalSafeStringNoStrOverlap (
+ IN CHAR16 *Str1,
+ IN UINTN Size1,
+ IN CHAR16 *Str2,
+ IN UINTN Size2
+ )
+{
+ return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
+}
+
+/**
+ Convert a Null-terminated Unicode decimal string to a value of type UINT64.
+
+ This function outputs a value of type UINT64 by interpreting the contents of
+ the Unicode string specified by String as a decimal number. The format of the
+ input Unicode string String is:
+
+ [spaces] [decimal digits].
+
+ The valid decimal digit character is in the range [0-9]. The function will
+ ignore the pad space, which includes spaces or tab characters, before
+ [decimal digits]. The running zero in the beginning of [decimal digits] will
+ be ignored. Then, the function stops at the first character that is a not a
+ valid decimal character or a Null-terminator, whichever one comes first.
+
+ If String is NULL, then ASSERT().
+ If Data is NULL, then ASSERT().
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the
+ Null-terminator, then ASSERT().
+
+ If String has no valid decimal digits in the above format, then 0 is stored
+ at the location pointed to by Data.
+ If the number represented by String exceeds the range defined by UINT64, then
+ MAX_UINT64 is stored at the location pointed to by Data.
+
+ If EndPointer is not NULL, a pointer to the character that stopped the scan
+ is stored at the location pointed to by EndPointer. If String has no valid
+ decimal digits right after the optional pad spaces, the value of String is
+ stored at the location pointed to by EndPointer.
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param EndPointer Pointer to character that stops scan.
+ @param Data Pointer to the converted value.
+
+ @retval RETURN_SUCCESS Value is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ If PcdMaximumUnicodeStringLength is not
+ zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode
+ characters, not including the
+ Null-terminator.
+ @retval RETURN_UNSUPPORTED If the number represented by String exceeds
+ the range defined by UINT64.
+
+**/
+RETURN_STATUS
+StrDecimalToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINT64 *Data
+ )
+{
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. Neither String nor Data shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. The length of String shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*String == L' ') || (*String == L'\t')) {
+ String++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*String == L'0') {
+ String++;
+ }
+
+ *Data = 0;
+
+ while (InternalIsDecimalDigitCharacter (*String)) {
+ //
+ // If the number represented by String overflows according to the range
+ // defined by UINT64, then MAX_UINT64 is stored in *Data and
+ // RETURN_UNSUPPORTED is returned.
+ //
+ if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) {
+ *Data = MAX_UINT64;
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_UNSUPPORTED;
+ }
+
+ *Data = (*Data) * 10 + (*String - L'0');
+ String++;
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Convert a Null-terminated Unicode hexadecimal string to a value of type
+ UINT64.
+
+ This function outputs a value of type UINT64 by interpreting the contents of
+ the Unicode string specified by String as a hexadecimal number. The format of
+ the input Unicode string String is:
+
+ [spaces][zeros][x][hexadecimal digits].
+
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+ If "x" appears in the input string, it must be prefixed with at least one 0.
+ The function will ignore the pad space, which includes spaces or tab
+ characters, before [zeros], [x] or [hexadecimal digit]. The running zero
+ before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
+ after [x] or the first valid hexadecimal digit. Then, the function stops at
+ the first character that is a not a valid hexadecimal character or NULL,
+ whichever one comes first.
+
+ If String is NULL, then ASSERT().
+ If Data is NULL, then ASSERT().
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the
+ Null-terminator, then ASSERT().
+
+ If String has no valid hexadecimal digits in the above format, then 0 is
+ stored at the location pointed to by Data.
+ If the number represented by String exceeds the range defined by UINT64, then
+ MAX_UINT64 is stored at the location pointed to by Data.
+
+ If EndPointer is not NULL, a pointer to the character that stopped the scan
+ is stored at the location pointed to by EndPointer. If String has no valid
+ hexadecimal digits right after the optional pad spaces, the value of String
+ is stored at the location pointed to by EndPointer.
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param EndPointer Pointer to character that stops scan.
+ @param Data Pointer to the converted value.
+
+ @retval RETURN_SUCCESS Value is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ If PcdMaximumUnicodeStringLength is not
+ zero, and String contains more than
+ PcdMaximumUnicodeStringLength Unicode
+ characters, not including the
+ Null-terminator.
+ @retval RETURN_UNSUPPORTED If the number represented by String exceeds
+ the range defined by UINT64.
+
+**/
+RETURN_STATUS
+StrHexToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINT64 *Data
+ )
+{
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. Neither String nor Data shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. The length of String shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*String == L' ') || (*String == L'\t')) {
+ String++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*String == L'0') {
+ String++;
+ }
+
+ if (InternalCharToUpper (*String) == L'X') {
+ if (*(String - 1) != L'0') {
+ *Data = 0;
+ return RETURN_SUCCESS;
+ }
+ //
+ // Skip the 'X'
+ //
+ String++;
+ }
+
+ *Data = 0;
+
+ while (InternalIsHexaDecimalDigitCharacter (*String)) {
+ //
+ // If the number represented by String overflows according to the range
+ // defined by UINT64, then MAX_UINT64 is stored in *Data and
+ // RETURN_UNSUPPORTED is returned.
+ //
+ if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) {
+ *Data = MAX_UINT64;
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_UNSUPPORTED;
+ }
+
+ *Data = ((*Data) << 4) + InternalHexCharToUintn (*String);
+ String++;
+ }
+
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) String;
+ }
+ return RETURN_SUCCESS;
+}
+
+UINT64
+StrDecimalToUint64 (
+ CONST CHAR16 *String
+ )
+{
+ UINT64 Result;
+
+ StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
+ return Result;
+}
+
+
+UINT64
+StrHexToUint64 (
+ CONST CHAR16 *String
+ )
+{
+ UINT64 Result;
+
+ StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
+ return Result;
+}
+
+UINTN
+StrSize (
+ CONST CHAR16 *String
+ )
+{
+ return (StrLen (String) + 1) * sizeof (*String);
+}
+
+
+UINT64
+ReadUnaligned64 (
+ CONST UINT64 *Buffer
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer;
+}
+
+UINT64
+WriteUnaligned64 (
+ UINT64 *Buffer,
+ UINT64 Value
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer = Value;
+}
+
+
+EFI_GUID *
+CopyGuid (
+ EFI_GUID *DestinationGuid,
+ CONST EFI_GUID *SourceGuid
+ )
+{
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid)
+ );
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid + 1,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
+ );
+ return DestinationGuid;
+}
+
+UINT16
+SwapBytes16 (
+ UINT16 Value
+ )
+{
+ return (UINT16) ((Value<< 8) | (Value>> 8));
+}
+
+
+UINT32
+SwapBytes32 (
+ UINT32 Value
+ )
+{
+ UINT32 LowerBytes;
+ UINT32 HigherBytes;
+
+ LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value);
+ HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));
+ return (LowerBytes << 16 | HigherBytes);
+}
+
+BOOLEAN
+InternalIsDecimalDigitCharacter (
+ CHAR16 Char
+ )
+{
+ return (BOOLEAN) (Char >= L'0' && Char <= L'9');
+}
+
+VOID *
+InternalAllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+
+ Memory = malloc (AllocationSize);
+ if (Memory != NULL) {
+ Memory = memcpy (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+BOOLEAN
+InternalIsHexaDecimalDigitCharacter (
+ CHAR16 Char
+ )
+{
+
+ return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
+ (Char >= L'A' && Char <= L'F') ||
+ (Char >= L'a' && Char <= L'f'));
+}
+
+UINTN
+InternalHexCharToUintn (
+ CHAR16 Char
+ )
+{
+ if (InternalIsDecimalDigitCharacter (Char)) {
+ return Char - L'0';
+ }
+
+ return (10 + InternalCharToUpper (Char) - L'A');
+}
+
+
+/**
+ Convert a Null-terminated Unicode hexadecimal string to a byte array.
+
+ This function outputs a byte array by interpreting the contents of
+ the Unicode string specified by String in hexadecimal format. The format of
+ the input Unicode string String is:
+
+ [XX]*
+
+ X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+ The function decodes every two hexadecimal digit characters as one byte. The
+ decoding stops after Length of characters and outputs Buffer containing
+ (Length / 2) bytes.
+
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+
+ If String is NULL, then ASSERT().
+
+ If Buffer is NULL, then ASSERT().
+
+ If Length is not multiple of 2, then ASSERT().
+
+ If PcdMaximumUnicodeStringLength is not zero and Length is greater than
+ PcdMaximumUnicodeStringLength, then ASSERT().
+
+ If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param Length The number of Unicode characters to decode.
+ @param Buffer Pointer to the converted bytes array.
+ @param MaxBufferSize The maximum size of Buffer.
+
+ @retval RETURN_SUCCESS Buffer is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ If Length is not multiple of 2.
+ If PcdMaximumUnicodeStringLength is not zero,
+ and Length is greater than
+ PcdMaximumUnicodeStringLength.
+ @retval RETURN_UNSUPPORTED If Length of characters from String contain
+ a character that is not valid hexadecimal
+ digit characters, or a Null-terminator.
+ @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+StrHexToBytes (
+ CONST CHAR16 *String,
+ UINTN Length,
+ UINT8 *Buffer,
+ UINTN MaxBufferSize
+ )
+{
+ UINTN Index;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Buffer shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. Length shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ //
+ // 3. Length shall not be odd.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
+
+ //
+ // 4. MaxBufferSize shall equal to or greater than Length / 2.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
+
+ //
+ // 5. String shall not contains invalid hexadecimal digits.
+ //
+ for (Index = 0; Index < Length; Index++) {
+ if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
+ break;
+ }
+ }
+ if (Index != Length) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Convert the hex string to bytes.
+ //
+ for(Index = 0; Index < Length; Index++) {
+
+ //
+ // For even characters, write the upper nibble for each buffer byte,
+ // and for even characters, the lower nibble.
+ //
+ if ((Index & BIT0) == 0) {
+ Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
+ } else {
+ Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
+ }
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Convert a Null-terminated Unicode GUID string to a value of type
+ EFI_GUID.
+
+ This function outputs a GUID value by interpreting the contents of
+ the Unicode string specified by String. The format of the input
+ Unicode string String consists of 36 characters, as follows:
+
+ aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+ The pairs aa - pp are two characters in the range [0-9], [a-f] and
+ [A-F], with each pair representing a single byte hexadecimal value.
+
+ The mapping between String and the EFI_GUID structure is as follows:
+ aa Data1[24:31]
+ bb Data1[16:23]
+ cc Data1[8:15]
+ dd Data1[0:7]
+ ee Data2[8:15]
+ ff Data2[0:7]
+ gg Data3[8:15]
+ hh Data3[0:7]
+ ii Data4[0:7]
+ jj Data4[8:15]
+ kk Data4[16:23]
+ ll Data4[24:31]
+ mm Data4[32:39]
+ nn Data4[40:47]
+ oo Data4[48:55]
+ pp Data4[56:63]
+
+ If String is NULL, then ASSERT().
+ If Guid is NULL, then ASSERT().
+ If String is not aligned in a 16-bit boundary, then ASSERT().
+
+ @param String Pointer to a Null-terminated Unicode string.
+ @param Guid Pointer to the converted GUID.
+
+ @retval RETURN_SUCCESS Guid is translated from String.
+ @retval RETURN_INVALID_PARAMETER If String is NULL.
+ If Data is NULL.
+ @retval RETURN_UNSUPPORTED If String is not as the above format.
+
+**/
+RETURN_STATUS
+StrToGuid (
+ CONST CHAR16 *String,
+ EFI_GUID *Guid
+ )
+{
+ RETURN_STATUS Status;
+ EFI_GUID LocalGuid;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Guid shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // Get aabbccdd in big-endian.
+ //
+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Convert big-endian to little-endian.
+ //
+ LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
+ String += 2 * sizeof (LocalGuid.Data1) + 1;
+
+ //
+ // Get eeff in big-endian.
+ //
+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Convert big-endian to little-endian.
+ //
+ LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
+ String += 2 * sizeof (LocalGuid.Data2) + 1;
+
+ //
+ // Get gghh in big-endian.
+ //
+ Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
+ if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ //
+ // Convert big-endian to little-endian.
+ //
+ LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
+ String += 2 * sizeof (LocalGuid.Data3) + 1;
+
+ //
+ // Get iijj.
+ //
+ Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
+ if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
+ return RETURN_UNSUPPORTED;
+ }
+ String += 2 * 2 + 1;
+
+ //
+ // Get kkllmmnnoopp.
+ //
+ Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
+ if (RETURN_ERROR (Status)) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ CopyGuid (Guid, &LocalGuid);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Compares up to a specified length the contents of two Null-terminated Unicode strings,
+ and returns the difference between the first mismatched Unicode characters.
+
+ This function compares the Null-terminated Unicode string FirstString to the
+ Null-terminated Unicode string SecondString. At most, Length Unicode
+ characters will be compared. If Length is 0, then 0 is returned. If
+ FirstString is identical to SecondString, then 0 is returned. Otherwise, the
+ value returned is the first mismatched Unicode character in SecondString
+ subtracted from the first mismatched Unicode character in FirstString.
+
+ If Length > 0 and FirstString is NULL, then ASSERT().
+ If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
+ If Length > 0 and SecondString is NULL, then ASSERT().
+ If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
+ PcdMaximumUnicodeStringLength, then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+ then ASSERT().
+ If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
+ PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+ then ASSERT().
+
+ @param FirstString A pointer to a Null-terminated Unicode string.
+ @param SecondString A pointer to a Null-terminated Unicode string.
+ @param Length The maximum number of Unicode characters to compare.
+
+ @retval 0 FirstString is identical to SecondString.
+ @return others FirstString is not identical to SecondString.
+
+**/
+INTN
+StrnCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString,
+ UINTN Length
+ )
+{
+ if (Length == 0) {
+ return 0;
+ }
+
+ //
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
+ // Length tests are performed inside StrLen().
+ //
+ ASSERT (StrSize (FirstString) != 0);
+ ASSERT (StrSize (SecondString) != 0);
+
+ while ((*FirstString != L'\0') &&
+ (*SecondString != L'\0') &&
+ (*FirstString == *SecondString) &&
+ (Length > 1)) {
+ FirstString++;
+ SecondString++;
+ Length--;
+ }
+
+ return *FirstString - *SecondString;
+}
+
+VOID *
+AllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ )
+{
+ return InternalAllocateCopyPool (AllocationSize, Buffer);
+}
+
+INTN
+StrCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString
+ )
+{
+ //
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
+ //
+ ASSERT (StrSize (FirstString) != 0);
+ ASSERT (StrSize (SecondString) != 0);
+
+ while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
+ FirstString++;
+ SecondString++;
+ }
+ return *FirstString - *SecondString;
+}
+
+UINT64
+SwapBytes64 (
+ UINT64 Value
+ )
+{
+ return InternalMathSwapBytes64 (Value);
+}
+
+UINT64
+InternalMathSwapBytes64 (
+ UINT64 Operand
+ )
+{
+ UINT64 LowerBytes;
+ UINT64 HigherBytes;
+
+ LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand);
+ HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));
+
+ return (LowerBytes << 32 | HigherBytes);
+}
+
+RETURN_STATUS
+StrToIpv4Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv4_ADDRESS *Address,
+ UINT8 *PrefixLength
+ )
+{
+ RETURN_STATUS Status;
+ UINTN AddressIndex;
+ UINT64 Uint64;
+ EFI_IPv4_ADDRESS LocalAddress;
+ UINT8 LocalPrefixLength;
+ CHAR16 *Pointer;
+
+ LocalPrefixLength = MAX_UINT8;
+ LocalAddress.Addr[0] = 0;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Guid shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+ for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+ if (!InternalIsDecimalDigitCharacter (*Pointer)) {
+ //
+ // D or P contains invalid characters.
+ //
+ break;
+ }
+
+ //
+ // Get D or P.
+ //
+ Status = StrDecimalToUint64S ((CONST CHAR16 *) Pointer, &Pointer, &Uint64);
+ if (RETURN_ERROR (Status)) {
+ return RETURN_UNSUPPORTED;
+ }
+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ //
+ // It's P.
+ //
+ if (Uint64 > 32) {
+ return RETURN_UNSUPPORTED;
+ }
+ LocalPrefixLength = (UINT8) Uint64;
+ } else {
+ //
+ // It's D.
+ //
+ if (Uint64 > MAX_UINT8) {
+ return RETURN_UNSUPPORTED;
+ }
+ LocalAddress.Addr[AddressIndex] = (UINT8) Uint64;
+ AddressIndex++;
+ }
+
+ //
+ // Check the '.' or '/', depending on the AddressIndex.
+ //
+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ if (*Pointer == L'/') {
+ //
+ // '/P' is in the String.
+ // Skip "/" and get P in next loop.
+ //
+ Pointer++;
+ } else {
+ //
+ // '/P' is not in the String.
+ //
+ break;
+ }
+ } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+ if (*Pointer == L'.') {
+ //
+ // D should be followed by '.'
+ //
+ Pointer++;
+ } else {
+ return RETURN_UNSUPPORTED;
+ }
+ }
+ }
+
+ if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ memcpy (Address, &LocalAddress, sizeof (*Address));
+ if (PrefixLength != NULL) {
+ *PrefixLength = LocalPrefixLength;
+ }
+ if (EndPointer != NULL) {
+ *EndPointer = Pointer;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+StrToIpv6Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv6_ADDRESS *Address,
+ UINT8 *PrefixLength
+ )
+{
+ RETURN_STATUS Status;
+ UINTN AddressIndex;
+ UINT64 Uint64;
+ EFI_IPv6_ADDRESS LocalAddress;
+ UINT8 LocalPrefixLength;
+ CONST CHAR16 *Pointer;
+ CHAR16 *End;
+ UINTN CompressStart;
+ BOOLEAN ExpectPrefix;
+
+ LocalPrefixLength = MAX_UINT8;
+ CompressStart = ARRAY_SIZE (Address->Addr);
+ ExpectPrefix = FALSE;
+
+ ASSERT (((UINTN) String & BIT0) == 0);
+
+ //
+ // 1. None of String or Guid shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+ for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+ if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+ if (*Pointer != L':') {
+ //
+ // ":" or "/" should be followed by digit characters.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Meet second ":" after previous ":" or "/"
+ // or meet first ":" in the beginning of String.
+ //
+ if (ExpectPrefix) {
+ //
+ // ":" shall not be after "/"
+ //
+ return RETURN_UNSUPPORTED;
+ }
+
+ if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ //
+ // "::" can only appear once.
+ // "::" can only appear when address is not full length.
+ //
+ return RETURN_UNSUPPORTED;
+ } else {
+ //
+ // Remember the start of zero compressing.
+ //
+ CompressStart = AddressIndex;
+ Pointer++;
+
+ if (CompressStart == 0) {
+ if (*Pointer != L':') {
+ //
+ // Single ":" shall not be in the beginning of String.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ Pointer++;
+ }
+ }
+ }
+
+ if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+ if (*Pointer == L'/') {
+ //
+ // Might be optional "/P" after "::".
+ //
+ if (CompressStart != AddressIndex) {
+ return RETURN_UNSUPPORTED;
+ }
+ } else {
+ break;
+ }
+ } else {
+ if (!ExpectPrefix) {
+ //
+ // Get X.
+ //
+ Status = StrHexToUint64S (Pointer, &End, &Uint64);
+ if (RETURN_ERROR (Status) || End - Pointer > 4) {
+ //
+ // Number of hexadecimal digit characters is no more than 4.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ Pointer = End;
+ //
+ // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
+ //
+ ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
+ LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uint64 >> 8);
+ LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uint64;
+ AddressIndex += 2;
+ } else {
+ //
+ // Get P, then exit the loop.
+ //
+ Status = StrDecimalToUint64S (Pointer, &End, &Uint64);
+ if (RETURN_ERROR (Status) || End == Pointer || Uint64 > 128) {
+ //
+ // Prefix length should not exceed 128.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ LocalPrefixLength = (UINT8) Uint64;
+ Pointer = End;
+ break;
+ }
+ }
+
+ //
+ // Skip ':' or "/"
+ //
+ if (*Pointer == L'/') {
+ ExpectPrefix = TRUE;
+ } else if (*Pointer == L':') {
+ if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+ //
+ // Meet additional ":" after all 8 16-bit address
+ //
+ break;
+ }
+ } else {
+ //
+ // Meet other character that is not "/" or ":" after all 8 16-bit address
+ //
+ break;
+ }
+ Pointer++;
+ }
+
+ if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
+ (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
+ ) {
+ //
+ // Full length of address shall not have compressing zeros.
+ // Non-full length of address shall have compressing zeros.
+ //
+ return RETURN_UNSUPPORTED;
+ }
+ memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
+ if (AddressIndex > CompressStart) {
+ memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) - AddressIndex);
+ memcpy (
+ &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
+ &LocalAddress.Addr[CompressStart],
+ AddressIndex - CompressStart
+ );
+ }
+
+ if (PrefixLength != NULL) {
+ *PrefixLength = LocalPrefixLength;
+ }
+ if (EndPointer != NULL) {
+ *EndPointer = (CHAR16 *) Pointer;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+RETURN_STATUS
+UnicodeStrToAsciiStrS (
+ CONST CHAR16 *Source,
+ CHAR8 *Destination,
+ UINTN DestMax
+ )
+{
+ UINTN SourceLen;
+
+ ASSERT (((UINTN) Source & BIT0) == 0);
+
+ //
+ // 1. Neither Destination nor Source shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
+ //
+ if (ASCII_RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ //
+ // 3. DestMax shall not equal zero.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
+
+ //
+ // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
+ //
+ SourceLen = StrnLenS (Source, DestMax);
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
+
+ //
+ // 5. Copying shall not take place between objects that overlap.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
+
+ //
+ // convert string
+ //
+ while (*Source != '\0') {
+ //
+ // If any Unicode characters in Source contain
+ // non-zero value in the upper 8 bits, then ASSERT().
+ //
+ ASSERT (*Source < 0x100);
+ *(Destination++) = (CHAR8) *(Source++);
+ }
+ *Destination = '\0';
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+StrCpyS (
+ CHAR16 *Destination,
+ UINTN DestMax,
+ CONST CHAR16 *Source
+ )
+{
+ UINTN SourceLen;
+
+ ASSERT (((UINTN) Destination & BIT0) == 0);
+ ASSERT (((UINTN) Source & BIT0) == 0);
+
+ //
+ // 1. Neither Destination nor Source shall be a null pointer.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
+ SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
+
+ //
+ // 2. DestMax shall not be greater than RSIZE_MAX.
+ //
+ if (RSIZE_MAX != 0) {
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+ }
+
+ //
+ // 3. DestMax shall not equal zero.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
+
+ //
+ // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
+ //
+ SourceLen = StrnLenS (Source, DestMax);
+ SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
+
+ //
+ // 5. Copying shall not take place between objects that overlap.
+ //
+ SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
+
+ //
+ // The StrCpyS function copies the string pointed to by Source (including the terminating
+ // null character) into the array pointed to by Destination.
+ //
+ while (*Source != 0) {
+ *(Destination++) = *(Source++);
+ }
+ *Destination = 0;
+
+ return RETURN_SUCCESS;
+}
+
+VOID *
+AllocateZeroPool (
+ UINTN AllocationSize
+ )
+{
+ VOID * Memory;
+ Memory = malloc(AllocationSize);
+ ASSERT (Memory != NULL);
+ if (Memory == NULL) {
+ fprintf(stderr, "Not memory for malloc\n");
+ }
+ memset(Memory, 0, AllocationSize);
+ return Memory;
+}
+
+VOID *
+AllocatePool (
+ UINTN AllocationSize
+ )
+{
+ return InternalAllocatePool (AllocationSize);
+}
+
+UINT16
+WriteUnaligned16 (
+ UINT16 *Buffer,
+ UINT16 Value
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer = Value;
+}
+
+UINT16
+ReadUnaligned16 (
+ CONST UINT16 *Buffer
+ )
+{
+ ASSERT (Buffer != NULL);
+
+ return *Buffer;
+}
+/**
+ Return whether the integer string is a hex string.
+
+ @param Str The integer string
+
+ @retval TRUE Hex string
+ @retval FALSE Decimal string
+
+**/
+BOOLEAN
+IsHexStr (
+ CHAR16 *Str
+ )
+{
+ //
+ // skip preceding white space
+ //
+ while ((*Str != 0) && *Str == L' ') {
+ Str ++;
+ }
+ //
+ // skip preceding zeros
+ //
+ while ((*Str != 0) && *Str == L'0') {
+ Str ++;
+ }
+
+ return (BOOLEAN) (*Str == L'x' || *Str == L'X');
+}
+
+/**
+
+ Convert integer string to uint.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+
+ @return A UINTN value represented by Str
+
+**/
+UINTN
+Strtoi (
+ CHAR16 *Str
+ )
+{
+ if (IsHexStr (Str)) {
+ return (UINTN)StrHexToUint64 (Str);
+ } else {
+ return (UINTN)StrDecimalToUint64 (Str);
+ }
+}
+
+/**
+
+ Convert integer string to 64 bit data.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+ @param Data A pointer to the UINT64 value represented by Str
+
+**/
+VOID
+Strtoi64 (
+ CHAR16 *Str,
+ UINT64 *Data
+ )
+{
+ if (IsHexStr (Str)) {
+ *Data = StrHexToUint64 (Str);
+ } else {
+ *Data = StrDecimalToUint64 (Str);
+ }
+}
+
+/**
+ Converts a Unicode string to ASCII string.
+
+ @param Str The equivalent Unicode string
+ @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
+ to the next ASCII string next to it
+
+**/
+VOID
+StrToAscii (
+ CHAR16 *Str,
+ CHAR8 **AsciiStr
+ )
+{
+ CHAR8 *Dest;
+
+ Dest = *AsciiStr;
+ while (!IS_NULL (*Str)) {
+ *(Dest++) = (CHAR8) *(Str++);
+ }
+ *Dest = 0;
+
+ //
+ // Return the string next to it
+ //
+ *AsciiStr = Dest + 1;
+}
+
+/**
+ Gets current sub-string from a string list, before return
+ the list header is moved to next sub-string. The sub-string is separated
+ by the specified character. For example, the separator is ',', the string
+ list is "2,0,3", it returns "2", the remain list move to "0,3"
+
+ @param List A string list separated by the specified separator
+ @param Separator The separator character
+
+ @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+SplitStr (
+ CHAR16 **List,
+ CHAR16 Separator
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+
+ Str = *List;
+ ReturnStr = Str;
+
+ if (IS_NULL (*Str)) {
+ return ReturnStr;
+ }
+
+ //
+ // Find first occurrence of the separator
+ //
+ while (!IS_NULL (*Str)) {
+ if (*Str == Separator) {
+ break;
+ }
+ Str++;
+ }
+
+ if (*Str == Separator) {
+ //
+ // Find a sub-string, terminate it
+ //
+ *Str = L'\0';
+ Str++;
+ }
+
+ //
+ // Move to next sub-string
+ //
+ *List = Str;
+ return ReturnStr;
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.h
new file mode 100644
index 00000000..2fa4b576
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/CommonLib.h
@@ -0,0 +1,469 @@
+/** @file
+Common library assistance routines.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_COMMON_LIB_H
+#define _EFI_COMMON_LIB_H
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/BuildVersion.h>
+#include <assert.h>
+#ifndef _WIN32
+#include <limits.h>
+#endif
+
+#define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination
+
+#ifdef PATH_MAX
+#define MAX_LONG_FILE_PATH PATH_MAX
+#else
+#define MAX_LONG_FILE_PATH 500
+#endif
+
+#define MAX_UINT64 ((UINT64)0xFFFFFFFFFFFFFFFFULL)
+#define MAX_UINT32 ((UINT32)0xFFFFFFFF)
+#define MAX_UINT16 ((UINT16)0xFFFF)
+#define MAX_UINT8 ((UINT8)0xFF)
+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
+#define ASCII_RSIZE_MAX 1000000
+#undef RSIZE_MAX
+#define RSIZE_MAX 1000000
+
+#define IS_COMMA(a) ((a) == L',')
+#define IS_HYPHEN(a) ((a) == L'-')
+#define IS_DOT(a) ((a) == L'.')
+#define IS_LEFT_PARENTH(a) ((a) == L'(')
+#define IS_RIGHT_PARENTH(a) ((a) == L')')
+#define IS_SLASH(a) ((a) == L'/')
+#define IS_NULL(a) ((a) == L'\0')
+
+#define ASSERT(x) assert(x)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// Function declarations
+//
+VOID
+PeiZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+;
+
+VOID
+PeiCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+;
+
+VOID
+ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+;
+
+VOID
+CopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+;
+
+INTN
+CompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ )
+;
+
+EFI_STATUS
+GetFileImage (
+ IN CHAR8 *InputFileName,
+ OUT CHAR8 **InputFileImage,
+ OUT UINT32 *BytesRead
+ )
+;
+
+EFI_STATUS
+PutFileImage (
+ IN CHAR8 *OutputFileName,
+ IN CHAR8 *OutputFileImage,
+ IN UINT32 BytesToWrite
+ )
+;
+/*++
+
+Routine Description:
+
+ This function opens a file and writes OutputFileImage into the file.
+
+Arguments:
+
+ OutputFileName The name of the file to write.
+ OutputFileImage A pointer to the memory buffer.
+ BytesToWrite The size of the memory buffer.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED An error occurred.
+ EFI_OUT_OF_RESOURCES No resource to complete operations.
+
+**/
+
+UINT8
+CalculateChecksum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ )
+;
+
+UINT8
+CalculateSum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ )
+;
+
+UINT16
+CalculateChecksum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ )
+;
+
+UINT16
+CalculateSum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ )
+;
+
+EFI_STATUS
+PrintGuid (
+ IN EFI_GUID *Guid
+ )
+;
+
+#define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination
+EFI_STATUS
+PrintGuidToBuffer (
+ IN EFI_GUID *Guid,
+ IN OUT UINT8 *Buffer,
+ IN UINT32 BufferLen,
+ IN BOOLEAN Uppercase
+ )
+;
+
+CHAR8 *
+LongFilePath (
+ IN CHAR8 *FileName
+);
+
+UINTN
+StrLen (
+ CONST CHAR16 *String
+ );
+
+VOID *
+AllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ );
+
+INTN
+StrnCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString,
+ UINTN Length
+ );
+
+RETURN_STATUS
+StrToGuid (
+ CONST CHAR16 *String,
+ EFI_GUID *Guid
+ );
+
+RETURN_STATUS
+StrHexToBytes (
+ CONST CHAR16 *String,
+ UINTN Length,
+ UINT8 *Buffer,
+ UINTN MaxBufferSize
+ );
+
+UINTN
+InternalHexCharToUintn (
+ CHAR16 Char
+ );
+
+VOID *
+InternalAllocateCopyPool (
+ UINTN AllocationSize,
+ CONST VOID *Buffer
+ );
+
+BOOLEAN
+InternalIsDecimalDigitCharacter (
+ CHAR16 Char
+ );
+
+UINT32
+SwapBytes32 (
+ UINT32 Value
+ );
+
+UINT16
+SwapBytes16 (
+ UINT16 Value
+ );
+
+EFI_GUID *
+CopyGuid (
+ EFI_GUID *DestinationGuid,
+ CONST EFI_GUID *SourceGuid
+ );
+
+UINT64
+WriteUnaligned64 (
+ UINT64 *Buffer,
+ UINT64 Value
+ );
+
+UINT64
+ReadUnaligned64 (
+ CONST UINT64 *Buffer
+ );
+
+UINTN
+StrSize (
+ CONST CHAR16 *String
+ );
+
+UINT64
+StrHexToUint64 (
+ CONST CHAR16 *String
+ );
+
+UINT64
+StrDecimalToUint64 (
+ CONST CHAR16 *String
+ );
+
+RETURN_STATUS
+StrHexToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ UINT64 *Data
+ );
+
+RETURN_STATUS
+StrDecimalToUint64S (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer, OPTIONAL
+ UINT64 *Data
+ );
+
+VOID *
+ReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ );
+
+VOID *
+InternalReallocatePool (
+ UINTN OldSize,
+ UINTN NewSize,
+ VOID *OldBuffer OPTIONAL
+ );
+
+VOID *
+InternalAllocateZeroPool (
+ UINTN AllocationSize
+ ) ;
+
+VOID *
+InternalAllocatePool (
+ UINTN AllocationSize
+ );
+
+UINTN
+StrnLenS (
+ CONST CHAR16 *String,
+ UINTN MaxSize
+ );
+
+CHAR16
+InternalCharToUpper (
+ CHAR16 Char
+ );
+
+INTN
+StrCmp (
+ CONST CHAR16 *FirstString,
+ CONST CHAR16 *SecondString
+ );
+
+UINT64
+SwapBytes64 (
+ UINT64 Value
+ );
+
+UINT64
+InternalMathSwapBytes64 (
+ UINT64 Operand
+ );
+
+RETURN_STATUS
+StrToIpv4Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv4_ADDRESS *Address,
+ UINT8 *PrefixLength
+ );
+
+RETURN_STATUS
+StrToIpv6Address (
+ CONST CHAR16 *String,
+ CHAR16 **EndPointer,
+ EFI_IPv6_ADDRESS *Address,
+ UINT8 *PrefixLength
+ );
+
+RETURN_STATUS
+StrCpyS (
+ CHAR16 *Destination,
+ UINTN DestMax,
+ CONST CHAR16 *Source
+ );
+
+RETURN_STATUS
+UnicodeStrToAsciiStrS (
+ CONST CHAR16 *Source,
+ CHAR8 *Destination,
+ UINTN DestMax
+ );
+VOID *
+AllocatePool (
+ UINTN AllocationSize
+ );
+
+UINT16
+WriteUnaligned16 (
+ UINT16 *Buffer,
+ UINT16 Value
+ );
+
+UINT16
+ReadUnaligned16 (
+ CONST UINT16 *Buffer
+ );
+
+VOID *
+AllocateZeroPool (
+ UINTN AllocationSize
+ );
+
+BOOLEAN
+InternalIsHexaDecimalDigitCharacter (
+ CHAR16 Char
+ );
+
+BOOLEAN
+InternalSafeStringIsOverlap (
+ IN VOID *Base1,
+ IN UINTN Size1,
+ IN VOID *Base2,
+ IN UINTN Size2
+ );
+
+BOOLEAN
+InternalSafeStringNoStrOverlap (
+ IN CHAR16 *Str1,
+ IN UINTN Size1,
+ IN CHAR16 *Str2,
+ IN UINTN Size2
+ );
+
+BOOLEAN
+IsHexStr (
+ CHAR16 *Str
+ );
+
+UINTN
+Strtoi (
+ CHAR16 *Str
+ );
+
+VOID
+Strtoi64 (
+ CHAR16 *Str,
+ UINT64 *Data
+ );
+
+VOID
+StrToAscii (
+ CHAR16 *Str,
+ CHAR8 **AsciiStr
+ );
+
+CHAR16 *
+SplitStr (
+ CHAR16 **List,
+ CHAR16 Separator
+ );
+
+/*++
+
+Routine Description:
+ Convert FileName to the long file path, which can support larger than 260 length.
+
+Arguments:
+ FileName - FileName.
+
+Returns:
+ LongFilePath A pointer to the converted long file path.
+
+--*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __GNUC__
+#include <stdio.h>
+#include <sys/stat.h>
+#define stricmp strcasecmp
+#define _stricmp strcasecmp
+#define strnicmp strncasecmp
+#define strcmpi strcasecmp
+size_t _filelength(int fd);
+#ifndef __CYGWIN__
+char *strlwr(char *s);
+#endif
+#endif
+
+//
+// On windows, mkdir only has one parameter.
+// On unix, it has two parameters
+//
+#if defined(__GNUC__)
+#define mkdir(dir, perm) mkdir(dir, perm)
+#else
+#define mkdir(dir, perm) mkdir(dir)
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Compress.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Compress.h
new file mode 100644
index 00000000..bacc8183
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Compress.h
@@ -0,0 +1,82 @@
+/** @file
+Header file for compression routine.
+Providing both EFI and Tiano Compress algorithms.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _COMPRESS_H_
+#define _COMPRESS_H_
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "CommonLib.h"
+#include <Common/UefiBaseTypes.h>
+/*++
+
+Routine Description:
+
+ Tiano compression routine.
+
+--*/
+EFI_STATUS
+TianoCompress (
+ IN UINT8 *SrcBuffer,
+ IN UINT32 SrcSize,
+ IN UINT8 *DstBuffer,
+ IN OUT UINT32 *DstSize
+ )
+;
+
+/*++
+
+Routine Description:
+
+ Efi compression routine.
+
+--*/
+EFI_STATUS
+EfiCompress (
+ IN UINT8 *SrcBuffer,
+ IN UINT32 SrcSize,
+ IN UINT8 *DstBuffer,
+ IN OUT UINT32 *DstSize
+ )
+;
+
+/*++
+
+Routine Description:
+
+ The compression routine.
+
+Arguments:
+
+ SrcBuffer - The buffer storing the source data
+ SrcSize - The size of source data
+ DstBuffer - The buffer to store the compressed data
+ DstSize - On input, the size of DstBuffer; On output,
+ the size of the actual compressed data.
+
+Returns:
+
+ EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
+ DstSize contains the size needed.
+ EFI_SUCCESS - Compression is successful.
+ EFI_OUT_OF_RESOURCES - No resource to complete function.
+ EFI_INVALID_PARAMETER - Parameter supplied is wrong.
+
+--*/
+typedef
+EFI_STATUS
+(*COMPRESS_FUNCTION) (
+ IN UINT8 *SrcBuffer,
+ IN UINT32 SrcSize,
+ IN UINT8 *DstBuffer,
+ IN OUT UINT32 *DstSize
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.c
new file mode 100644
index 00000000..df823283
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.c
@@ -0,0 +1,313 @@
+/** @file
+CalculateCrc32 routine.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdlib.h>
+#include "Crc32.h"
+
+UINT32 mCrcTable[256] = {
+ 0x00000000,
+ 0x77073096,
+ 0xEE0E612C,
+ 0x990951BA,
+ 0x076DC419,
+ 0x706AF48F,
+ 0xE963A535,
+ 0x9E6495A3,
+ 0x0EDB8832,
+ 0x79DCB8A4,
+ 0xE0D5E91E,
+ 0x97D2D988,
+ 0x09B64C2B,
+ 0x7EB17CBD,
+ 0xE7B82D07,
+ 0x90BF1D91,
+ 0x1DB71064,
+ 0x6AB020F2,
+ 0xF3B97148,
+ 0x84BE41DE,
+ 0x1ADAD47D,
+ 0x6DDDE4EB,
+ 0xF4D4B551,
+ 0x83D385C7,
+ 0x136C9856,
+ 0x646BA8C0,
+ 0xFD62F97A,
+ 0x8A65C9EC,
+ 0x14015C4F,
+ 0x63066CD9,
+ 0xFA0F3D63,
+ 0x8D080DF5,
+ 0x3B6E20C8,
+ 0x4C69105E,
+ 0xD56041E4,
+ 0xA2677172,
+ 0x3C03E4D1,
+ 0x4B04D447,
+ 0xD20D85FD,
+ 0xA50AB56B,
+ 0x35B5A8FA,
+ 0x42B2986C,
+ 0xDBBBC9D6,
+ 0xACBCF940,
+ 0x32D86CE3,
+ 0x45DF5C75,
+ 0xDCD60DCF,
+ 0xABD13D59,
+ 0x26D930AC,
+ 0x51DE003A,
+ 0xC8D75180,
+ 0xBFD06116,
+ 0x21B4F4B5,
+ 0x56B3C423,
+ 0xCFBA9599,
+ 0xB8BDA50F,
+ 0x2802B89E,
+ 0x5F058808,
+ 0xC60CD9B2,
+ 0xB10BE924,
+ 0x2F6F7C87,
+ 0x58684C11,
+ 0xC1611DAB,
+ 0xB6662D3D,
+ 0x76DC4190,
+ 0x01DB7106,
+ 0x98D220BC,
+ 0xEFD5102A,
+ 0x71B18589,
+ 0x06B6B51F,
+ 0x9FBFE4A5,
+ 0xE8B8D433,
+ 0x7807C9A2,
+ 0x0F00F934,
+ 0x9609A88E,
+ 0xE10E9818,
+ 0x7F6A0DBB,
+ 0x086D3D2D,
+ 0x91646C97,
+ 0xE6635C01,
+ 0x6B6B51F4,
+ 0x1C6C6162,
+ 0x856530D8,
+ 0xF262004E,
+ 0x6C0695ED,
+ 0x1B01A57B,
+ 0x8208F4C1,
+ 0xF50FC457,
+ 0x65B0D9C6,
+ 0x12B7E950,
+ 0x8BBEB8EA,
+ 0xFCB9887C,
+ 0x62DD1DDF,
+ 0x15DA2D49,
+ 0x8CD37CF3,
+ 0xFBD44C65,
+ 0x4DB26158,
+ 0x3AB551CE,
+ 0xA3BC0074,
+ 0xD4BB30E2,
+ 0x4ADFA541,
+ 0x3DD895D7,
+ 0xA4D1C46D,
+ 0xD3D6F4FB,
+ 0x4369E96A,
+ 0x346ED9FC,
+ 0xAD678846,
+ 0xDA60B8D0,
+ 0x44042D73,
+ 0x33031DE5,
+ 0xAA0A4C5F,
+ 0xDD0D7CC9,
+ 0x5005713C,
+ 0x270241AA,
+ 0xBE0B1010,
+ 0xC90C2086,
+ 0x5768B525,
+ 0x206F85B3,
+ 0xB966D409,
+ 0xCE61E49F,
+ 0x5EDEF90E,
+ 0x29D9C998,
+ 0xB0D09822,
+ 0xC7D7A8B4,
+ 0x59B33D17,
+ 0x2EB40D81,
+ 0xB7BD5C3B,
+ 0xC0BA6CAD,
+ 0xEDB88320,
+ 0x9ABFB3B6,
+ 0x03B6E20C,
+ 0x74B1D29A,
+ 0xEAD54739,
+ 0x9DD277AF,
+ 0x04DB2615,
+ 0x73DC1683,
+ 0xE3630B12,
+ 0x94643B84,
+ 0x0D6D6A3E,
+ 0x7A6A5AA8,
+ 0xE40ECF0B,
+ 0x9309FF9D,
+ 0x0A00AE27,
+ 0x7D079EB1,
+ 0xF00F9344,
+ 0x8708A3D2,
+ 0x1E01F268,
+ 0x6906C2FE,
+ 0xF762575D,
+ 0x806567CB,
+ 0x196C3671,
+ 0x6E6B06E7,
+ 0xFED41B76,
+ 0x89D32BE0,
+ 0x10DA7A5A,
+ 0x67DD4ACC,
+ 0xF9B9DF6F,
+ 0x8EBEEFF9,
+ 0x17B7BE43,
+ 0x60B08ED5,
+ 0xD6D6A3E8,
+ 0xA1D1937E,
+ 0x38D8C2C4,
+ 0x4FDFF252,
+ 0xD1BB67F1,
+ 0xA6BC5767,
+ 0x3FB506DD,
+ 0x48B2364B,
+ 0xD80D2BDA,
+ 0xAF0A1B4C,
+ 0x36034AF6,
+ 0x41047A60,
+ 0xDF60EFC3,
+ 0xA867DF55,
+ 0x316E8EEF,
+ 0x4669BE79,
+ 0xCB61B38C,
+ 0xBC66831A,
+ 0x256FD2A0,
+ 0x5268E236,
+ 0xCC0C7795,
+ 0xBB0B4703,
+ 0x220216B9,
+ 0x5505262F,
+ 0xC5BA3BBE,
+ 0xB2BD0B28,
+ 0x2BB45A92,
+ 0x5CB36A04,
+ 0xC2D7FFA7,
+ 0xB5D0CF31,
+ 0x2CD99E8B,
+ 0x5BDEAE1D,
+ 0x9B64C2B0,
+ 0xEC63F226,
+ 0x756AA39C,
+ 0x026D930A,
+ 0x9C0906A9,
+ 0xEB0E363F,
+ 0x72076785,
+ 0x05005713,
+ 0x95BF4A82,
+ 0xE2B87A14,
+ 0x7BB12BAE,
+ 0x0CB61B38,
+ 0x92D28E9B,
+ 0xE5D5BE0D,
+ 0x7CDCEFB7,
+ 0x0BDBDF21,
+ 0x86D3D2D4,
+ 0xF1D4E242,
+ 0x68DDB3F8,
+ 0x1FDA836E,
+ 0x81BE16CD,
+ 0xF6B9265B,
+ 0x6FB077E1,
+ 0x18B74777,
+ 0x88085AE6,
+ 0xFF0F6A70,
+ 0x66063BCA,
+ 0x11010B5C,
+ 0x8F659EFF,
+ 0xF862AE69,
+ 0x616BFFD3,
+ 0x166CCF45,
+ 0xA00AE278,
+ 0xD70DD2EE,
+ 0x4E048354,
+ 0x3903B3C2,
+ 0xA7672661,
+ 0xD06016F7,
+ 0x4969474D,
+ 0x3E6E77DB,
+ 0xAED16A4A,
+ 0xD9D65ADC,
+ 0x40DF0B66,
+ 0x37D83BF0,
+ 0xA9BCAE53,
+ 0xDEBB9EC5,
+ 0x47B2CF7F,
+ 0x30B5FFE9,
+ 0xBDBDF21C,
+ 0xCABAC28A,
+ 0x53B39330,
+ 0x24B4A3A6,
+ 0xBAD03605,
+ 0xCDD70693,
+ 0x54DE5729,
+ 0x23D967BF,
+ 0xB3667A2E,
+ 0xC4614AB8,
+ 0x5D681B02,
+ 0x2A6F2B94,
+ 0xB40BBE37,
+ 0xC30C8EA1,
+ 0x5A05DF1B,
+ 0x2D02EF8D
+};
+
+EFI_STATUS
+CalculateCrc32 (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN OUT UINT32 *CrcOut
+ )
+/*++
+
+Routine Description:
+
+ The CalculateCrc32 routine.
+
+Arguments:
+
+ Data - The buffer containing the data to be processed
+ DataSize - The size of data to be processed
+ CrcOut - A pointer to the caller allocated UINT32 that on
+ contains the CRC32 checksum of Data
+
+Returns:
+
+ EFI_SUCCESS - Calculation is successful.
+ EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0
+
+--*/
+{
+ UINT32 Crc;
+ UINTN Index;
+ UINT8 *Ptr;
+
+ if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Crc = 0xffffffff;
+ for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {
+ Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];
+ }
+
+ *CrcOut = Crc ^ 0xffffffff;
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.h
new file mode 100644
index 00000000..a8c855c4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Crc32.h
@@ -0,0 +1,41 @@
+/** @file
+Header file for CalculateCrc32 routine
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _CRC32_H
+#define _CRC32_H
+
+#include <Common/UefiBaseTypes.h>
+
+EFI_STATUS
+CalculateCrc32 (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN OUT UINT32 *CrcOut
+ )
+/*++
+
+Routine Description:
+
+ The CalculateCrc32 routine.
+
+Arguments:
+
+ Data - The buffer containing the data to be processed
+ DataSize - The size of data to be processed
+ CrcOut - A pointer to the caller allocated UINT32 that on
+ contains the CRC32 checksum of Data
+
+Returns:
+
+ EFI_SUCCESS - Calculation is successful.
+ EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0
+
+--*/
+;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.c
new file mode 100644
index 00000000..e494437a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.c
@@ -0,0 +1,1014 @@
+/** @file
+Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
+compress algorithm.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+--*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "Decompress.h"
+
+//
+// Decompression algorithm begins here
+//
+#define BITBUFSIZ 32
+#define MAXMATCH 256
+#define THRESHOLD 3
+#define CODE_BIT 16
+#define BAD_TABLE - 1
+
+//
+// C: Char&Len Set; P: Position Set; T: exTra Set
+//
+#define NC (0xff + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9
+#define EFIPBIT 4
+#define MAXPBIT 5
+#define TBIT 5
+#define MAXNP ((1U << MAXPBIT) - 1)
+#define NT (CODE_BIT + 3)
+#if NT > MAXNP
+#define NPT NT
+#else
+#define NPT MAXNP
+#endif
+
+typedef struct {
+ UINT8 *mSrcBase; // Starting address of compressed data
+ UINT8 *mDstBase; // Starting address of decompressed data
+ UINT32 mOutBuf;
+ UINT32 mInBuf;
+
+ UINT16 mBitCount;
+ UINT32 mBitBuf;
+ UINT32 mSubBitBuf;
+ UINT16 mBlockSize;
+ UINT32 mCompSize;
+ UINT32 mOrigSize;
+
+ UINT16 mBadTableFlag;
+
+ UINT16 mLeft[2 * NC - 1];
+ UINT16 mRight[2 * NC - 1];
+ UINT8 mCLen[NC];
+ UINT8 mPTLen[NPT];
+ UINT16 mCTable[4096];
+ UINT16 mPTTable[256];
+} SCRATCH_DATA;
+
+STATIC UINT16 mPbit = EFIPBIT;
+
+STATIC
+VOID
+FillBuf (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfBits
+ )
+/*++
+
+Routine Description:
+
+ Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
+
+Arguments:
+
+ Sd - The global scratch data
+ NumOfBit - The number of bits to shift and read.
+
+Returns: (VOID)
+
+--*/
+{
+ Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
+
+ while (NumOfBits > Sd->mBitCount) {
+
+ Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
+
+ if (Sd->mCompSize > 0) {
+ //
+ // Get 1 byte into SubBitBuf
+ //
+ Sd->mCompSize--;
+ Sd->mSubBitBuf = 0;
+ Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
+ Sd->mBitCount = 8;
+
+ } else {
+ //
+ // No more bits from the source, just pad zero bit.
+ //
+ Sd->mSubBitBuf = 0;
+ Sd->mBitCount = 8;
+
+ }
+ }
+
+ Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
+ Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
+}
+
+STATIC
+UINT32
+GetBits (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfBits
+ )
+/*++
+
+Routine Description:
+
+ Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
+ NumOfBits of bits from source. Returns NumOfBits of bits that are
+ popped out.
+
+Arguments:
+
+ Sd - The global scratch data.
+ NumOfBits - The number of bits to pop and read.
+
+Returns:
+
+ The bits that are popped out.
+
+--*/
+{
+ UINT32 OutBits;
+
+ OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
+
+ FillBuf (Sd, NumOfBits);
+
+ return OutBits;
+}
+
+STATIC
+UINT16
+MakeTable (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfChar,
+ IN UINT8 *BitLen,
+ IN UINT16 TableBits,
+ OUT UINT16 *Table
+ )
+/*++
+
+Routine Description:
+
+ Creates Huffman Code mapping table according to code length array.
+
+Arguments:
+
+ Sd - The global scratch data
+ NumOfChar - Number of symbols in the symbol set
+ BitLen - Code length array
+ TableBits - The width of the mapping table
+ Table - The table
+
+Returns:
+
+ 0 - OK.
+ BAD_TABLE - The table is corrupted.
+
+--*/
+{
+ UINT16 Count[17];
+ UINT16 Weight[17];
+ UINT16 Start[18];
+ UINT16 *Pointer;
+ UINT16 Index3;
+ UINT16 Index;
+ UINT16 Len;
+ UINT16 Char;
+ UINT16 JuBits;
+ UINT16 Avail;
+ UINT16 NextCode;
+ UINT16 Mask;
+ UINT16 MaxTableLength;
+
+ for (Index = 1; Index <= 16; Index++) {
+ Count[Index] = 0;
+ }
+
+ for (Index = 0; Index < NumOfChar; Index++) {
+ if (BitLen[Index] > 16) {
+ return (UINT16) BAD_TABLE;
+ }
+ Count[BitLen[Index]]++;
+ }
+
+ Start[1] = 0;
+
+ for (Index = 1; Index <= 16; Index++) {
+ Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
+ }
+
+ if (Start[17] != 0) {
+ /*(1U << 16)*/
+ return (UINT16) BAD_TABLE;
+ }
+
+ JuBits = (UINT16) (16 - TableBits);
+
+ for (Index = 1; Index <= TableBits; Index++) {
+ Start[Index] >>= JuBits;
+ Weight[Index] = (UINT16) (1U << (TableBits - Index));
+ }
+
+ while (Index <= 16) {
+ Weight[Index] = (UINT16) (1U << (16 - Index));
+ Index++;
+ }
+
+ Index = (UINT16) (Start[TableBits + 1] >> JuBits);
+
+ if (Index != 0) {
+ Index3 = (UINT16) (1U << TableBits);
+ while (Index != Index3) {
+ Table[Index++] = 0;
+ }
+ }
+
+ Avail = NumOfChar;
+ Mask = (UINT16) (1U << (15 - TableBits));
+ MaxTableLength = (UINT16) (1U << TableBits);
+
+ for (Char = 0; Char < NumOfChar; Char++) {
+
+ Len = BitLen[Char];
+ if (Len == 0 || Len >= 17) {
+ continue;
+ }
+
+ NextCode = (UINT16) (Start[Len] + Weight[Len]);
+
+ if (Len <= TableBits) {
+
+ if (Start[Len] >= NextCode || NextCode > MaxTableLength){
+ return (UINT16) BAD_TABLE;
+ }
+
+ for (Index = Start[Len]; Index < NextCode; Index++) {
+ Table[Index] = Char;
+ }
+
+ } else {
+
+ Index3 = Start[Len];
+ Pointer = &Table[Index3 >> JuBits];
+ Index = (UINT16) (Len - TableBits);
+
+ while (Index != 0) {
+ if (*Pointer == 0) {
+ Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
+ *Pointer = Avail++;
+ }
+
+ if (Index3 & Mask) {
+ Pointer = &Sd->mRight[*Pointer];
+ } else {
+ Pointer = &Sd->mLeft[*Pointer];
+ }
+
+ Index3 <<= 1;
+ Index--;
+ }
+
+ *Pointer = Char;
+
+ }
+
+ Start[Len] = NextCode;
+ }
+ //
+ // Succeeds
+ //
+ return 0;
+}
+
+STATIC
+UINT32
+DecodeP (
+ IN SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Decodes a position value.
+
+Arguments:
+
+ Sd - the global scratch data
+
+Returns:
+
+ The position value decoded.
+
+--*/
+{
+ UINT16 Val;
+ UINT32 Mask;
+ UINT32 Pos;
+
+ Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
+
+ if (Val >= MAXNP) {
+ Mask = 1U << (BITBUFSIZ - 1 - 8);
+
+ do {
+
+ if (Sd->mBitBuf & Mask) {
+ Val = Sd->mRight[Val];
+ } else {
+ Val = Sd->mLeft[Val];
+ }
+
+ Mask >>= 1;
+ } while (Val >= MAXNP);
+ }
+ //
+ // Advance what we have read
+ //
+ FillBuf (Sd, Sd->mPTLen[Val]);
+
+ Pos = Val;
+ if (Val > 1) {
+ Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
+ }
+
+ return Pos;
+}
+
+STATIC
+UINT16
+ReadPTLen (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 nn,
+ IN UINT16 nbit,
+ IN UINT16 Special
+ )
+/*++
+
+Routine Description:
+
+ Reads code lengths for the Extra Set or the Position Set
+
+Arguments:
+
+ Sd - The global scratch data
+ nn - Number of symbols
+ nbit - Number of bits needed to represent nn
+ Special - The special symbol that needs to be taken care of
+
+Returns:
+
+ 0 - OK.
+ BAD_TABLE - Table is corrupted.
+
+--*/
+{
+ UINT16 Number;
+ UINT16 CharC;
+ UINT16 Index;
+ UINT32 Mask;
+
+ assert (nn <= NPT);
+
+ Number = (UINT16) GetBits (Sd, nbit);
+
+ if (Number == 0) {
+ CharC = (UINT16) GetBits (Sd, nbit);
+
+ for (Index = 0; Index < 256; Index++) {
+ Sd->mPTTable[Index] = CharC;
+ }
+
+ for (Index = 0; Index < nn; Index++) {
+ Sd->mPTLen[Index] = 0;
+ }
+
+ return 0;
+ }
+
+ Index = 0;
+
+ while (Index < Number && Index < NPT) {
+
+ CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
+
+ if (CharC == 7) {
+ Mask = 1U << (BITBUFSIZ - 1 - 3);
+ while (Mask & Sd->mBitBuf) {
+ Mask >>= 1;
+ CharC += 1;
+ }
+ }
+
+ FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
+
+ Sd->mPTLen[Index++] = (UINT8) CharC;
+
+ if (Index == Special) {
+ CharC = (UINT16) GetBits (Sd, 2);
+ CharC--;
+ while ((INT16) (CharC) >= 0 && Index < NPT) {
+ Sd->mPTLen[Index++] = 0;
+ CharC--;
+ }
+ }
+ }
+
+ while (Index < nn && Index < NPT) {
+ Sd->mPTLen[Index++] = 0;
+ }
+
+ return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
+}
+
+STATIC
+VOID
+ReadCLen (
+ SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Reads code lengths for Char&Len Set.
+
+Arguments:
+
+ Sd - the global scratch data
+
+Returns: (VOID)
+
+--*/
+{
+ UINT16 Number;
+ UINT16 CharC;
+ UINT16 Index;
+ UINT32 Mask;
+
+ Number = (UINT16) GetBits (Sd, CBIT);
+
+ if (Number == 0) {
+ CharC = (UINT16) GetBits (Sd, CBIT);
+
+ for (Index = 0; Index < NC; Index++) {
+ Sd->mCLen[Index] = 0;
+ }
+
+ for (Index = 0; Index < 4096; Index++) {
+ Sd->mCTable[Index] = CharC;
+ }
+
+ return ;
+ }
+
+ Index = 0;
+ while (Index < Number) {
+
+ CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
+ if (CharC >= NT) {
+ Mask = 1U << (BITBUFSIZ - 1 - 8);
+
+ do {
+
+ if (Mask & Sd->mBitBuf) {
+ CharC = Sd->mRight[CharC];
+ } else {
+ CharC = Sd->mLeft[CharC];
+ }
+
+ Mask >>= 1;
+
+ } while (CharC >= NT);
+ }
+ //
+ // Advance what we have read
+ //
+ FillBuf (Sd, Sd->mPTLen[CharC]);
+
+ if (CharC <= 2) {
+
+ if (CharC == 0) {
+ CharC = 1;
+ } else if (CharC == 1) {
+ CharC = (UINT16) (GetBits (Sd, 4) + 3);
+ } else if (CharC == 2) {
+ CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
+ }
+
+ CharC--;
+ while ((INT16) (CharC) >= 0) {
+ Sd->mCLen[Index++] = 0;
+ CharC--;
+ }
+
+ } else {
+
+ Sd->mCLen[Index++] = (UINT8) (CharC - 2);
+
+ }
+ }
+
+ while (Index < NC) {
+ Sd->mCLen[Index++] = 0;
+ }
+
+ MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
+
+ return ;
+}
+
+STATIC
+UINT16
+DecodeC (
+ SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Decode a character/length value.
+
+Arguments:
+
+ Sd - The global scratch data.
+
+Returns:
+
+ The value decoded.
+
+--*/
+{
+ UINT16 Index2;
+ UINT32 Mask;
+
+ if (Sd->mBlockSize == 0) {
+ //
+ // Starting a new block
+ //
+ Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
+ Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
+ if (Sd->mBadTableFlag != 0) {
+ return 0;
+ }
+
+ ReadCLen (Sd);
+
+ Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1));
+ if (Sd->mBadTableFlag != 0) {
+ return 0;
+ }
+ }
+
+ Sd->mBlockSize--;
+ Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
+
+ if (Index2 >= NC) {
+ Mask = 1U << (BITBUFSIZ - 1 - 12);
+
+ do {
+ if (Sd->mBitBuf & Mask) {
+ Index2 = Sd->mRight[Index2];
+ } else {
+ Index2 = Sd->mLeft[Index2];
+ }
+
+ Mask >>= 1;
+ } while (Index2 >= NC);
+ }
+ //
+ // Advance what we have read
+ //
+ FillBuf (Sd, Sd->mCLen[Index2]);
+
+ return Index2;
+}
+
+STATIC
+VOID
+Decode (
+ SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Decode the source data and put the resulting data into the destination buffer.
+
+Arguments:
+
+ Sd - The global scratch data
+
+Returns: (VOID)
+
+ --*/
+{
+ UINT16 BytesRemain;
+ UINT32 DataIdx;
+ UINT16 CharC;
+
+ BytesRemain = (UINT16) (-1);
+
+ DataIdx = 0;
+
+ for (;;) {
+ CharC = DecodeC (Sd);
+ if (Sd->mBadTableFlag != 0) {
+ return ;
+ }
+
+ if (CharC < 256) {
+ //
+ // Process an Original character
+ //
+ Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ return ;
+ }
+
+ } else {
+ //
+ // Process a Pointer
+ //
+ CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
+
+ BytesRemain = CharC;
+
+ DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
+
+ BytesRemain--;
+ while ((INT16) (BytesRemain) >= 0) {
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ return ;
+ }
+ if (DataIdx >= Sd->mOrigSize) {
+ Sd->mBadTableFlag = (UINT16) BAD_TABLE;
+ return ;
+ }
+ Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
+
+ BytesRemain--;
+ }
+ //
+ // Once mOutBuf is fully filled, directly return
+ //
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ return ;
+ }
+ }
+ }
+
+ return ;
+}
+
+EFI_STATUS
+GetInfo (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ )
+/*++
+
+Routine Description:
+
+ The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ DstSize - The size of destination buffer.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ UINT8 *Src;
+ UINT32 CompSize;
+
+ *ScratchSize = sizeof (SCRATCH_DATA);
+
+ Src = Source;
+ if (SrcSize < 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
+ *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+
+ if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Decompress (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ )
+/*++
+
+Routine Description:
+
+ The implementation Efi and Tiano Decompress().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ Destination - The destination buffer to store the decompressed data
+ DstSize - The size of destination buffer.
+ Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - Decompression is successful
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ UINT32 Index;
+ UINT32 CompSize;
+ UINT32 OrigSize;
+ EFI_STATUS Status;
+ SCRATCH_DATA *Sd;
+ UINT8 *Src;
+ UINT8 *Dst;
+
+ Status = EFI_SUCCESS;
+ Src = Source;
+ Dst = Destination;
+
+ if (ScratchSize < sizeof (SCRATCH_DATA)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Sd = (SCRATCH_DATA *) Scratch;
+
+ if (SrcSize < 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
+ OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+
+ if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DstSize != OrigSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Src = Src + 8;
+
+ for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
+ ((UINT8 *) Sd)[Index] = 0;
+ }
+
+ Sd->mSrcBase = Src;
+ Sd->mDstBase = Dst;
+ Sd->mCompSize = CompSize;
+ Sd->mOrigSize = OrigSize;
+
+ //
+ // Fill the first BITBUFSIZ bits
+ //
+ FillBuf (Sd, BITBUFSIZ);
+
+ //
+ // Decompress it
+ //
+ Decode (Sd);
+
+ if (Sd->mBadTableFlag != 0) {
+ //
+ // Something wrong with the source
+ //
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EfiGetInfo (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ )
+/*++
+
+Routine Description:
+
+ The implementation Efi Decompress GetInfo().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ DstSize - The size of destination buffer.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ return GetInfo (Source, SrcSize, DstSize, ScratchSize);
+}
+
+EFI_STATUS
+TianoGetInfo (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ )
+/*++
+
+Routine Description:
+
+ The implementation Tiano Decompress GetInfo().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ DstSize - The size of destination buffer.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ return GetInfo (Source, SrcSize, DstSize, ScratchSize);
+}
+
+EFI_STATUS
+EfiDecompress (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ )
+/*++
+
+Routine Description:
+
+ The implementation of Efi Decompress().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ Destination - The destination buffer to store the decompressed data
+ DstSize - The size of destination buffer.
+ Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - Decompression is successful
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ mPbit = EFIPBIT;
+ return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
+}
+
+EFI_STATUS
+TianoDecompress (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ )
+/*++
+
+Routine Description:
+
+ The implementation of Tiano Decompress().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ Destination - The destination buffer to store the decompressed data
+ DstSize - The size of destination buffer.
+ Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - Decompression is successful
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ mPbit = MAXPBIT;
+ return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);
+}
+
+EFI_STATUS
+Extract (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT VOID **Destination,
+ OUT UINT32 *DstSize,
+ IN UINTN Algorithm
+ )
+{
+ VOID *Scratch;
+ UINT32 ScratchSize;
+ EFI_STATUS Status;
+
+ Scratch = NULL;
+ Status = EFI_SUCCESS;
+
+ switch (Algorithm) {
+ case 0:
+ *Destination = (VOID *)malloc(SrcSize);
+ if (*Destination != NULL) {
+ memcpy(*Destination, Source, SrcSize);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ break;
+ case 1:
+ Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);
+ if (Status == EFI_SUCCESS) {
+ Scratch = (VOID *)malloc(ScratchSize);
+ if (Scratch == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Destination = (VOID *)malloc(*DstSize);
+ if (*Destination == NULL) {
+ free (Scratch);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
+ }
+ break;
+ case 2:
+ Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);
+ if (Status == EFI_SUCCESS) {
+ Scratch = (VOID *)malloc(ScratchSize);
+ if (Scratch == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Destination = (VOID *)malloc(*DstSize);
+ if (*Destination == NULL) {
+ free (Scratch);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
+ }
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ if (Scratch != NULL) {
+ free (Scratch);
+ }
+
+ return Status;
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.h
new file mode 100644
index 00000000..2df9a14b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Decompress.h
@@ -0,0 +1,159 @@
+/** @file
+Header file for compression routine
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_DECOMPRESS_H
+#define _EFI_DECOMPRESS_H
+
+#include <Common/UefiBaseTypes.h>
+
+EFI_STATUS
+EfiGetInfo (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ );
+/**
+
+Routine Description:
+
+ The implementation Efi Decompress GetInfo().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ DstSize - The size of destination buffer.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+**/
+
+EFI_STATUS
+EfiDecompress (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ );
+/**
+
+Routine Description:
+
+ The implementation of Efi Decompress().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ Destination - The destination buffer to store the decompressed data
+ DstSize - The size of destination buffer.
+ Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - Decompression is successful
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+**/
+
+EFI_STATUS
+TianoGetInfo (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ );
+/**
+
+Routine Description:
+
+ The implementation Tiano Decompress GetInfo().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ DstSize - The size of destination buffer.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+**/
+
+EFI_STATUS
+TianoDecompress (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ );
+/**
+
+Routine Description:
+
+ The implementation of Tiano Decompress().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ SrcSize - The size of source buffer
+ Destination - The destination buffer to store the decompressed data
+ DstSize - The size of destination buffer.
+ Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
+ ScratchSize - The size of scratch buffer.
+
+Returns:
+
+ EFI_SUCCESS - Decompression is successful
+ EFI_INVALID_PARAMETER - The source data is corrupted
+
+**/
+
+typedef
+EFI_STATUS
+(*GETINFO_FUNCTION) (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ );
+
+typedef
+EFI_STATUS
+(*DECOMPRESS_FUNCTION) (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ );
+
+EFI_STATUS
+Extract (
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT VOID **Destination,
+ OUT UINT32 *DstSize,
+ IN UINTN Algorithm
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiCompress.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiCompress.c
new file mode 100644
index 00000000..4cbd49b5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiCompress.c
@@ -0,0 +1,1591 @@
+/** @file
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman
+coding. LZ77 transforms the source data into a sequence of Original Characters
+and Pointers to repeated strings. This sequence is further divided into Blocks
+and Huffman codings are applied to each Block.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Compress.h"
+
+
+//
+// Macro Definitions
+//
+
+#undef UINT8_MAX
+typedef INT16 NODE;
+#define UINT8_MAX 0xff
+#define UINT8_BIT 8
+#define THRESHOLD 3
+#define INIT_CRC 0
+#define WNDBIT 13
+#define WNDSIZ (1U << WNDBIT)
+#define MAXMATCH 256
+#define PERC_FLAG 0x8000U
+#define CODE_BIT 16
+#define NIL 0
+#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
+#define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
+#define CRCPOLY 0xA001
+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
+
+//
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set
+//
+
+#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9
+#define NP (WNDBIT + 1)
+#define PBIT 4
+#define NT (CODE_BIT + 3)
+#define TBIT 5
+#if NT > NP
+ #define NPT NT
+#else
+ #define NPT NP
+#endif
+
+//
+// Function Prototypes
+//
+
+STATIC
+VOID
+PutDword(
+ IN UINT32 Data
+ );
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+ );
+
+STATIC
+VOID
+FreeMemory (
+ );
+
+STATIC
+VOID
+InitSlide (
+ );
+
+STATIC
+NODE
+Child (
+ IN NODE q,
+ IN UINT8 c
+ );
+
+STATIC
+VOID
+MakeChild (
+ IN NODE q,
+ IN UINT8 c,
+ IN NODE r
+ );
+
+STATIC
+VOID
+Split (
+ IN NODE Old
+ );
+
+STATIC
+VOID
+InsertNode (
+ );
+
+STATIC
+VOID
+DeleteNode (
+ );
+
+STATIC
+VOID
+GetNextMatch (
+ );
+
+STATIC
+EFI_STATUS
+Encode (
+ );
+
+STATIC
+VOID
+CountTFreq (
+ );
+
+STATIC
+VOID
+WritePTLen (
+ IN INT32 n,
+ IN INT32 nbit,
+ IN INT32 Special
+ );
+
+STATIC
+VOID
+WriteCLen (
+ );
+
+STATIC
+VOID
+EncodeC (
+ IN INT32 c
+ );
+
+STATIC
+VOID
+EncodeP (
+ IN UINT32 p
+ );
+
+STATIC
+VOID
+SendBlock (
+ );
+
+STATIC
+VOID
+Output (
+ IN UINT32 c,
+ IN UINT32 p
+ );
+
+STATIC
+VOID
+HufEncodeStart (
+ );
+
+STATIC
+VOID
+HufEncodeEnd (
+ );
+
+STATIC
+VOID
+MakeCrcTable (
+ );
+
+STATIC
+VOID
+PutBits (
+ IN INT32 n,
+ IN UINT32 x
+ );
+
+STATIC
+INT32
+FreadCrc (
+ OUT UINT8 *p,
+ IN INT32 n
+ );
+
+STATIC
+VOID
+InitPutBits (
+ );
+
+STATIC
+VOID
+CountLen (
+ IN INT32 i
+ );
+
+STATIC
+VOID
+MakeLen (
+ IN INT32 Root
+ );
+
+STATIC
+VOID
+DownHeap (
+ IN INT32 i
+ );
+
+STATIC
+VOID
+MakeCode (
+ IN INT32 n,
+ IN UINT8 Len[],
+ OUT UINT16 Code[]
+ );
+
+STATIC
+INT32
+MakeTree (
+ IN INT32 NParm,
+ IN UINT16 FreqParm[],
+ OUT UINT8 LenParm[],
+ OUT UINT16 CodeParm[]
+ );
+
+
+//
+// Global Variables
+//
+
+STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
+
+STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
+STATIC INT16 mHeap[NC + 1];
+STATIC INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
+STATIC UINT32 mCompSize, mOrigSize;
+
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1],
+ mCrcTable[UINT8_MAX + 1], mCFreq[2 * NC - 1],mCCode[NC],
+ mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
+
+STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
+
+
+//
+// functions
+//
+
+EFI_STATUS
+EfiCompress (
+ IN UINT8 *SrcBuffer,
+ IN UINT32 SrcSize,
+ IN UINT8 *DstBuffer,
+ IN OUT UINT32 *DstSize
+ )
+/*++
+
+Routine Description:
+
+ The main compression routine.
+
+Arguments:
+
+ SrcBuffer - The buffer storing the source data
+ SrcSize - The size of source data
+ DstBuffer - The buffer to store the compressed data
+ DstSize - On input, the size of DstBuffer; On output,
+ the size of the actual compressed data.
+
+Returns:
+
+ EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
+ DstSize contains the size needed.
+ EFI_SUCCESS - Compression is successful.
+
+--*/
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ //
+ // Initializations
+ //
+ mBufSiz = 0;
+ mBuf = NULL;
+ mText = NULL;
+ mLevel = NULL;
+ mChildCount = NULL;
+ mPosition = NULL;
+ mParent = NULL;
+ mPrev = NULL;
+ mNext = NULL;
+
+
+ mSrc = SrcBuffer;
+ mSrcUpperLimit = mSrc + SrcSize;
+ mDst = DstBuffer;
+ mDstUpperLimit = mDst + *DstSize;
+
+ PutDword(0L);
+ PutDword(0L);
+
+ MakeCrcTable ();
+
+ mOrigSize = mCompSize = 0;
+ mCrc = INIT_CRC;
+
+ //
+ // Compress it
+ //
+
+ Status = Encode();
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Null terminate the compressed data
+ //
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = 0;
+ }
+
+ //
+ // Fill in compressed size and original size
+ //
+ mDst = DstBuffer;
+ PutDword(mCompSize+1);
+ PutDword(mOrigSize);
+
+ //
+ // Return
+ //
+
+ if (mCompSize + 1 + 8 > *DstSize) {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_SUCCESS;
+ }
+
+}
+
+STATIC
+VOID
+PutDword(
+ IN UINT32 Data
+ )
+/*++
+
+Routine Description:
+
+ Put a dword to output stream
+
+Arguments:
+
+ Data - the dword to put
+
+Returns: (VOID)
+
+--*/
+{
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8)(((UINT8)(Data )) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8)(((UINT8)(Data >> 0x08)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8)(((UINT8)(Data >> 0x10)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8)(((UINT8)(Data >> 0x18)) & 0xff);
+ }
+}
+
+STATIC
+EFI_STATUS
+AllocateMemory ()
+/*++
+
+Routine Description:
+
+ Allocate memory spaces for data structures used in compression process
+
+Arguments: (VOID)
+
+Returns:
+
+ EFI_SUCCESS - Memory is allocated successfully
+ EFI_OUT_OF_RESOURCES - Allocation fails
+
+--*/
+{
+ UINT32 i;
+
+ mText = malloc (WNDSIZ * 2 + MAXMATCH);
+ if (mText == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ for (i = 0 ; i < WNDSIZ * 2 + MAXMATCH; i ++) {
+ mText[i] = 0;
+ }
+
+ mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
+ mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
+ mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
+ mParent = malloc (WNDSIZ * 2 * sizeof(*mParent));
+ mPrev = malloc (WNDSIZ * 2 * sizeof(*mPrev));
+ mNext = malloc ((MAX_HASH_VAL + 1) * sizeof(*mNext));
+ if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||
+ mParent == NULL || mPrev == NULL || mNext == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mBufSiz = 16 * 1024U;
+ while ((mBuf = malloc(mBufSiz)) == NULL) {
+ mBufSiz = (mBufSiz / 10U) * 9U;
+ if (mBufSiz < 4 * 1024U) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ mBuf[0] = 0;
+
+ return EFI_SUCCESS;
+}
+
+VOID
+FreeMemory ()
+/*++
+
+Routine Description:
+
+ Called when compression is completed to free memory previously allocated.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ if (mText) {
+ free (mText);
+ }
+
+ if (mLevel) {
+ free (mLevel);
+ }
+
+ if (mChildCount) {
+ free (mChildCount);
+ }
+
+ if (mPosition) {
+ free (mPosition);
+ }
+
+ if (mParent) {
+ free (mParent);
+ }
+
+ if (mPrev) {
+ free (mPrev);
+ }
+
+ if (mNext) {
+ free (mNext);
+ }
+
+ if (mBuf) {
+ free (mBuf);
+ }
+
+ return;
+}
+
+
+STATIC
+VOID
+InitSlide ()
+/*++
+
+Routine Description:
+
+ Initialize String Info Log data structures
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE i;
+
+ for (i = WNDSIZ; i <= WNDSIZ + UINT8_MAX; i++) {
+ mLevel[i] = 1;
+ mPosition[i] = NIL; /* sentinel */
+ }
+ for (i = WNDSIZ; i < WNDSIZ * 2; i++) {
+ mParent[i] = NIL;
+ }
+ mAvail = 1;
+ for (i = 1; i < WNDSIZ - 1; i++) {
+ mNext[i] = (NODE)(i + 1);
+ }
+
+ mNext[WNDSIZ - 1] = NIL;
+ for (i = WNDSIZ * 2; i <= MAX_HASH_VAL; i++) {
+ mNext[i] = NIL;
+ }
+}
+
+
+STATIC
+NODE
+Child (
+ IN NODE q,
+ IN UINT8 c
+ )
+/*++
+
+Routine Description:
+
+ Find child node given the parent node and the edge character
+
+Arguments:
+
+ q - the parent node
+ c - the edge character
+
+Returns:
+
+ The child node (NIL if not found)
+
+--*/
+{
+ NODE r;
+
+ r = mNext[HASH(q, c)];
+ mParent[NIL] = q; /* sentinel */
+ while (mParent[r] != q) {
+ r = mNext[r];
+ }
+
+ return r;
+}
+
+STATIC
+VOID
+MakeChild (
+ IN NODE q,
+ IN UINT8 c,
+ IN NODE r
+ )
+/*++
+
+Routine Description:
+
+ Create a new child for a given parent node.
+
+Arguments:
+
+ q - the parent node
+ c - the edge character
+ r - the child node
+
+Returns: (VOID)
+
+--*/
+{
+ NODE h, t;
+
+ h = (NODE)HASH(q, c);
+ t = mNext[h];
+ mNext[h] = r;
+ mNext[r] = t;
+ mPrev[t] = r;
+ mPrev[r] = h;
+ mParent[r] = q;
+ mChildCount[q]++;
+}
+
+STATIC
+VOID
+Split (
+ NODE Old
+ )
+/*++
+
+Routine Description:
+
+ Split a node.
+
+Arguments:
+
+ Old - the node to split
+
+Returns: (VOID)
+
+--*/
+{
+ NODE New, t;
+
+ New = mAvail;
+ mAvail = mNext[New];
+ mChildCount[New] = 0;
+ t = mPrev[Old];
+ mPrev[New] = t;
+ mNext[t] = New;
+ t = mNext[Old];
+ mNext[New] = t;
+ mPrev[t] = New;
+ mParent[New] = mParent[Old];
+ mLevel[New] = (UINT8)mMatchLen;
+ mPosition[New] = mPos;
+ MakeChild(New, mText[mMatchPos + mMatchLen], Old);
+ MakeChild(New, mText[mPos + mMatchLen], mPos);
+}
+
+STATIC
+VOID
+InsertNode ()
+/*++
+
+Routine Description:
+
+ Insert string info for current position into the String Info Log
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE q, r, j, t;
+ UINT8 c, *t1, *t2;
+
+ if (mMatchLen >= 4) {
+
+ //
+ // We have just got a long match, the target tree
+ // can be located by MatchPos + 1. Traverse the tree
+ // from bottom up to get to a proper starting point.
+ // The usage of PERC_FLAG ensures proper node deletion
+ // in DeleteNode() later.
+ //
+
+ mMatchLen--;
+ r = (INT16)((mMatchPos + 1) | WNDSIZ);
+ while ((q = mParent[r]) == NIL) {
+ r = mNext[r];
+ }
+ while (mLevel[q] >= mMatchLen) {
+ r = q; q = mParent[q];
+ }
+ t = q;
+ while (mPosition[t] < 0) {
+ mPosition[t] = mPos;
+ t = mParent[t];
+ }
+ if (t < WNDSIZ) {
+ mPosition[t] = (NODE)(mPos | PERC_FLAG);
+ }
+ } else {
+
+ //
+ // Locate the target tree
+ //
+
+ q = (INT16)(mText[mPos] + WNDSIZ);
+ c = mText[mPos + 1];
+ if ((r = Child(q, c)) == NIL) {
+ MakeChild(q, c, mPos);
+ mMatchLen = 1;
+ return;
+ }
+ mMatchLen = 2;
+ }
+
+ //
+ // Traverse down the tree to find a match.
+ // Update Position value along the route.
+ // Node split or creation is involved.
+ //
+
+ for ( ; ; ) {
+ if (r >= WNDSIZ) {
+ j = MAXMATCH;
+ mMatchPos = r;
+ } else {
+ j = mLevel[r];
+ mMatchPos = (NODE)(mPosition[r] & ~PERC_FLAG);
+ }
+ if (mMatchPos >= mPos) {
+ mMatchPos -= WNDSIZ;
+ }
+ t1 = &mText[mPos + mMatchLen];
+ t2 = &mText[mMatchPos + mMatchLen];
+ while (mMatchLen < j) {
+ if (*t1 != *t2) {
+ Split(r);
+ return;
+ }
+ mMatchLen++;
+ t1++;
+ t2++;
+ }
+ if (mMatchLen >= MAXMATCH) {
+ break;
+ }
+ mPosition[r] = mPos;
+ q = r;
+ if ((r = Child(q, *t1)) == NIL) {
+ MakeChild(q, *t1, mPos);
+ return;
+ }
+ mMatchLen++;
+ }
+ t = mPrev[r];
+ mPrev[mPos] = t;
+ mNext[t] = mPos;
+ t = mNext[r];
+ mNext[mPos] = t;
+ mPrev[t] = mPos;
+ mParent[mPos] = q;
+ mParent[r] = NIL;
+
+ //
+ // Special usage of 'next'
+ //
+ mNext[r] = mPos;
+
+}
+
+STATIC
+VOID
+DeleteNode ()
+/*++
+
+Routine Description:
+
+ Delete outdated string info. (The Usage of PERC_FLAG
+ ensures a clean deletion)
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE q, r, s, t, u;
+
+ if (mParent[mPos] == NIL) {
+ return;
+ }
+
+ r = mPrev[mPos];
+ s = mNext[mPos];
+ mNext[r] = s;
+ mPrev[s] = r;
+ r = mParent[mPos];
+ mParent[mPos] = NIL;
+ if (r >= WNDSIZ || --mChildCount[r] > 1) {
+ return;
+ }
+ t = (NODE)(mPosition[r] & ~PERC_FLAG);
+ if (t >= mPos) {
+ t -= WNDSIZ;
+ }
+ s = t;
+ q = mParent[r];
+ while ((u = mPosition[q]) & PERC_FLAG) {
+ u &= ~PERC_FLAG;
+ if (u >= mPos) {
+ u -= WNDSIZ;
+ }
+ if (u > s) {
+ s = u;
+ }
+ mPosition[q] = (INT16)(s | WNDSIZ);
+ q = mParent[q];
+ }
+ if (q < WNDSIZ) {
+ if (u >= mPos) {
+ u -= WNDSIZ;
+ }
+ if (u > s) {
+ s = u;
+ }
+ mPosition[q] = (INT16)(s | WNDSIZ | PERC_FLAG);
+ }
+ s = Child(r, mText[t + mLevel[r]]);
+ t = mPrev[s];
+ u = mNext[s];
+ mNext[t] = u;
+ mPrev[u] = t;
+ t = mPrev[r];
+ mNext[t] = s;
+ mPrev[s] = t;
+ t = mNext[r];
+ mPrev[t] = s;
+ mNext[s] = t;
+ mParent[s] = mParent[r];
+ mParent[r] = NIL;
+ mNext[r] = mAvail;
+ mAvail = r;
+}
+
+STATIC
+VOID
+GetNextMatch ()
+/*++
+
+Routine Description:
+
+ Advance the current position (read in new data if needed).
+ Delete outdated string info. Find a match string for current position.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 n;
+
+ mRemainder--;
+ if (++mPos == WNDSIZ * 2) {
+ memmove(&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);
+ n = FreadCrc(&mText[WNDSIZ + MAXMATCH], WNDSIZ);
+ mRemainder += n;
+ mPos = WNDSIZ;
+ }
+ DeleteNode();
+ InsertNode();
+}
+
+STATIC
+EFI_STATUS
+Encode ()
+/*++
+
+Routine Description:
+
+ The main controlling routine for compression process.
+
+Arguments: (VOID)
+
+Returns:
+
+ EFI_SUCCESS - The compression is successful
+ EFI_OUT_0F_RESOURCES - Not enough memory for compression process
+
+--*/
+{
+ EFI_STATUS Status;
+ INT32 LastMatchLen;
+ NODE LastMatchPos;
+
+ Status = AllocateMemory();
+ if (EFI_ERROR(Status)) {
+ FreeMemory();
+ return Status;
+ }
+
+ InitSlide();
+
+ HufEncodeStart();
+
+ mRemainder = FreadCrc(&mText[WNDSIZ], WNDSIZ + MAXMATCH);
+
+ mMatchLen = 0;
+ mPos = WNDSIZ;
+ InsertNode();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+ while (mRemainder > 0) {
+ LastMatchLen = mMatchLen;
+ LastMatchPos = mMatchPos;
+ GetNextMatch();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
+
+ //
+ // Not enough benefits are gained by outputting a pointer,
+ // so just output the original character
+ //
+
+ Output(mText[mPos - 1], 0);
+ } else {
+
+ //
+ // Outputting a pointer is beneficial enough, do it.
+ //
+
+ Output(LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
+ (mPos - LastMatchPos - 2) & (WNDSIZ - 1));
+ while (--LastMatchLen > 0) {
+ GetNextMatch();
+ }
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+ }
+ }
+
+ HufEncodeEnd();
+ FreeMemory();
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+CountTFreq ()
+/*++
+
+Routine Description:
+
+ Count the frequencies for the Extra Set
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 i, k, n, Count;
+
+ for (i = 0; i < NT; i++) {
+ mTFreq[i] = 0;
+ }
+ n = NC;
+ while (n > 0 && mCLen[n - 1] == 0) {
+ n--;
+ }
+ i = 0;
+ while (i < n) {
+ k = mCLen[i++];
+ if (k == 0) {
+ Count = 1;
+ while (i < n && mCLen[i] == 0) {
+ i++;
+ Count++;
+ }
+ if (Count <= 2) {
+ mTFreq[0] = (UINT16)(mTFreq[0] + Count);
+ } else if (Count <= 18) {
+ mTFreq[1]++;
+ } else if (Count == 19) {
+ mTFreq[0]++;
+ mTFreq[1]++;
+ } else {
+ mTFreq[2]++;
+ }
+ } else {
+ mTFreq[k + 2]++;
+ }
+ }
+}
+
+STATIC
+VOID
+WritePTLen (
+ IN INT32 n,
+ IN INT32 nbit,
+ IN INT32 Special
+ )
+/*++
+
+Routine Description:
+
+ Outputs the code length array for the Extra Set or the Position Set.
+
+Arguments:
+
+ n - the number of symbols
+ nbit - the number of bits needed to represent 'n'
+ Special - the special symbol that needs to be take care of
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 i, k;
+
+ while (n > 0 && mPTLen[n - 1] == 0) {
+ n--;
+ }
+ PutBits(nbit, n);
+ i = 0;
+ while (i < n) {
+ k = mPTLen[i++];
+ if (k <= 6) {
+ PutBits(3, k);
+ } else {
+ PutBits(k - 3, (1U << (k - 3)) - 2);
+ }
+ if (i == Special) {
+ while (i < 6 && mPTLen[i] == 0) {
+ i++;
+ }
+ PutBits(2, (i - 3) & 3);
+ }
+ }
+}
+
+STATIC
+VOID
+WriteCLen ()
+/*++
+
+Routine Description:
+
+ Outputs the code length array for Char&Length Set
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 i, k, n, Count;
+
+ n = NC;
+ while (n > 0 && mCLen[n - 1] == 0) {
+ n--;
+ }
+ PutBits(CBIT, n);
+ i = 0;
+ while (i < n) {
+ k = mCLen[i++];
+ if (k == 0) {
+ Count = 1;
+ while (i < n && mCLen[i] == 0) {
+ i++;
+ Count++;
+ }
+ if (Count <= 2) {
+ for (k = 0; k < Count; k++) {
+ PutBits(mPTLen[0], mPTCode[0]);
+ }
+ } else if (Count <= 18) {
+ PutBits(mPTLen[1], mPTCode[1]);
+ PutBits(4, Count - 3);
+ } else if (Count == 19) {
+ PutBits(mPTLen[0], mPTCode[0]);
+ PutBits(mPTLen[1], mPTCode[1]);
+ PutBits(4, 15);
+ } else {
+ PutBits(mPTLen[2], mPTCode[2]);
+ PutBits(CBIT, Count - 20);
+ }
+ } else {
+ PutBits(mPTLen[k + 2], mPTCode[k + 2]);
+ }
+ }
+}
+
+STATIC
+VOID
+EncodeC (
+ IN INT32 c
+ )
+{
+ PutBits(mCLen[c], mCCode[c]);
+}
+
+STATIC
+VOID
+EncodeP (
+ IN UINT32 p
+ )
+{
+ UINT32 c, q;
+
+ c = 0;
+ q = p;
+ while (q) {
+ q >>= 1;
+ c++;
+ }
+ PutBits(mPTLen[c], mPTCode[c]);
+ if (c > 1) {
+ PutBits(c - 1, p & (0xFFFFU >> (17 - c)));
+ }
+}
+
+STATIC
+VOID
+SendBlock ()
+/*++
+
+Routine Description:
+
+ Huffman code the block and output it.
+
+Argument: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ UINT32 i, k, Flags, Root, Pos, Size;
+ Flags = 0;
+
+ Root = MakeTree(NC, mCFreq, mCLen, mCCode);
+ Size = mCFreq[Root];
+ PutBits(16, Size);
+ if (Root >= NC) {
+ CountTFreq();
+ Root = MakeTree(NT, mTFreq, mPTLen, mPTCode);
+ if (Root >= NT) {
+ WritePTLen(NT, TBIT, 3);
+ } else {
+ PutBits(TBIT, 0);
+ PutBits(TBIT, Root);
+ }
+ WriteCLen();
+ } else {
+ PutBits(TBIT, 0);
+ PutBits(TBIT, 0);
+ PutBits(CBIT, 0);
+ PutBits(CBIT, Root);
+ }
+ Root = MakeTree(NP, mPFreq, mPTLen, mPTCode);
+ if (Root >= NP) {
+ WritePTLen(NP, PBIT, -1);
+ } else {
+ PutBits(PBIT, 0);
+ PutBits(PBIT, Root);
+ }
+ Pos = 0;
+ for (i = 0; i < Size; i++) {
+ if (i % UINT8_BIT == 0) {
+ Flags = mBuf[Pos++];
+ } else {
+ Flags <<= 1;
+ }
+ if (Flags & (1U << (UINT8_BIT - 1))) {
+ EncodeC(mBuf[Pos++] + (1U << UINT8_BIT));
+ k = mBuf[Pos++] << UINT8_BIT;
+ k += mBuf[Pos++];
+ EncodeP(k);
+ } else {
+ EncodeC(mBuf[Pos++]);
+ }
+ }
+ for (i = 0; i < NC; i++) {
+ mCFreq[i] = 0;
+ }
+ for (i = 0; i < NP; i++) {
+ mPFreq[i] = 0;
+ }
+}
+
+
+STATIC
+VOID
+Output (
+ IN UINT32 c,
+ IN UINT32 p
+ )
+/*++
+
+Routine Description:
+
+ Outputs an Original Character or a Pointer
+
+Arguments:
+
+ c - The original character or the 'String Length' element of a Pointer
+ p - The 'Position' field of a Pointer
+
+Returns: (VOID)
+
+--*/
+{
+ STATIC UINT32 CPos;
+
+ if ((mOutputMask >>= 1) == 0) {
+ mOutputMask = 1U << (UINT8_BIT - 1);
+ if (mOutputPos >= mBufSiz - 3 * UINT8_BIT) {
+ SendBlock();
+ mOutputPos = 0;
+ }
+ CPos = mOutputPos++;
+ mBuf[CPos] = 0;
+ }
+ mBuf[mOutputPos++] = (UINT8) c;
+ mCFreq[c]++;
+ if (c >= (1U << UINT8_BIT)) {
+ mBuf[CPos] |= mOutputMask;
+ mBuf[mOutputPos++] = (UINT8)(p >> UINT8_BIT);
+ mBuf[mOutputPos++] = (UINT8) p;
+ c = 0;
+ while (p) {
+ p >>= 1;
+ c++;
+ }
+ mPFreq[c]++;
+ }
+}
+
+STATIC
+VOID
+HufEncodeStart ()
+{
+ INT32 i;
+
+ for (i = 0; i < NC; i++) {
+ mCFreq[i] = 0;
+ }
+ for (i = 0; i < NP; i++) {
+ mPFreq[i] = 0;
+ }
+ mOutputPos = mOutputMask = 0;
+ InitPutBits();
+ return;
+}
+
+STATIC
+VOID
+HufEncodeEnd ()
+{
+ SendBlock();
+
+ //
+ // Flush remaining bits
+ //
+ PutBits(UINT8_BIT - 1, 0);
+
+ return;
+}
+
+
+STATIC
+VOID
+MakeCrcTable ()
+{
+ UINT32 i, j, r;
+
+ for (i = 0; i <= UINT8_MAX; i++) {
+ r = i;
+ for (j = 0; j < UINT8_BIT; j++) {
+ if (r & 1) {
+ r = (r >> 1) ^ CRCPOLY;
+ } else {
+ r >>= 1;
+ }
+ }
+ mCrcTable[i] = (UINT16)r;
+ }
+}
+
+STATIC
+VOID
+PutBits (
+ IN INT32 n,
+ IN UINT32 x
+ )
+/*++
+
+Routine Description:
+
+ Outputs rightmost n bits of x
+
+Arguments:
+
+ n - the rightmost n bits of the data is used
+ x - the data
+
+Returns: (VOID)
+
+--*/
+{
+ UINT8 Temp;
+
+ if (n < mBitCount) {
+ mSubBitBuf |= x << (mBitCount -= n);
+ } else {
+
+ Temp = (UINT8)(mSubBitBuf | (x >> (n -= mBitCount)));
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = Temp;
+ }
+ mCompSize++;
+
+ if (n < UINT8_BIT) {
+ mSubBitBuf = x << (mBitCount = UINT8_BIT - n);
+ } else {
+
+ Temp = (UINT8)(x >> (n - UINT8_BIT));
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = Temp;
+ }
+ mCompSize++;
+
+ mSubBitBuf = x << (mBitCount = 2 * UINT8_BIT - n);
+ }
+ }
+}
+
+STATIC
+INT32
+FreadCrc (
+ OUT UINT8 *p,
+ IN INT32 n
+ )
+/*++
+
+Routine Description:
+
+ Read in source data
+
+Arguments:
+
+ p - the buffer to hold the data
+ n - number of bytes to read
+
+Returns:
+
+ number of bytes actually read
+
+--*/
+{
+ INT32 i;
+
+ for (i = 0; mSrc < mSrcUpperLimit && i < n; i++) {
+ *p++ = *mSrc++;
+ }
+ n = i;
+
+ p -= n;
+ mOrigSize += n;
+ while (--i >= 0) {
+ UPDATE_CRC(*p++);
+ }
+ return n;
+}
+
+
+STATIC
+VOID
+InitPutBits ()
+{
+ mBitCount = UINT8_BIT;
+ mSubBitBuf = 0;
+}
+
+STATIC
+VOID
+CountLen (
+ IN INT32 i
+ )
+/*++
+
+Routine Description:
+
+ Count the number of each code length for a Huffman tree.
+
+Arguments:
+
+ i - the top node
+
+Returns: (VOID)
+
+--*/
+{
+ STATIC INT32 Depth = 0;
+
+ if (i < mN) {
+ mLenCnt[(Depth < 16) ? Depth : 16]++;
+ } else {
+ Depth++;
+ CountLen(mLeft [i]);
+ CountLen(mRight[i]);
+ Depth--;
+ }
+}
+
+STATIC
+VOID
+MakeLen (
+ IN INT32 Root
+ )
+/*++
+
+Routine Description:
+
+ Create code length array for a Huffman tree
+
+Arguments:
+
+ Root - the root of the tree
+
+--*/
+{
+ INT32 i, k;
+ UINT32 Cum;
+
+ for (i = 0; i <= 16; i++) {
+ mLenCnt[i] = 0;
+ }
+ CountLen(Root);
+
+ //
+ // Adjust the length count array so that
+ // no code will be generated longer than its designated length
+ //
+
+ Cum = 0;
+ for (i = 16; i > 0; i--) {
+ Cum += mLenCnt[i] << (16 - i);
+ }
+ while (Cum != (1U << 16)) {
+ mLenCnt[16]--;
+ for (i = 15; i > 0; i--) {
+ if (mLenCnt[i] != 0) {
+ mLenCnt[i]--;
+ mLenCnt[i+1] += 2;
+ break;
+ }
+ }
+ Cum--;
+ }
+ for (i = 16; i > 0; i--) {
+ k = mLenCnt[i];
+ while (--k >= 0) {
+ mLen[*mSortPtr++] = (UINT8)i;
+ }
+ }
+}
+
+STATIC
+VOID
+DownHeap (
+ IN INT32 i
+ )
+{
+ INT32 j, k;
+
+ //
+ // priority queue: send i-th entry down heap
+ //
+
+ k = mHeap[i];
+ while ((j = 2 * i) <= mHeapSize) {
+ if (j < mHeapSize && mFreq[mHeap[j]] > mFreq[mHeap[j + 1]]) {
+ j++;
+ }
+ if (mFreq[k] <= mFreq[mHeap[j]]) {
+ break;
+ }
+ mHeap[i] = mHeap[j];
+ i = j;
+ }
+ mHeap[i] = (INT16)k;
+}
+
+STATIC
+VOID
+MakeCode (
+ IN INT32 n,
+ IN UINT8 Len[],
+ OUT UINT16 Code[]
+ )
+/*++
+
+Routine Description:
+
+ Assign code to each symbol based on the code length array
+
+Arguments:
+
+ n - number of symbols
+ Len - the code length array
+ Code - stores codes for each symbol
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 i;
+ UINT16 Start[18];
+
+ Start[1] = 0;
+ for (i = 1; i <= 16; i++) {
+ Start[i + 1] = (UINT16)((Start[i] + mLenCnt[i]) << 1);
+ }
+ for (i = 0; i < n; i++) {
+ Code[i] = Start[Len[i]]++;
+ }
+}
+
+STATIC
+INT32
+MakeTree (
+ IN INT32 NParm,
+ IN UINT16 FreqParm[],
+ OUT UINT8 LenParm[],
+ OUT UINT16 CodeParm[]
+ )
+/*++
+
+Routine Description:
+
+ Generates Huffman codes given a frequency distribution of symbols
+
+Arguments:
+
+ NParm - number of symbols
+ FreqParm - frequency of each symbol
+ LenParm - code length for each symbol
+ CodeParm - code for each symbol
+
+Returns:
+
+ Root of the Huffman tree.
+
+--*/
+{
+ INT32 i, j, k, Avail;
+
+ //
+ // make tree, calculate len[], return root
+ //
+
+ mN = NParm;
+ mFreq = FreqParm;
+ mLen = LenParm;
+ Avail = mN;
+ mHeapSize = 0;
+ mHeap[1] = 0;
+ for (i = 0; i < mN; i++) {
+ mLen[i] = 0;
+ if (mFreq[i]) {
+ mHeap[++mHeapSize] = (INT16)i;
+ }
+ }
+ if (mHeapSize < 2) {
+ CodeParm[mHeap[1]] = 0;
+ return mHeap[1];
+ }
+ for (i = mHeapSize / 2; i >= 1; i--) {
+
+ //
+ // make priority queue
+ //
+ DownHeap(i);
+ }
+ mSortPtr = CodeParm;
+ do {
+ i = mHeap[1];
+ if (i < mN) {
+ *mSortPtr++ = (UINT16)i;
+ }
+ mHeap[1] = mHeap[mHeapSize--];
+ DownHeap(1);
+ j = mHeap[1];
+ if (j < mN) {
+ *mSortPtr++ = (UINT16)j;
+ }
+ k = Avail++;
+ mFreq[k] = (UINT16)(mFreq[i] + mFreq[j]);
+ mHeap[1] = (INT16)k;
+ DownHeap(1);
+ mLeft[k] = (UINT16)i;
+ mRight[k] = (UINT16)j;
+ } while (mHeapSize > 1);
+
+ mSortPtr = CodeParm;
+ MakeLen(k);
+ MakeCode(NParm, LenParm, CodeParm);
+
+ //
+ // return root
+ //
+ return k;
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.c
new file mode 100644
index 00000000..69b9f899
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.c
@@ -0,0 +1,902 @@
+/** @file
+EFI tools utility functions to display warning, error, and informational messages
+
+Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+--*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <time.h>
+
+#include "EfiUtilityMsgs.h"
+
+//
+// Declare module globals for keeping track of the utility's
+// name and other settings.
+//
+STATIC STATUS mStatus = STATUS_SUCCESS;
+STATIC CHAR8 mUtilityName[50] = { 0 };
+STATIC UINT64 mPrintLogLevel = INFO_LOG_LEVEL;
+STATIC CHAR8 *mSourceFileName = NULL;
+STATIC UINT32 mSourceFileLineNum = 0;
+STATIC UINT32 mErrorCount = 0;
+STATIC UINT32 mWarningCount = 0;
+STATIC UINT32 mMaxErrors = 0;
+STATIC UINT32 mMaxWarnings = 0;
+STATIC UINT32 mMaxWarningsPlusErrors = 0;
+STATIC INT8 mPrintLimitsSet = 0;
+
+STATIC
+VOID
+PrintLimitExceeded (
+ VOID
+ );
+
+VOID
+Error (
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT32 MessageCode,
+ CHAR8 *Text,
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Prints an error message.
+
+Arguments:
+ All arguments are optional, though the printed message may be useless if
+ at least something valid is not specified.
+
+ FileName - name of the file or application. If not specified, then the
+ utility name (as set by the utility calling SetUtilityName()
+ earlier) is used. Otherwise "Unknown utility" is used.
+
+ LineNumber - the line number of error, typically used by parsers. If the
+ utility is not a parser, then 0 should be specified. Otherwise
+ the FileName and LineNumber info can be used to cause
+ MS Visual Studio to jump to the error.
+
+ MessageCode - an application-specific error code that can be referenced in
+ other documentation.
+
+ Text - the text in question, typically used by parsers.
+
+ MsgFmt - the format string for the error message. Can contain formatting
+ controls for use with the varargs.
+
+Returns:
+ None.
+
+Notes:
+ We print the following (similar to the Warn() and Debug()
+ W
+ Typical error/warning message format:
+
+ bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters
+
+ BUGBUG -- these three utility functions are almost identical, and
+ should be modified to share code.
+
+ Visual Studio does not find error messages with:
+
+ " error :"
+ " error 1:"
+ " error c1:"
+ " error 1000:"
+ " error c100:"
+
+ It does find:
+ " error c1000:"
+--*/
+{
+ va_list List;
+ //
+ // If limits have been set, then check that we have not exceeded them
+ //
+ if (mPrintLimitsSet) {
+ //
+ // See if we've exceeded our total count
+ //
+ if (mMaxWarningsPlusErrors != 0) {
+ if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ //
+ // See if we've exceeded our error count
+ //
+ if (mMaxErrors != 0) {
+ if (mErrorCount > mMaxErrors) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ }
+
+ mErrorCount++;
+ va_start (List, MsgFmt);
+ PrintMessage ("ERROR", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+ParserError (
+ UINT32 MessageCode,
+ CHAR8 *Text,
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a parser error, using the source file name and line number
+ set by a previous call to SetParserPosition().
+
+Arguments:
+ MessageCode - application-specific error code
+ Text - text to print in the error message
+ MsgFmt - format string to print at the end of the error message
+
+Returns:
+ NA
+
+--*/
+{
+ va_list List;
+ //
+ // If limits have been set, then check them
+ //
+ if (mPrintLimitsSet) {
+ //
+ // See if we've exceeded our total count
+ //
+ if (mMaxWarningsPlusErrors != 0) {
+ if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ //
+ // See if we've exceeded our error count
+ //
+ if (mMaxErrors != 0) {
+ if (mErrorCount > mMaxErrors) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ }
+
+ mErrorCount++;
+ va_start (List, MsgFmt);
+ PrintMessage ("ERROR", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+ParserWarning (
+ UINT32 ErrorCode,
+ CHAR8 *OffendingText,
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a parser warning, using the source file name and line number
+ set by a previous call to SetParserPosition().
+
+Arguments:
+ ErrorCode - application-specific error code
+ OffendingText - text to print in the warning message
+ MsgFmt - format string to print at the end of the warning message
+
+Returns:
+ NA
+
+--*/
+{
+ va_list List;
+ //
+ // If limits have been set, then check them
+ //
+ if (mPrintLimitsSet) {
+ //
+ // See if we've exceeded our total count
+ //
+ if (mMaxWarningsPlusErrors != 0) {
+ if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ //
+ // See if we've exceeded our warning count
+ //
+ if (mMaxWarnings != 0) {
+ if (mWarningCount > mMaxWarnings) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ }
+
+ mWarningCount++;
+ va_start (List, MsgFmt);
+ PrintMessage ("WARNING", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);
+ va_end (List);
+ //
+ // Don't set warning status accordingly
+ //
+ // if (mStatus < STATUS_WARNING) {
+ // mStatus = STATUS_WARNING;
+ // }
+}
+
+VOID
+Warning (
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT32 MessageCode,
+ CHAR8 *Text,
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a warning message.
+
+Arguments:
+ FileName - name of the file where the warning was detected, or the name
+ of the application that detected the warning
+
+ LineNumber - the line number where the warning was detected (parsers).
+ 0 should be specified if the utility is not a parser.
+
+ MessageCode - an application-specific warning code that can be referenced in
+ other documentation.
+
+ Text - the text in question (parsers)
+
+ MsgFmt - the format string for the warning message. Can contain formatting
+ controls for use with varargs.
+
+Returns:
+ None.
+
+--*/
+{
+ va_list List;
+
+ //
+ // Current Print Level not output warning information.
+ //
+ if (WARNING_LOG_LEVEL < mPrintLogLevel) {
+ return;
+ }
+ //
+ // If limits have been set, then check them
+ //
+ if (mPrintLimitsSet) {
+ //
+ // See if we've exceeded our total count
+ //
+ if (mMaxWarningsPlusErrors != 0) {
+ if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ //
+ // See if we've exceeded our warning count
+ //
+ if (mMaxWarnings != 0) {
+ if (mWarningCount > mMaxWarnings) {
+ PrintLimitExceeded ();
+ return ;
+ }
+ }
+ }
+
+ mWarningCount++;
+ va_start (List, MsgFmt);
+ PrintMessage ("WARNING", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+DebugMsg (
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT64 MsgLevel,
+ CHAR8 *Text,
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a Debug message.
+
+Arguments:
+ FileName - typically the name of the utility printing the debug message, but
+ can be the name of a file being parsed.
+
+ LineNumber - the line number in FileName (parsers)
+
+ MsgLevel - Debug message print level (0~9)
+
+ Text - the text in question (parsers)
+
+ MsgFmt - the format string for the debug message. Can contain formatting
+ controls for use with varargs.
+
+Returns:
+ None.
+
+--*/
+{
+ va_list List;
+ //
+ // If the debug level is less than current print level, then do nothing.
+ //
+ if (MsgLevel < mPrintLogLevel) {
+ return ;
+ }
+
+ va_start (List, MsgFmt);
+ PrintMessage ("DEBUG", FileName, LineNumber, 0, Text, MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+PrintMessage (
+ CHAR8 *Type,
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT32 MessageCode,
+ CHAR8 *Text,
+ CHAR8 *MsgFmt,
+ va_list List
+ )
+/*++
+
+Routine Description:
+ Worker routine for all the utility printing services. Prints the message in
+ a format that Visual Studio will find when scanning build outputs for
+ errors or warnings.
+
+Arguments:
+ Type - "warning" or "error" string to insert into the message to be
+ printed. The first character of this string (converted to uppercase)
+ is used to precede the MessageCode value in the output string.
+
+ FileName - name of the file where the warning was detected, or the name
+ of the application that detected the warning
+
+ LineNumber - the line number where the warning was detected (parsers).
+ 0 should be specified if the utility is not a parser.
+
+ MessageCode - an application-specific warning code that can be referenced in
+ other documentation.
+
+ Text - part of the message to print
+
+ MsgFmt - the format string for the message. Can contain formatting
+ controls for use with varargs.
+ List - the variable list.
+
+Returns:
+ None.
+
+Notes:
+ If FileName == NULL then this utility will use the string passed into SetUtilityName().
+
+ LineNumber is only used if the caller is a parser, in which case FileName refers to the
+ file being parsed.
+
+ Text and MsgFmt are both optional, though it would be of little use calling this function with
+ them both NULL.
+
+ Output will typically be of the form:
+ <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>
+
+ Parser (LineNumber != 0)
+ VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters
+ Generic utility (LineNumber == 0)
+ UtilityName : error E1234 : Text string : MsgFmt string and args
+
+--*/
+{
+ CHAR8 Line[MAX_LINE_LEN];
+ CHAR8 Line2[MAX_LINE_LEN];
+ CHAR8 *Cptr;
+ struct tm *NewTime;
+ time_t CurrentTime;
+
+ //
+ // init local variable
+ //
+ Line[0] = '\0';
+ Line2[0] = '\0';
+
+ //
+ // If given a filename, then add it (and the line number) to the string.
+ // If there's no filename, then use the program name if provided.
+ //
+ if (FileName != NULL) {
+ Cptr = FileName;
+ } else {
+ Cptr = NULL;
+ }
+
+ if (strcmp (Type, "DEBUG") == 0) {
+ //
+ // Debug Message requires current time.
+ //
+ time (&CurrentTime);
+ NewTime = localtime (&CurrentTime);
+ if (NewTime != NULL) {
+ fprintf (stdout, "%04d-%02d-%02d %02d:%02d:%02d",
+ NewTime->tm_year + 1900,
+ NewTime->tm_mon + 1,
+ NewTime->tm_mday,
+ NewTime->tm_hour,
+ NewTime->tm_min,
+ NewTime->tm_sec
+ );
+ }
+ if (Cptr != NULL) {
+ strcpy (Line, ": ");
+ strncat (Line, Cptr, MAX_LINE_LEN - strlen (Line) - 1);
+ if (LineNumber != 0) {
+ sprintf (Line2, "(%u)", (unsigned) LineNumber);
+ strncat (Line, Line2, MAX_LINE_LEN - strlen (Line) - 1);
+ }
+ }
+ } else {
+ //
+ // Error and Warning Information.
+ //
+ if (Cptr != NULL) {
+ if (mUtilityName[0] != '\0') {
+ fprintf (stdout, "%s...\n", mUtilityName);
+ }
+ strncpy (Line, Cptr, MAX_LINE_LEN - 1);
+ Line[MAX_LINE_LEN - 1] = 0;
+ if (LineNumber != 0) {
+ sprintf (Line2, "(%u)", (unsigned) LineNumber);
+ strncat (Line, Line2, MAX_LINE_LEN - strlen (Line) - 1);
+ }
+ } else {
+ if (mUtilityName[0] != '\0') {
+ strncpy (Line, mUtilityName, MAX_LINE_LEN - 1);
+ Line[MAX_LINE_LEN - 1] = 0;
+ }
+ }
+
+ if (strcmp (Type, "ERROR") == 0) {
+ //
+ // Set status accordingly for ERROR information.
+ //
+ if (mStatus < STATUS_ERROR) {
+ mStatus = STATUS_ERROR;
+ }
+ }
+ }
+
+ //
+ // Have to print an error code or Visual Studio won't find the
+ // message for you. It has to be decimal digits too.
+ //
+ strncat (Line, ": ", MAX_LINE_LEN - strlen (Line) - 1);
+ strncat (Line, Type, MAX_LINE_LEN - strlen (Line) - 1);
+ if (MessageCode != 0) {
+ sprintf (Line2, " %04u", (unsigned) MessageCode);
+ strncat (Line, Line2, MAX_LINE_LEN - strlen (Line) - 1);
+ }
+ fprintf (stdout, "%s", Line);
+ //
+ // If offending text was provided, then print it
+ //
+ if (Text != NULL) {
+ fprintf (stdout, ": %s", Text);
+ }
+ fprintf (stdout, "\n");
+
+ //
+ // Print formatted message if provided
+ //
+ if (MsgFmt != NULL) {
+ vsprintf (Line2, MsgFmt, List);
+ fprintf (stdout, " %s\n", Line2);
+ }
+
+}
+
+STATIC
+VOID
+PrintSimpleMessage (
+ CHAR8 *MsgFmt,
+ va_list List
+ )
+/*++
+Routine Description:
+ Print message into stdout.
+
+Arguments:
+ MsgFmt - the format string for the message. Can contain formatting
+ controls for use with varargs.
+ List - the variable list.
+
+Returns:
+ None.
+--*/
+{
+ CHAR8 Line[MAX_LINE_LEN];
+ //
+ // Print formatted message if provided
+ //
+ if (MsgFmt != NULL) {
+ vsprintf (Line, MsgFmt, List);
+ fprintf (stdout, "%s\n", Line);
+ }
+}
+
+VOID
+ParserSetPosition (
+ CHAR8 *SourceFileName,
+ UINT32 LineNum
+ )
+/*++
+
+Routine Description:
+ Set the position in a file being parsed. This can be used to
+ print error messages deeper down in a parser.
+
+Arguments:
+ SourceFileName - name of the source file being parsed
+ LineNum - line number of the source file being parsed
+
+Returns:
+ NA
+
+--*/
+{
+ mSourceFileName = SourceFileName;
+ mSourceFileLineNum = LineNum;
+}
+
+VOID
+SetUtilityName (
+ CHAR8 *UtilityName
+ )
+/*++
+
+Routine Description:
+ All printed error/warning/debug messages follow the same format, and
+ typically will print a filename or utility name followed by the error
+ text. However if a filename is not passed to the print routines, then
+ they'll print the utility name if you call this function early in your
+ app to set the utility name.
+
+Arguments:
+ UtilityName - name of the utility, which will be printed with all
+ error/warning/debug messages.
+
+Returns:
+ NA
+
+--*/
+{
+ //
+ // Save the name of the utility in our local variable. Make sure its
+ // length does not exceed our buffer.
+ //
+ if (UtilityName != NULL) {
+ if (strlen (UtilityName) >= sizeof (mUtilityName)) {
+ Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");
+ }
+ strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);
+ mUtilityName[sizeof (mUtilityName) - 1] = 0;
+ } else {
+ Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");
+ }
+}
+
+STATUS
+GetUtilityStatus (
+ VOID
+ )
+/*++
+
+Routine Description:
+ When you call Error() or Warning(), this module keeps track of it and
+ sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility
+ exits, it can call this function to get the status and use it as a return
+ value.
+
+Arguments:
+ None.
+
+Returns:
+ Worst-case status reported, as defined by which print function was called.
+
+--*/
+{
+ return mStatus;
+}
+
+VOID
+SetPrintLevel (
+ UINT64 LogLevel
+ )
+/*++
+
+Routine Description:
+ Set the printing message Level. This is used by the PrintMsg() function
+ to determine when/if a message should be printed.
+
+Arguments:
+ LogLevel - 0~50 to specify the different level message.
+
+Returns:
+ NA
+
+--*/
+{
+ mPrintLogLevel = LogLevel;
+}
+
+VOID
+VerboseMsg (
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a verbose level message.
+
+Arguments:
+ MsgFmt - the format string for the message. Can contain formatting
+ controls for use with varargs.
+ List - the variable list.
+
+Returns:
+ NA
+
+--*/
+{
+ va_list List;
+ //
+ // If the debug level is less than current print level, then do nothing.
+ //
+ if (VERBOSE_LOG_LEVEL < mPrintLogLevel) {
+ return ;
+ }
+
+ va_start (List, MsgFmt);
+ PrintSimpleMessage (MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+NormalMsg (
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a default level message.
+
+Arguments:
+ MsgFmt - the format string for the message. Can contain formatting
+ controls for use with varargs.
+ List - the variable list.
+
+Returns:
+ NA
+
+--*/
+{
+ va_list List;
+ //
+ // If the debug level is less than current print level, then do nothing.
+ //
+ if (INFO_LOG_LEVEL < mPrintLogLevel) {
+ return ;
+ }
+
+ va_start (List, MsgFmt);
+ PrintSimpleMessage (MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+KeyMsg (
+ CHAR8 *MsgFmt,
+ ...
+ )
+/*++
+
+Routine Description:
+ Print a key level message.
+
+Arguments:
+ MsgFmt - the format string for the message. Can contain formatting
+ controls for use with varargs.
+ List - the variable list.
+
+Returns:
+ NA
+
+--*/
+{
+ va_list List;
+ //
+ // If the debug level is less than current print level, then do nothing.
+ //
+ if (KEY_LOG_LEVEL < mPrintLogLevel) {
+ return ;
+ }
+
+ va_start (List, MsgFmt);
+ PrintSimpleMessage (MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+SetPrintLimits (
+ UINT32 MaxErrors,
+ UINT32 MaxWarnings,
+ UINT32 MaxWarningsPlusErrors
+ )
+/*++
+
+Routine Description:
+ Set the limits of how many errors, warnings, and errors+warnings
+ we will print.
+
+Arguments:
+ MaxErrors - maximum number of error messages to print
+ MaxWarnings - maximum number of warning messages to print
+ MaxWarningsPlusErrors
+ - maximum number of errors+warnings to print
+
+Returns:
+ NA
+
+--*/
+{
+ mMaxErrors = MaxErrors;
+ mMaxWarnings = MaxWarnings;
+ mMaxWarningsPlusErrors = MaxWarningsPlusErrors;
+ mPrintLimitsSet = 1;
+}
+
+STATIC
+VOID
+PrintLimitExceeded (
+ VOID
+ )
+{
+ STATIC INT8 mPrintLimitExceeded = 0;
+ //
+ // If we've already printed the message, do nothing. Otherwise
+ // temporarily increase our print limits so we can pass one
+ // more message through.
+ //
+ if (mPrintLimitExceeded == 0) {
+ mPrintLimitExceeded++;
+ mMaxErrors++;
+ mMaxWarnings++;
+ mMaxWarningsPlusErrors++;
+ Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);
+ mMaxErrors--;
+ mMaxWarnings--;
+ mMaxWarningsPlusErrors--;
+ }
+}
+
+#if 0
+VOID
+TestUtilityMessages (
+ VOID
+ )
+{
+ CHAR8 *ArgStr = "ArgString";
+ int ArgInt;
+
+ ArgInt = 0x12345678;
+ //
+ // Test without setting utility name
+ //
+ fprintf (stdout, "* Testing without setting utility name\n");
+ fprintf (stdout, "** Test debug message not printed\n");
+ DebugMsg (NULL, 0, 0x00000001, NULL, NULL);
+ fprintf (stdout, "** Test warning with two strings and two args\n");
+ Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+ fprintf (stdout, "** Test error with two strings and two args\n");
+ Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+ fprintf (stdout, "** Test parser warning with nothing\n");
+ ParserWarning (0, NULL, NULL);
+ fprintf (stdout, "** Test parser error with nothing\n");
+ ParserError (0, NULL, NULL);
+ //
+ // Test with utility name set now
+ //
+ fprintf (stdout, "** Testingin with utility name set\n");
+ SetUtilityName ("MyUtilityName");
+ //
+ // Test debug prints
+ //
+ SetDebugMsgMask (2);
+ fprintf (stdout, "** Test debug message with one string\n");
+ DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);
+ fprintf (stdout, "** Test debug message with one string\n");
+ DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");
+ fprintf (stdout, "** Test debug message with two strings\n");
+ DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");
+ fprintf (stdout, "** Test debug message with two strings and two args\n");
+ DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+ //
+ // Test warning prints
+ //
+ fprintf (stdout, "** Test warning with no strings\n");
+ Warning (NULL, 0, 1234, NULL, NULL);
+ fprintf (stdout, "** Test warning with one string\n");
+ Warning (NULL, 0, 1234, "Text1", NULL);
+ fprintf (stdout, "** Test warning with one string\n");
+ Warning (NULL, 0, 1234, NULL, "Text2");
+ fprintf (stdout, "** Test warning with two strings and two args\n");
+ Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+ //
+ // Test error prints
+ //
+ fprintf (stdout, "** Test error with no strings\n");
+ Error (NULL, 0, 1234, NULL, NULL);
+ fprintf (stdout, "** Test error with one string\n");
+ Error (NULL, 0, 1234, "Text1", NULL);
+ fprintf (stdout, "** Test error with one string\n");
+ Error (NULL, 0, 1234, NULL, "Text2");
+ fprintf (stdout, "** Test error with two strings and two args\n");
+ Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+ //
+ // Test parser prints
+ //
+ fprintf (stdout, "** Test parser errors\n");
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserError (1234, NULL, NULL);
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserError (1234, "Text1", NULL);
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserError (1234, NULL, "Text2");
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserError (1234, "Text1", "Text2");
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+
+ fprintf (stdout, "** Test parser warnings\n");
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserWarning (4321, NULL, NULL);
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserWarning (4321, "Text1", NULL);
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserWarning (4321, NULL, "Text2");
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserWarning (4321, "Text1", "Text2");
+ ParserSetPosition (__FILE__, __LINE__ + 1);
+ ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
+}
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.h
new file mode 100644
index 00000000..406cc70e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/EfiUtilityMsgs.h
@@ -0,0 +1,164 @@
+/** @file
+Defines and prototypes for common EFI utility error and debug messages.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_UTILITY_MSGS_H_
+#define _EFI_UTILITY_MSGS_H_
+
+#include <Common/UefiBaseTypes.h>
+
+//
+// Log message print Level
+//
+#define VERBOSE_LOG_LEVEL 15
+#define WARNING_LOG_LEVEL 15
+#define INFO_LOG_LEVEL 20
+#define KEY_LOG_LEVEL 40
+#define ERROR_LOG_LEVLE 50
+
+//
+// Status codes returned by EFI utility programs and functions
+//
+#define STATUS_SUCCESS 0
+#define STATUS_WARNING 1
+#define STATUS_ERROR 2
+#define VOID void
+
+typedef int STATUS;
+
+#define MAX_LINE_LEN 0x200
+#define MAXIMUM_INPUT_FILE_NUM 10
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+//
+// When we call Error() or Warning(), the module keeps track of the worst
+// case reported. GetUtilityStatus() will get the worst-case results, which
+// can be used as the return value from the app.
+//
+STATUS
+GetUtilityStatus (
+ VOID
+ );
+
+//
+// If someone prints an error message and didn't specify a source file name,
+// then we print the utility name instead. However they must tell us the
+// utility name early on via this function.
+//
+VOID
+SetUtilityName (
+ CHAR8 *ProgramName
+ )
+;
+
+VOID
+PrintMessage (
+ CHAR8 *Type,
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT32 MessageCode,
+ CHAR8 *Text,
+ CHAR8 *MsgFmt,
+ va_list List
+ );
+
+VOID
+Error (
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT32 ErrorCode,
+ CHAR8 *OffendingText,
+ CHAR8 *MsgFmt,
+ ...
+ )
+;
+
+VOID
+Warning (
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT32 WarningCode,
+ CHAR8 *OffendingText,
+ CHAR8 *MsgFmt,
+ ...
+ )
+;
+
+VOID
+DebugMsg (
+ CHAR8 *FileName,
+ UINT32 LineNumber,
+ UINT64 MsgLevel,
+ CHAR8 *OffendingText,
+ CHAR8 *MsgFmt,
+ ...
+ )
+;
+
+VOID
+VerboseMsg (
+ CHAR8 *MsgFmt,
+ ...
+ );
+
+VOID
+NormalMsg (
+ CHAR8 *MsgFmt,
+ ...
+ );
+
+VOID
+KeyMsg (
+ CHAR8 *MsgFmt,
+ ...
+ );
+
+VOID
+SetPrintLevel (
+ UINT64 LogLevel
+ );
+
+VOID
+ParserSetPosition (
+ CHAR8 *SourceFileName,
+ UINT32 LineNum
+ )
+;
+
+VOID
+ParserError (
+ UINT32 ErrorCode,
+ CHAR8 *OffendingText,
+ CHAR8 *MsgFmt,
+ ...
+ )
+;
+
+VOID
+ParserWarning (
+ UINT32 ErrorCode,
+ CHAR8 *OffendingText,
+ CHAR8 *MsgFmt,
+ ...
+ )
+;
+
+VOID
+SetPrintLimits (
+ UINT32 NumErrors,
+ UINT32 NumWarnings,
+ UINT32 NumWarningsPlusErrors
+ )
+;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef _EFI_UTILITY_MSGS_H_
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c
new file mode 100644
index 00000000..fcf62e70
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c
@@ -0,0 +1,1775 @@
+/** @file
+EFI Firmware Volume routines which work on a Fv image in buffers.
+
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "FirmwareVolumeBufferLib.h"
+#include "BinderFuncs.h"
+
+//
+// Local macros
+//
+#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
+ ( \
+ (BOOLEAN) ( \
+ (FvbAttributes & EFI_FVB2_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
+ ) \
+ )
+
+
+//
+// Local prototypes
+//
+
+STATIC
+UINT32
+FvBufGetSecHdrLen(
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ if (FvBufExpand3ByteSize(SectionHeader->Size) == 0xffffff) {
+ return sizeof(EFI_COMMON_SECTION_HEADER2);
+ }
+ return sizeof(EFI_COMMON_SECTION_HEADER);
+}
+
+STATIC
+UINT32
+FvBufGetSecFileLen (
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ UINT32 Length;
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ Length = FvBufExpand3ByteSize(SectionHeader->Size);
+ if (Length == 0xffffff) {
+ Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
+ }
+ return Length;
+}
+
+//
+// Local prototypes
+//
+
+STATIC
+UINT16
+FvBufCalculateChecksum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ );
+
+STATIC
+UINT8
+FvBufCalculateChecksum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ );
+
+//
+// Procedures start
+//
+
+EFI_STATUS
+FvBufRemoveFileNew (
+ IN OUT VOID *Fv,
+ IN EFI_GUID *Name
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ SourceFv - Address of the Fv in memory, this firmware volume volume will
+ be modified, if SourceFfsFile exists
+ SourceFfsFile - Input FFS file to replace
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER* FileToRm;
+ UINTN FileToRmLength;
+
+ Status = FvBufFindFileByName(
+ Fv,
+ Name,
+ (VOID **)&FileToRm
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FileToRmLength = FvBufGetFfsFileSize (FileToRm);
+
+ CommonLibBinderSetMem (
+ FileToRm,
+ FileToRmLength,
+ (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY)
+ ? 0xFF : 0
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufRemoveFile (
+ IN OUT VOID *Fv,
+ IN EFI_GUID *Name
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ SourceFv - Address of the Fv in memory, this firmware volume volume will
+ be modified, if SourceFfsFile exists
+ SourceFfsFile - Input FFS file to replace
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER *NextFile;
+ EFI_FIRMWARE_VOLUME_HEADER *TempFv;
+ UINTN FileKey;
+ UINTN FvLength;
+
+ Status = FvBufFindFileByName(
+ Fv,
+ Name,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = FvBufGetSize (Fv, &FvLength);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TempFv = NULL;
+ Status = FvBufDuplicate (Fv, (VOID **)&TempFv);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = FvBufClearAllFiles (TempFv);
+ if (EFI_ERROR (Status)) {
+ CommonLibBinderFree (TempFv);
+ return Status;
+ }
+
+ // TempFv has been allocated. It must now be freed
+ // before returning.
+
+ FileKey = 0;
+ while (TRUE) {
+
+ Status = FvBufFindNextFile (Fv, &FileKey, (VOID **)&NextFile);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ } else if (EFI_ERROR (Status)) {
+ CommonLibBinderFree (TempFv);
+ return Status;
+ }
+
+ if (CommonLibBinderCompareGuid (Name, &NextFile->Name)) {
+ continue;
+ }
+ else {
+ Status = FvBufAddFile (TempFv, NextFile);
+ if (EFI_ERROR (Status)) {
+ CommonLibBinderFree (TempFv);
+ return Status;
+ }
+ }
+ }
+
+ CommonLibBinderCopyMem (Fv, TempFv, FvLength);
+ CommonLibBinderFree (TempFv);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufChecksumFile (
+ IN OUT VOID *FfsFile
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ SourceFfsFile - Input FFS file to update the checksum for
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+
+--*/
+{
+ EFI_FFS_FILE_HEADER* File = (EFI_FFS_FILE_HEADER*)FfsFile;
+ EFI_FFS_FILE_STATE StateBackup;
+ UINT32 FileSize;
+
+ FileSize = FvBufGetFfsFileSize (File);
+
+ //
+ // Fill in checksums and state, they must be 0 for checksumming.
+ //
+ File->IntegrityCheck.Checksum.Header = 0;
+ File->IntegrityCheck.Checksum.File = 0;
+ StateBackup = File->State;
+ File->State = 0;
+
+ File->IntegrityCheck.Checksum.Header =
+ FvBufCalculateChecksum8 (
+ (UINT8 *) File,
+ FvBufGetFfsHeaderSize (File)
+ );
+
+ if (File->Attributes & FFS_ATTRIB_CHECKSUM) {
+ File->IntegrityCheck.Checksum.File = FvBufCalculateChecksum8 (
+ (VOID*)((UINT8 *)File + FvBufGetFfsHeaderSize (File)),
+ FileSize - FvBufGetFfsHeaderSize (File)
+ );
+ } else {
+ File->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
+ }
+
+ File->State = StateBackup;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufChecksumHeader (
+ IN OUT VOID *Fv
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ SourceFv - Address of the Fv in memory, this firmware volume volume will
+ be modified, if SourceFfsFile exists
+ SourceFfsFile - Input FFS file to replace
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER* FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum =
+ FvBufCalculateChecksum16 (
+ (UINT16*) FvHeader,
+ FvHeader->HeaderLength / sizeof (UINT16)
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufDuplicate (
+ IN VOID *SourceFv,
+ IN OUT VOID **DestinationFv
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ SourceFv - Address of the Fv in memory
+ DestinationFv - Output for destination Fv
+ DestinationFv == NULL - invalid parameter
+ *DestinationFv == NULL - memory will be allocated
+ *DestinationFv != NULL - this address will be the destination
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN size;
+
+ if (DestinationFv == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvBufGetSize (SourceFv, &size);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (*DestinationFv == NULL) {
+ *DestinationFv = CommonLibBinderAllocate (size);
+ if (*DestinationFv == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ CommonLibBinderCopyMem (*DestinationFv, SourceFv, size);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufExtend (
+ IN VOID **Fv,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ Extends a firmware volume by the given number of bytes.
+
+ BUGBUG: Does not handle the case where the firmware volume has a
+ VTF (Volume Top File). The VTF will not be moved to the
+ end of the extended FV.
+
+Arguments:
+
+ Fv - Source and destination firmware volume.
+ Note: The original firmware volume buffer is freed!
+
+ Size - The minimum size that the firmware volume is to be extended by.
+ The FV may be extended more than this size.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN OldSize;
+ UINTN NewSize;
+ UINTN BlockCount;
+ VOID* NewFv;
+
+ EFI_FIRMWARE_VOLUME_HEADER* hdr;
+ EFI_FV_BLOCK_MAP_ENTRY* blk;
+
+ Status = FvBufGetSize (*Fv, &OldSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Locate the block map in the fv header
+ //
+ hdr = (EFI_FIRMWARE_VOLUME_HEADER*)*Fv;
+ blk = hdr->BlockMap;
+
+ //
+ // Calculate the number of blocks needed to achieve the requested
+ // size extension
+ //
+ BlockCount = ((Size + (blk->Length - 1)) / blk->Length);
+
+ //
+ // Calculate the new size from the number of blocks that will be added
+ //
+ NewSize = OldSize + (BlockCount * blk->Length);
+
+ NewFv = CommonLibBinderAllocate (NewSize);
+ if (NewFv == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy the old data
+ //
+ CommonLibBinderCopyMem (NewFv, *Fv, OldSize);
+
+ //
+ // Free the old fv buffer
+ //
+ CommonLibBinderFree (*Fv);
+
+ //
+ // Locate the block map in the new fv header
+ //
+ hdr = (EFI_FIRMWARE_VOLUME_HEADER*)NewFv;
+ hdr->FvLength = NewSize;
+ blk = hdr->BlockMap;
+
+ //
+ // Update the block map for the new fv
+ //
+ blk->NumBlocks += (UINT32)BlockCount;
+
+ //
+ // Update the FV header checksum
+ //
+ FvBufChecksumHeader (NewFv);
+
+ //
+ // Clear out the new area of the FV
+ //
+ CommonLibBinderSetMem (
+ (UINT8*)NewFv + OldSize,
+ (NewSize - OldSize),
+ (hdr->Attributes & EFI_FVB2_ERASE_POLARITY) ? 0xFF : 0
+ );
+
+ //
+ // Set output with new fv that was created
+ //
+ *Fv = NewFv;
+
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS
+FvBufClearAllFiles (
+ IN OUT VOID *Fv
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+
+{
+ EFI_FIRMWARE_VOLUME_HEADER *hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+ EFI_STATUS Status;
+ UINTN size = 0;
+
+ Status = FvBufGetSize (Fv, &size);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CommonLibBinderSetMem(
+ (UINT8*)hdr + hdr->HeaderLength,
+ size - hdr->HeaderLength,
+ (hdr->Attributes & EFI_FVB2_ERASE_POLARITY) ? 0xFF : 0
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufGetSize (
+ IN VOID *Fv,
+ OUT UINTN *Size
+ )
+/*++
+
+Routine Description:
+
+ Clears out all files from the Fv buffer in memory
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+
+{
+ EFI_FIRMWARE_VOLUME_HEADER *hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+ EFI_FV_BLOCK_MAP_ENTRY *blk = hdr->BlockMap;
+
+ *Size = 0;
+
+ while (blk->Length != 0 || blk->NumBlocks != 0) {
+ *Size = *Size + (blk->Length * blk->NumBlocks);
+ if (*Size >= 0x40000000) {
+ // If size is greater than 1GB, then assume it is corrupted
+ return EFI_VOLUME_CORRUPTED;
+ }
+ blk++;
+ }
+
+ if (*Size == 0) {
+ // If size is 0, then assume the volume is corrupted
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufAddFile (
+ IN OUT VOID *Fv,
+ IN VOID *File
+ )
+/*++
+
+Routine Description:
+
+ Adds a new FFS file
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+ File - FFS file to add to Fv
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+
+ EFI_FFS_FILE_HEADER *fhdr = NULL;
+ EFI_FVB_ATTRIBUTES_2 FvbAttributes;
+ UINTN offset;
+ UINTN fsize;
+ UINTN newSize;
+ UINTN clearLoop;
+
+ EFI_STATUS Status;
+ UINTN fvSize;
+
+ Status = FvBufGetSize (Fv, &fvSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FvbAttributes = hdr->Attributes;
+ newSize = FvBufGetFfsFileSize ((EFI_FFS_FILE_HEADER*)File);
+
+ for(
+ offset = (UINTN)ALIGN_POINTER (hdr->HeaderLength, 8);
+ offset + newSize <= fvSize;
+ offset = (UINTN)ALIGN_POINTER (offset, 8)
+ ) {
+
+ fhdr = (EFI_FFS_FILE_HEADER*) ((UINT8*)hdr + offset);
+
+ if (EFI_TEST_FFS_ATTRIBUTES_BIT(
+ FvbAttributes,
+ fhdr->State,
+ EFI_FILE_HEADER_VALID
+ )
+ ) {
+ // BUGBUG: Need to make sure that the new file does not already
+ // exist.
+
+ fsize = FvBufGetFfsFileSize (fhdr);
+ if (fsize == 0 || (offset + fsize > fvSize)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ offset = offset + fsize;
+ continue;
+ }
+
+ clearLoop = 0;
+ while ((clearLoop < newSize) &&
+ (((UINT8*)fhdr)[clearLoop] ==
+ (UINT8)((hdr->Attributes & EFI_FVB2_ERASE_POLARITY) ? 0xFF : 0)
+ )
+ ) {
+ clearLoop++;
+ }
+
+ //
+ // We found a place in the FV which is empty and big enough for
+ // the new file
+ //
+ if (clearLoop >= newSize) {
+ break;
+ }
+
+ offset = offset + 1; // Make some forward progress
+ }
+
+ if (offset + newSize > fvSize) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CommonLibBinderCopyMem (fhdr, File, newSize);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufAddFileWithExtend (
+ IN OUT VOID **Fv,
+ IN VOID *File
+ )
+/*++
+
+Routine Description:
+
+ Adds a new FFS file. Extends the firmware volume if needed.
+
+Arguments:
+
+ Fv - Source and destination firmware volume.
+ Note: If the FV is extended, then the original firmware volume
+ buffer is freed!
+
+ Size - The minimum size that the firmware volume is to be extended by.
+ The FV may be extended more than this size.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER* NewFile;
+
+ NewFile = (EFI_FFS_FILE_HEADER*)File;
+
+ //
+ // Try to add to the capsule volume
+ //
+ Status = FvBufAddFile (*Fv, NewFile);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ //
+ // Try to extend the capsule volume by the size of the file
+ //
+ Status = FvBufExtend (Fv, FvBufExpand3ByteSize (NewFile->Size));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Now, try to add the file again
+ //
+ Status = FvBufAddFile (*Fv, NewFile);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+FvBufAddVtfFile (
+ IN OUT VOID *Fv,
+ IN VOID *File
+ )
+/*++
+
+Routine Description:
+
+ Adds a new FFS VFT (Volume Top File) file. In other words, adds the
+ file to the end of the firmware volume.
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+ File - FFS file to add to Fv
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_STATUS Status;
+
+ EFI_FIRMWARE_VOLUME_HEADER *hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+
+ EFI_FFS_FILE_HEADER* NewFile;
+ UINTN NewFileSize;
+
+ UINT8 erasedUint8;
+ UINTN clearLoop;
+
+ EFI_FFS_FILE_HEADER *LastFile;
+ UINTN LastFileSize;
+
+ UINTN fvSize;
+ UINTN Key;
+
+ Status = FvBufGetSize (Fv, &fvSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ erasedUint8 = (UINT8)((hdr->Attributes & EFI_FVB2_ERASE_POLARITY) ? 0xFF : 0);
+ NewFileSize = FvBufGetFfsFileSize ((EFI_FFS_FILE_HEADER*)File);
+
+ if (NewFileSize != (UINTN)ALIGN_POINTER (NewFileSize, 8)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Find the last file in the FV
+ //
+ Key = 0;
+ LastFile = NULL;
+ LastFileSize = 0;
+ do {
+ Status = FvBufFindNextFile (Fv, &Key, (VOID **)&LastFile);
+ LastFileSize = FvBufGetFfsFileSize ((EFI_FFS_FILE_HEADER*)File);
+ } while (!EFI_ERROR (Status));
+
+ //
+ // If no files were found, then we start at the beginning of the FV
+ //
+ if (LastFile == NULL) {
+ LastFile = (EFI_FFS_FILE_HEADER*)((UINT8*)hdr + hdr->HeaderLength);
+ }
+
+ //
+ // We want to put the new file (VTF) at the end of the FV
+ //
+ NewFile = (EFI_FFS_FILE_HEADER*)((UINT8*)hdr + (fvSize - NewFileSize));
+
+ //
+ // Check to see if there is enough room for the VTF after the last file
+ // found in the FV
+ //
+ if ((UINT8*)NewFile < ((UINT8*)LastFile + LastFileSize)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Loop to determine if the end of the FV is empty
+ //
+ clearLoop = 0;
+ while ((clearLoop < NewFileSize) &&
+ (((UINT8*)NewFile)[clearLoop] == erasedUint8)
+ ) {
+ clearLoop++;
+ }
+
+ //
+ // Check to see if there was not enough room for the file
+ //
+ if (clearLoop < NewFileSize) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CommonLibBinderCopyMem (NewFile, File, NewFileSize);
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+FvBufCompact3ByteSize (
+ OUT VOID* SizeDest,
+ IN UINT32 Size
+ )
+/*++
+
+Routine Description:
+
+ Expands the 3 byte size commonly used in Firmware Volume data structures
+
+Arguments:
+
+ Size - Address of the 3 byte array representing the size
+
+Returns:
+
+ UINT32
+
+--*/
+{
+ ((UINT8*)SizeDest)[0] = (UINT8)Size;
+ ((UINT8*)SizeDest)[1] = (UINT8)(Size >> 8);
+ ((UINT8*)SizeDest)[2] = (UINT8)(Size >> 16);
+}
+
+UINT32
+FvBufGetFfsFileSize (
+ IN EFI_FFS_FILE_HEADER *Ffs
+ )
+/*++
+
+Routine Description:
+
+ Get the FFS file size.
+
+Arguments:
+
+ Ffs - Pointer to FFS header
+
+Returns:
+
+ UINT32
+
+--*/
+{
+ if (Ffs == NULL) {
+ return 0;
+ }
+ if (Ffs->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return (UINT32) ((EFI_FFS_FILE_HEADER2 *)Ffs)->ExtendedSize;
+ }
+ return FvBufExpand3ByteSize(Ffs->Size);
+}
+
+UINT32
+FvBufGetFfsHeaderSize (
+ IN EFI_FFS_FILE_HEADER *Ffs
+ )
+/*++
+
+Routine Description:
+
+ Get the FFS header size.
+
+Arguments:
+
+ Ffs - Pointer to FFS header
+
+Returns:
+
+ UINT32
+
+--*/
+{
+ if (Ffs == NULL) {
+ return 0;
+ }
+ if (Ffs->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return sizeof(EFI_FFS_FILE_HEADER2);
+ }
+ return sizeof(EFI_FFS_FILE_HEADER);
+}
+
+UINT32
+FvBufExpand3ByteSize (
+ IN VOID* Size
+ )
+/*++
+
+Routine Description:
+
+ Expands the 3 byte size commonly used in Firmware Volume data structures
+
+Arguments:
+
+ Size - Address of the 3 byte array representing the size
+
+Returns:
+
+ UINT32
+
+--*/
+{
+ return (((UINT8*)Size)[2] << 16) +
+ (((UINT8*)Size)[1] << 8) +
+ ((UINT8*)Size)[0];
+}
+
+EFI_STATUS
+FvBufFindNextFile (
+ IN VOID *Fv,
+ IN OUT UINTN *Key,
+ OUT VOID **File
+ )
+/*++
+
+Routine Description:
+
+ Iterates through the files contained within the firmware volume
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+ Key - Should be 0 to get the first file. After that, it should be
+ passed back in without modifying its contents to retrieve
+ subsequent files.
+ File - Output file pointer
+ File == NULL - invalid parameter
+ otherwise - *File will be update to the location of the file
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+
+ EFI_FFS_FILE_HEADER *fhdr = NULL;
+ EFI_FVB_ATTRIBUTES_2 FvbAttributes;
+ UINTN fsize;
+
+ EFI_STATUS Status;
+ UINTN fvSize;
+
+ if (Fv == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvBufGetSize (Fv, &fvSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (*Key == 0) {
+ *Key = hdr->HeaderLength;
+ }
+
+ FvbAttributes = hdr->Attributes;
+
+ for(
+ *Key = (UINTN)ALIGN_POINTER (*Key, 8);
+ (*Key + sizeof (*fhdr)) < fvSize;
+ *Key = (UINTN)ALIGN_POINTER (*Key, 8)
+ ) {
+
+ fhdr = (EFI_FFS_FILE_HEADER*) ((UINT8*)hdr + *Key);
+ fsize = FvBufGetFfsFileSize (fhdr);
+
+ if (!EFI_TEST_FFS_ATTRIBUTES_BIT(
+ FvbAttributes,
+ fhdr->State,
+ EFI_FILE_HEADER_VALID
+ ) ||
+ EFI_TEST_FFS_ATTRIBUTES_BIT(
+ FvbAttributes,
+ fhdr->State,
+ EFI_FILE_HEADER_INVALID
+ )
+ ) {
+ *Key = *Key + 1; // Make some forward progress
+ continue;
+ } else if(
+ EFI_TEST_FFS_ATTRIBUTES_BIT(
+ FvbAttributes,
+ fhdr->State,
+ EFI_FILE_MARKED_FOR_UPDATE
+ ) ||
+ EFI_TEST_FFS_ATTRIBUTES_BIT(
+ FvbAttributes,
+ fhdr->State,
+ EFI_FILE_DELETED
+ )
+ ) {
+ *Key = *Key + fsize;
+ continue;
+ } else if (EFI_TEST_FFS_ATTRIBUTES_BIT(
+ FvbAttributes,
+ fhdr->State,
+ EFI_FILE_DATA_VALID
+ )
+ ) {
+ *File = (UINT8*)hdr + *Key;
+ *Key = *Key + fsize;
+ return EFI_SUCCESS;
+ }
+
+ *Key = *Key + 1; // Make some forward progress
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+FvBufFindFileByName (
+ IN VOID *Fv,
+ IN EFI_GUID *Name,
+ OUT VOID **File
+ )
+/*++
+
+Routine Description:
+
+ Searches the Fv for a file by its name
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+ Name - Guid filename to search for in the firmware volume
+ File - Output file pointer
+ File == NULL - Only determine if the file exists, based on return
+ value from the function call.
+ otherwise - *File will be update to the location of the file
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Key;
+ EFI_FFS_FILE_HEADER *NextFile;
+
+ Key = 0;
+ while (TRUE) {
+ Status = FvBufFindNextFile (Fv, &Key, (VOID **)&NextFile);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (CommonLibBinderCompareGuid (Name, &NextFile->Name)) {
+ if (File != NULL) {
+ *File = NextFile;
+ }
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+FvBufFindFileByType (
+ IN VOID *Fv,
+ IN EFI_FV_FILETYPE Type,
+ OUT VOID **File
+ )
+/*++
+
+Routine Description:
+
+ Searches the Fv for a file by its type
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+ Type - FFS FILE type to search for
+ File - Output file pointer
+ (File == NULL) -> Only determine if the file exists, based on return
+ value from the function call.
+ otherwise -> *File will be update to the location of the file
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Key;
+ EFI_FFS_FILE_HEADER *NextFile;
+
+ Key = 0;
+ while (TRUE) {
+ Status = FvBufFindNextFile (Fv, &Key, (VOID **)&NextFile);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Type == NextFile->Type) {
+ if (File != NULL) {
+ *File = NextFile;
+ }
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+FvBufGetFileRawData (
+ IN VOID* FfsFile,
+ OUT VOID** RawData,
+ OUT UINTN* RawDataSize
+ )
+/*++
+
+Routine Description:
+
+ Searches the requested file for raw data.
+
+ This routine either returns all the payload of a EFI_FV_FILETYPE_RAW file,
+ or finds the EFI_SECTION_RAW section within the file and returns its data.
+
+Arguments:
+
+ FfsFile - Address of the FFS file in memory
+ RawData - Pointer to the raw data within the file
+ (This is NOT allocated. It is within the file.)
+ RawDataSize - Size of the raw data within the file
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER* File;
+ EFI_RAW_SECTION* Section;
+
+ File = (EFI_FFS_FILE_HEADER*)FfsFile;
+
+ //
+ // Is the file type == EFI_FV_FILETYPE_RAW?
+ //
+ if (File->Type == EFI_FV_FILETYPE_RAW) {
+ //
+ // Raw filetypes don't have sections, so we just return the raw data
+ //
+ *RawData = (VOID*)((UINT8 *)File + FvBufGetFfsHeaderSize (File));
+ *RawDataSize = FvBufGetFfsFileSize (File) - FvBufGetFfsHeaderSize (File);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Within the file, we now need to find the EFI_SECTION_RAW section.
+ //
+ Status = FvBufFindSectionByType (File, EFI_SECTION_RAW, (VOID **)&Section);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *RawData = (VOID*)((UINT8 *)Section + FvBufGetSecHdrLen(Section));
+ *RawDataSize =
+ FvBufGetSecFileLen (Section) - FvBufGetSecHdrLen(Section);
+
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS
+FvBufPackageFreeformRawFile (
+ IN EFI_GUID* Filename,
+ IN VOID* RawData,
+ IN UINTN RawDataSize,
+ OUT VOID** FfsFile
+ )
+/*++
+
+Routine Description:
+
+ Packages up a FFS file containing the input raw data.
+
+ The file created will have a type of EFI_FV_FILETYPE_FREEFORM, and will
+ contain one EFI_FV_FILETYPE_RAW section.
+
+Arguments:
+
+ RawData - Pointer to the raw data to be packed
+ RawDataSize - Size of the raw data to be packed
+ FfsFile - Address of the packaged FFS file.
+ Note: The called must deallocate this memory!
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_FFS_FILE_HEADER* NewFile;
+ UINT32 NewFileSize;
+ EFI_RAW_SECTION* NewSection;
+ UINT32 NewSectionSize;
+ UINT32 FfsHdrLen;
+ UINT32 SecHdrLen;
+
+ //
+ // The section size is the DataSize + the size of the section header
+ //
+ NewSectionSize = (UINT32)sizeof (EFI_RAW_SECTION) + (UINT32)RawDataSize;
+ SecHdrLen = sizeof (EFI_RAW_SECTION);
+ if (NewSectionSize >= MAX_SECTION_SIZE) {
+ NewSectionSize = (UINT32)sizeof (EFI_RAW_SECTION2) + (UINT32)RawDataSize;
+ SecHdrLen = sizeof (EFI_RAW_SECTION2);
+ }
+
+ //
+ // The file size is the size of the file header + the section size
+ //
+ NewFileSize = sizeof (EFI_FFS_FILE_HEADER) + NewSectionSize;
+ FfsHdrLen = sizeof (EFI_FFS_FILE_HEADER);
+ if (NewFileSize >= MAX_FFS_SIZE) {
+ NewFileSize = sizeof (EFI_FFS_FILE_HEADER2) + NewSectionSize;
+ FfsHdrLen = sizeof (EFI_FFS_FILE_HEADER2);
+ }
+
+ //
+ // Try to allocate a buffer to build the new FFS file in
+ //
+ NewFile = CommonLibBinderAllocate (NewFileSize);
+ if (NewFile == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CommonLibBinderSetMem (NewFile, NewFileSize, 0);
+
+ //
+ // The NewSection follow right after the FFS file header
+ //
+ NewSection = (EFI_RAW_SECTION*)((UINT8*)NewFile + FfsHdrLen);
+ if (NewSectionSize >= MAX_SECTION_SIZE) {
+ FvBufCompact3ByteSize (NewSection->Size, 0xffffff);
+ ((EFI_RAW_SECTION2 *)NewSection)->ExtendedSize = NewSectionSize;
+ } else {
+ FvBufCompact3ByteSize (NewSection->Size, NewSectionSize);
+ }
+ NewSection->Type = EFI_SECTION_RAW;
+
+ //
+ // Copy the actual file data into the buffer
+ //
+ CommonLibBinderCopyMem ((UINT8 *)NewSection + SecHdrLen, RawData, RawDataSize);
+
+ //
+ // Initialize the FFS file header
+ //
+ CommonLibBinderCopyMem (&NewFile->Name, Filename, sizeof (EFI_GUID));
+ NewFile->Attributes = 0;
+ if (NewFileSize >= MAX_FFS_SIZE) {
+ FvBufCompact3ByteSize (NewFile->Size, 0x0);
+ ((EFI_FFS_FILE_HEADER2 *)NewFile)->ExtendedSize = NewFileSize;
+ NewFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
+ } else {
+ FvBufCompact3ByteSize (NewFile->Size, NewFileSize);
+ }
+ NewFile->Type = EFI_FV_FILETYPE_FREEFORM;
+ NewFile->IntegrityCheck.Checksum.Header =
+ FvBufCalculateChecksum8 ((UINT8*)NewFile, FfsHdrLen);
+ NewFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
+ NewFile->State = (UINT8)~( EFI_FILE_HEADER_CONSTRUCTION |
+ EFI_FILE_HEADER_VALID |
+ EFI_FILE_DATA_VALID
+ );
+
+ *FfsFile = NewFile;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FvBufFindNextSection (
+ IN VOID *SectionsStart,
+ IN UINTN TotalSectionsSize,
+ IN OUT UINTN *Key,
+ OUT VOID **Section
+ )
+/*++
+
+Routine Description:
+
+ Iterates through the sections contained within a given array of sections
+
+Arguments:
+
+ SectionsStart - Address of the start of the FFS sections array
+ TotalSectionsSize - Total size of all the sections
+ Key - Should be 0 to get the first section. After that, it should be
+ passed back in without modifying its contents to retrieve
+ subsequent files.
+ Section - Output section pointer
+ (Section == NULL) -> invalid parameter
+ otherwise -> *Section will be update to the location of the file
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_COMMON_SECTION_HEADER *sectionHdr;
+ UINTN sectionSize;
+
+ *Key = (UINTN)ALIGN_POINTER (*Key, 4); // Sections are DWORD aligned
+
+ if ((*Key + sizeof (*sectionHdr)) > TotalSectionsSize) {
+ return EFI_NOT_FOUND;
+ }
+
+ sectionHdr = (EFI_COMMON_SECTION_HEADER*)((UINT8*)SectionsStart + *Key);
+ sectionSize = FvBufGetSecFileLen (sectionHdr);
+
+ if (sectionSize < sizeof (EFI_COMMON_SECTION_HEADER)) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ((*Key + sectionSize) > TotalSectionsSize) {
+ return EFI_NOT_FOUND;
+ }
+
+ *Section = (UINT8*)sectionHdr;
+ *Key = *Key + sectionSize;
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS
+FvBufCountSections (
+ IN VOID* FfsFile,
+ IN UINTN* Count
+ )
+/*++
+
+Routine Description:
+
+ Searches the FFS file and counts the number of sections found.
+ The sections are NOT recursed.
+
+Arguments:
+
+ FfsFile - Address of the FFS file in memory
+ Count - The location to store the section count in
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Key;
+ VOID* SectionStart;
+ UINTN TotalSectionsSize;
+ EFI_COMMON_SECTION_HEADER* NextSection;
+
+ SectionStart = (VOID*)((UINTN)FfsFile + FvBufGetFfsHeaderSize(FfsFile));
+ TotalSectionsSize =
+ FvBufGetFfsFileSize ((EFI_FFS_FILE_HEADER*)FfsFile) -
+ FvBufGetFfsHeaderSize(FfsFile);
+ Key = 0;
+ *Count = 0;
+ while (TRUE) {
+ Status = FvBufFindNextSection (
+ SectionStart,
+ TotalSectionsSize,
+ &Key,
+ (VOID **)&NextSection
+ );
+ if (Status == EFI_NOT_FOUND) {
+ return EFI_SUCCESS;
+ } else if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Increment the section counter
+ //
+ *Count += 1;
+
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+FvBufFindSectionByType (
+ IN VOID *FfsFile,
+ IN UINT8 Type,
+ OUT VOID **Section
+ )
+/*++
+
+Routine Description:
+
+ Searches the FFS file for a section by its type
+
+Arguments:
+
+ FfsFile - Address of the FFS file in memory
+ Type - FFS FILE section type to search for
+ Section - Output section pointer
+ (Section == NULL) -> Only determine if the section exists, based on return
+ value from the function call.
+ otherwise -> *Section will be update to the location of the file
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Key;
+ VOID* SectionStart;
+ UINTN TotalSectionsSize;
+ EFI_COMMON_SECTION_HEADER* NextSection;
+
+ SectionStart = (VOID*)((UINTN)FfsFile + FvBufGetFfsHeaderSize(FfsFile));
+ TotalSectionsSize =
+ FvBufGetFfsFileSize ((EFI_FFS_FILE_HEADER*)FfsFile) -
+ FvBufGetFfsHeaderSize(FfsFile);
+ Key = 0;
+ while (TRUE) {
+ Status = FvBufFindNextSection (
+ SectionStart,
+ TotalSectionsSize,
+ &Key,
+ (VOID **)&NextSection
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Type == NextSection->Type) {
+ if (Section != NULL) {
+ *Section = NextSection;
+ }
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+FvBufShrinkWrap (
+ IN VOID *Fv
+ )
+/*++
+
+Routine Description:
+
+ Shrinks a firmware volume (in place) to provide a minimal FV.
+
+ BUGBUG: Does not handle the case where the firmware volume has a
+ VTF (Volume Top File). The VTF will not be moved to the
+ end of the extended FV.
+
+Arguments:
+
+ Fv - Firmware volume.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN OldSize;
+ UINT32 BlockCount;
+ UINT32 NewBlockSize = 128;
+ UINTN Key;
+ EFI_FFS_FILE_HEADER* FileIt;
+ VOID* EndOfLastFile;
+
+ EFI_FIRMWARE_VOLUME_HEADER* FvHdr;
+
+ Status = FvBufGetSize (Fv, &OldSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = FvBufUnifyBlockSizes (Fv, NewBlockSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Locate the block map in the fv header
+ //
+ FvHdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+
+ //
+ // Find the end of the last file
+ //
+ Key = 0;
+ EndOfLastFile = (UINT8*)FvHdr + FvHdr->FvLength;
+ while (!EFI_ERROR (FvBufFindNextFile (Fv, &Key, (VOID **)&FileIt))) {
+ EndOfLastFile =
+ (VOID*)((UINT8*)FileIt + FvBufGetFfsFileSize (FileIt));
+ }
+
+ //
+ // Set the BlockCount to have the minimal number of blocks for the Fv.
+ //
+ BlockCount = (UINT32)((UINTN)EndOfLastFile - (UINTN)Fv);
+ BlockCount = BlockCount + NewBlockSize - 1;
+ BlockCount = BlockCount / NewBlockSize;
+
+ //
+ // Adjust the block count to shrink the Fv in place.
+ //
+ FvHdr->BlockMap[0].NumBlocks = BlockCount;
+ FvHdr->FvLength = BlockCount * NewBlockSize;
+
+ //
+ // Update the FV header checksum
+ //
+ FvBufChecksumHeader (Fv);
+
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS
+FvBufUnifyBlockSizes (
+ IN OUT VOID *Fv,
+ IN UINTN BlockSize
+ )
+/*++
+
+Routine Description:
+
+ Searches the FFS file for a section by its type
+
+Arguments:
+
+ Fv - Address of the Fv in memory
+ BlockSize - The size of the blocks to convert the Fv to. If the total size
+ of the Fv is not evenly divisible by this size, then
+ EFI_INVALID_PARAMETER will be returned.
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_FOUND
+ EFI_VOLUME_CORRUPTED
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *hdr = (EFI_FIRMWARE_VOLUME_HEADER*)Fv;
+ EFI_FV_BLOCK_MAP_ENTRY *blk = hdr->BlockMap;
+ UINT32 Size;
+
+ Size = 0;
+
+ //
+ // Scan through the block map list, performing error checking, and adding
+ // up the total Fv size.
+ //
+ while( blk->Length != 0 ||
+ blk->NumBlocks != 0
+ ) {
+ Size = Size + (blk->Length * blk->NumBlocks);
+ blk++;
+ if ((UINT8*)blk > ((UINT8*)hdr + hdr->HeaderLength)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+ }
+
+ //
+ // Make sure that the Fv size is a multiple of the new block size.
+ //
+ if ((Size % BlockSize) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Zero out the entire block map.
+ //
+ CommonLibBinderSetMem (
+ &hdr->BlockMap,
+ (UINTN)blk - (UINTN)&hdr->BlockMap,
+ 0
+ );
+
+ //
+ // Write out the single block map entry.
+ //
+ hdr->BlockMap[0].Length = (UINT32)BlockSize;
+ hdr->BlockMap[0].NumBlocks = Size / (UINT32)BlockSize;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+UINT16
+FvBufCalculateSum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ This function calculates the UINT16 sum for the requested region.
+
+Arguments:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Returns:
+
+ The 16 bit checksum
+
+--*/
+{
+ UINTN Index;
+ UINT16 Sum;
+
+ Sum = 0;
+
+ //
+ // Perform the word sum for buffer
+ //
+ for (Index = 0; Index < Size; Index++) {
+ Sum = (UINT16) (Sum + Buffer[Index]);
+ }
+
+ return (UINT16) Sum;
+}
+
+
+STATIC
+UINT16
+FvBufCalculateChecksum16 (
+ IN UINT16 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description::
+
+ This function calculates the value needed for a valid UINT16 checksum
+
+Arguments:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Returns:
+
+ The 16 bit checksum value needed.
+
+--*/
+{
+ return (UINT16)(0x10000 - FvBufCalculateSum16 (Buffer, Size));
+}
+
+
+STATIC
+UINT8
+FvBufCalculateSum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Description:
+
+ This function calculates the UINT8 sum for the requested region.
+
+Input:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Return:
+
+ The 8 bit checksum value needed.
+
+--*/
+{
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+
+ //
+ // Perform the byte sum for buffer
+ //
+ for (Index = 0; Index < Size; Index++) {
+ Sum = (UINT8) (Sum + Buffer[Index]);
+ }
+
+ return Sum;
+}
+
+
+STATIC
+UINT8
+FvBufCalculateChecksum8 (
+ IN UINT8 *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Description:
+
+ This function calculates the value needed for a valid UINT8 checksum
+
+Input:
+
+ Buffer Pointer to buffer containing byte data of component.
+ Size Size of the buffer
+
+Return:
+
+ The 8 bit checksum value needed.
+
+--*/
+{
+ return (UINT8)(0x100 - FvBufCalculateSum8 (Buffer, Size));
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBufferLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBufferLib.h
new file mode 100644
index 00000000..6ba9e80e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FirmwareVolumeBufferLib.h
@@ -0,0 +1,163 @@
+/** @file
+EFI Firmware Volume routines which work on a Fv image in buffers.
+
+Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FirmwareVolumeBuffer_h_INCLUDED
+#define FirmwareVolumeBuffer_h_INCLUDED
+
+#include "Common/UefiBaseTypes.h"
+#include "Common/PiFirmwareFile.h"
+#include "Common/PiFirmwareVolume.h"
+
+EFI_STATUS
+FvBufAddFile (
+ IN OUT VOID *Fv,
+ IN VOID *File
+ );
+
+EFI_STATUS
+FvBufAddFileWithExtend (
+ IN OUT VOID **Fv,
+ IN VOID *File
+ );
+
+EFI_STATUS
+FvBufAddVtfFile (
+ IN OUT VOID *Fv,
+ IN VOID *File
+ );
+
+EFI_STATUS
+FvBufChecksumFile (
+ IN OUT VOID *FfsFile
+ );
+
+EFI_STATUS
+FvBufChecksumHeader (
+ IN OUT VOID *Fv
+ );
+
+EFI_STATUS
+FvBufClearAllFiles (
+ IN OUT VOID *Fv
+ );
+
+VOID
+FvBufCompact3ByteSize (
+ OUT VOID* SizeDest,
+ IN UINT32 Size
+ );
+
+EFI_STATUS
+FvBufCountSections (
+ IN VOID* FfsFile,
+ IN UINTN* Count
+ );
+
+EFI_STATUS
+FvBufDuplicate (
+ IN VOID *SourceFv,
+ IN OUT VOID **DestinationFv
+ );
+
+UINT32
+FvBufExpand3ByteSize (
+ IN VOID* Size
+ );
+
+UINT32
+FvBufGetFfsFileSize (
+ IN EFI_FFS_FILE_HEADER *Ffs
+ );
+
+UINT32
+FvBufGetFfsHeaderSize (
+ IN EFI_FFS_FILE_HEADER *Ffs
+ );
+
+EFI_STATUS
+FvBufExtend (
+ IN VOID **Fv,
+ IN UINTN Size
+ );
+
+EFI_STATUS
+FvBufFindFileByName (
+ IN VOID *Fv,
+ IN EFI_GUID *Name,
+ OUT VOID **File
+ );
+
+EFI_STATUS
+FvBufFindFileByType (
+ IN VOID *Fv,
+ IN EFI_FV_FILETYPE Type,
+ OUT VOID **File
+ );
+
+EFI_STATUS
+FvBufFindNextFile (
+ IN VOID *Fv,
+ IN OUT UINTN *Key,
+ OUT VOID **File
+ );
+
+EFI_STATUS
+FvBufFindNextSection (
+ IN VOID *SectionsStart,
+ IN UINTN TotalSectionsSize,
+ IN OUT UINTN *Key,
+ OUT VOID **Section
+ );
+
+EFI_STATUS
+FvBufFindSectionByType (
+ IN VOID *FfsFile,
+ IN UINT8 Type,
+ OUT VOID **Section
+ );
+
+EFI_STATUS
+FvBufGetFileRawData (
+ IN VOID* FfsFile,
+ OUT VOID** RawData,
+ OUT UINTN* RawDataSize
+ );
+
+EFI_STATUS
+FvBufGetSize (
+ IN VOID *Fv,
+ OUT UINTN *Size
+ );
+
+EFI_STATUS
+FvBufPackageFreeformRawFile (
+ IN EFI_GUID* Filename,
+ IN VOID* RawData,
+ IN UINTN RawDataSize,
+ OUT VOID** FfsFile
+ );
+
+EFI_STATUS
+FvBufRemoveFile (
+ IN OUT VOID *Fv,
+ IN EFI_GUID *Name
+ );
+
+EFI_STATUS
+FvBufUnifyBlockSizes (
+ IN OUT VOID *Fv,
+ IN UINTN BlockSize
+ );
+
+EFI_STATUS
+FvBufShrinkWrap (
+ IN VOID *Fv
+ );
+
+#endif // #ifndef FirmwareVolumeBuffer_h_INCLUDED
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.c
new file mode 100644
index 00000000..d9f45930
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.c
@@ -0,0 +1,927 @@
+/** @file
+These functions assist in parsing and manipulating a Firmware Volume.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Include files
+//
+#include "FvLib.h"
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+
+//
+// Module global variables
+//
+EFI_FIRMWARE_VOLUME_HEADER *mFvHeader = NULL;
+UINT32 mFvLength = 0;
+
+//
+// External function implementations
+//
+EFI_STATUS
+InitializeFvLib (
+ IN VOID *Fv,
+ IN UINT32 FvLength
+ )
+/*++
+
+Routine Description:
+
+ This initializes the FV lib with a pointer to the FV and length. It does not
+ verify the FV in any way.
+
+Arguments:
+
+ Fv Buffer containing the FV.
+ FvLength Length of the FV
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+{
+ //
+ // Verify input arguments
+ //
+ if (Fv == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv;
+ mFvLength = FvLength;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetFvHeader (
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader,
+ OUT UINT32 *FvLength
+ )
+/*++
+
+Routine Description:
+
+ This function returns a pointer to the current FV and the size.
+
+Arguments:
+
+ FvHeader Pointer to the FV buffer.
+ FvLength Length of the FV
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_ABORTED The library needs to be initialized.
+
+--*/
+{
+ //
+ // Verify library has been initialized.
+ //
+ if (mFvHeader == NULL || mFvLength == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify input arguments
+ //
+ if (FvHeader == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *FvHeader = mFvHeader;
+ *FvLength = mFvLength;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetNextFile (
+ IN EFI_FFS_FILE_HEADER *CurrentFile,
+ OUT EFI_FFS_FILE_HEADER **NextFile
+ )
+/*++
+
+Routine Description:
+
+ This function returns the next file. If the current file is NULL, it returns
+ the first file in the FV. If the function returns EFI_SUCCESS and the file
+ pointer is NULL, then there are no more files in the FV.
+
+Arguments:
+
+ CurrentFile Pointer to the current file, must be within the current FV.
+ NextFile Pointer to the next file in the FV.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
+ EFI_ABORTED The library needs to be initialized.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Verify library has been initialized.
+ //
+ if (mFvHeader == NULL || mFvLength == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify input arguments
+ //
+ if (NextFile == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Verify FV header
+ //
+ Status = VerifyFv (mFvHeader);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ //
+ // Get first file
+ //
+ if (CurrentFile == NULL) {
+ CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength);
+
+ //
+ // Verify file is valid
+ //
+ Status = VerifyFfsFile (CurrentFile);
+ if (EFI_ERROR (Status)) {
+ //
+ // no files in this FV
+ //
+ *NextFile = NULL;
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Verify file is in this FV.
+ //
+ if ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength) {
+ *NextFile = NULL;
+ return EFI_SUCCESS;
+ }
+
+ *NextFile = CurrentFile;
+ return EFI_SUCCESS;
+ }
+ }
+ //
+ // Verify current file is in range
+ //
+ if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||
+ ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength)
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Get next file, compensate for 8 byte alignment if necessary.
+ //
+ *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetFfsFileLength(CurrentFile) + 0x07) & (~(UINTN) 7)) + (UINT8 *) mFvHeader);
+
+ //
+ // Verify file is in this FV.
+ //
+ if (((UINTN) *NextFile + GetFfsHeaderLength(*NextFile) >= (UINTN) mFvHeader + mFvLength) ||
+ ((UINTN) *NextFile + GetFfsFileLength (*NextFile) > (UINTN) mFvHeader + mFvLength)
+ ) {
+ *NextFile = NULL;
+ return EFI_SUCCESS;
+ }
+ //
+ // Verify file is valid
+ //
+ Status = VerifyFfsFile (*NextFile);
+ if (EFI_ERROR (Status)) {
+ //
+ // no more files in this FV
+ //
+ *NextFile = NULL;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetFileByName (
+ IN EFI_GUID *FileName,
+ OUT EFI_FFS_FILE_HEADER **File
+ )
+/*++
+
+Routine Description:
+
+ Find a file by name. The function will return NULL if the file is not found.
+
+Arguments:
+
+ FileName The GUID file name of the file to search for.
+ File Return pointer. In the case of an error, contents are undefined.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_ABORTED An error was encountered.
+ EFI_INVALID_PARAMETER One of the parameters was NULL.
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *CurrentFile;
+ EFI_STATUS Status;
+ CHAR8 FileGuidString[80];
+
+ //
+ // Verify library has been initialized.
+ //
+ if (mFvHeader == NULL || mFvLength == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify input parameters
+ //
+ if (FileName == NULL || File == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // File Guid String Name
+ //
+ PrintGuidToBuffer (FileName, (UINT8 *)FileGuidString, sizeof (FileGuidString), TRUE);
+ //
+ // Verify FV header
+ //
+ Status = VerifyFv (mFvHeader);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ //
+ // Get the first file
+ //
+ Status = GetNextFile (NULL, &CurrentFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "FFS file with Guid %s can't be found", FileGuidString);
+ return EFI_ABORTED;
+ }
+ //
+ // Loop as long as we have a valid file
+ //
+ while (CurrentFile) {
+ if (!CompareGuid (&CurrentFile->Name, FileName)) {
+ *File = CurrentFile;
+ return EFI_SUCCESS;
+ }
+
+ Status = GetNextFile (CurrentFile, &CurrentFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "FFS file with Guid %s can't be found", FileGuidString);
+ return EFI_ABORTED;
+ }
+ }
+ //
+ // File not found in this FV.
+ //
+ *File = NULL;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetFileByType (
+ IN EFI_FV_FILETYPE FileType,
+ IN UINTN Instance,
+ OUT EFI_FFS_FILE_HEADER **File
+ )
+/*++
+
+Routine Description:
+
+ Find a file by type and instance. An instance of 1 is the first instance.
+ The function will return NULL if a matching file cannot be found.
+ File type EFI_FV_FILETYPE_ALL means any file type is valid.
+
+Arguments:
+
+ FileType Type of file to search for.
+ Instance Instance of the file type to return.
+ File Return pointer. In the case of an error, contents are undefined.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_ABORTED An error was encountered.
+ EFI_INVALID_PARAMETER One of the parameters was NULL.
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *CurrentFile;
+ EFI_STATUS Status;
+ UINTN FileCount;
+
+ //
+ // Verify library has been initialized.
+ //
+ if (mFvHeader == NULL || mFvLength == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify input parameters
+ //
+ if (File == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Verify FV header
+ //
+ Status = VerifyFv (mFvHeader);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ //
+ // Initialize the number of matching files found.
+ //
+ FileCount = 0;
+
+ //
+ // Get the first file
+ //
+ Status = GetNextFile (NULL, &CurrentFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "FFS file with FileType 0x%x can't be found", FileType);
+ return EFI_ABORTED;
+ }
+ //
+ // Loop as long as we have a valid file
+ //
+ while (CurrentFile) {
+ if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) {
+ FileCount++;
+ }
+
+ if (FileCount == Instance) {
+ *File = CurrentFile;
+ return EFI_SUCCESS;
+ }
+
+ Status = GetNextFile (CurrentFile, &CurrentFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "FFS file with FileType 0x%x can't be found", FileType);
+ return EFI_ABORTED;
+ }
+ }
+
+ *File = NULL;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SearchSectionByType (
+ IN EFI_FILE_SECTION_POINTER FirstSection,
+ IN UINT8 *SearchEnd,
+ IN EFI_SECTION_TYPE SectionType,
+ IN OUT UINTN *StartIndex,
+ IN UINTN Instance,
+ OUT EFI_FILE_SECTION_POINTER *Section
+ )
+/*++
+
+Routine Description:
+
+ Helper function to search a sequence of sections from the section pointed
+ by FirstSection to SearchEnd for the Instance-th section of type SectionType.
+ The current counter is saved in StartIndex and when the section is found, it's
+ saved in Section. GUID-defined sections, if special processing is not required,
+ are searched recursively in a depth-first manner.
+
+Arguments:
+
+ FirstSection The first section to start searching from.
+ SearchEnd The end address to stop search.
+ SectionType The type of section to search.
+ StartIndex The current counter is saved.
+ Instance The requested n-th section number.
+ Section The found section returned.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_NOT_FOUND The section is not found.
+--*/
+{
+ EFI_FILE_SECTION_POINTER CurrentSection;
+ EFI_FILE_SECTION_POINTER InnerSection;
+ EFI_STATUS Status;
+ UINTN SectionSize;
+ UINT16 GuidSecAttr;
+ UINT16 GuidDataOffset;
+
+ GuidSecAttr = 0;
+ GuidDataOffset = 0;
+ CurrentSection = FirstSection;
+
+ while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {
+ if (CurrentSection.CommonHeader->Type == SectionType) {
+ (*StartIndex)++;
+ }
+
+ if (*StartIndex == Instance) {
+ *Section = CurrentSection;
+ return EFI_SUCCESS;
+ }
+ //
+ // If the requesting section is not GUID-defined and
+ // we find a GUID-defined section that doesn't need
+ // special processing, go ahead to search the requesting
+ // section inside the GUID-defined section.
+ //
+ if (CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED) {
+ if (GetLength(CurrentSection.CommonHeader->Size) == 0xffffff) {
+ GuidSecAttr = CurrentSection.GuidDefinedSection2->Attributes;
+ GuidDataOffset = CurrentSection.GuidDefinedSection2->DataOffset;
+ } else {
+ GuidSecAttr = CurrentSection.GuidDefinedSection->Attributes;
+ GuidDataOffset = CurrentSection.GuidDefinedSection->DataOffset;
+ }
+ }
+ if (SectionType != EFI_SECTION_GUID_DEFINED &&
+ CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&
+ !(GuidSecAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {
+ InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)
+ ((UINTN) CurrentSection.CommonHeader + GuidDataOffset);
+ SectionSize = GetSectionFileLength(CurrentSection.CommonHeader);
+ Status = SearchSectionByType (
+ InnerSection,
+ (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),
+ SectionType,
+ StartIndex,
+ Instance,
+ Section
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+ }
+ //
+ // Find next section (including compensating for alignment issues.
+ //
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetSectionFileLength(CurrentSection.CommonHeader) + 0x03) & (~(UINTN) 3));
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+GetSectionByType (
+ IN EFI_FFS_FILE_HEADER *File,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_FILE_SECTION_POINTER *Section
+ )
+/*++
+
+Routine Description:
+
+ Find a section in a file by type and instance. An instance of 1 is the first
+ instance. The function will return NULL if a matching section cannot be found.
+ GUID-defined sections, if special processing is not needed, are handled in a
+ depth-first manner.
+
+Arguments:
+
+ File The file to search.
+ SectionType Type of file to search for.
+ Instance Instance of the section to return.
+ Section Return pointer. In the case of an error, contents are undefined.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_ABORTED An error was encountered.
+ EFI_INVALID_PARAMETER One of the parameters was NULL.
+ EFI_NOT_FOUND No found.
+--*/
+{
+ EFI_FILE_SECTION_POINTER CurrentSection;
+ EFI_STATUS Status;
+ UINTN SectionCount;
+
+ //
+ // Verify input parameters
+ //
+ if (File == NULL || Instance == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Verify FFS header
+ //
+ Status = VerifyFfsFile (File);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0006, "invalid FFS file", NULL);
+ return EFI_ABORTED;
+ }
+ //
+ // Initialize the number of matching sections found.
+ //
+ SectionCount = 0;
+
+ //
+ // Get the first section
+ //
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + GetFfsHeaderLength(File));
+
+ //
+ // Depth-first manner to find section file.
+ //
+ Status = SearchSectionByType (
+ CurrentSection,
+ (UINT8 *) ((UINTN) File + GetFfsFileLength (File)),
+ SectionType,
+ &SectionCount,
+ Instance,
+ Section
+ );
+
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Section not found
+ //
+ (*Section).Code16Section = NULL;
+ return EFI_NOT_FOUND;
+ }
+}
+//
+// will not parse compressed sections
+//
+EFI_STATUS
+VerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+/*++
+
+Routine Description:
+
+ Verify the current pointer points to a valid FV header.
+
+Arguments:
+
+ FvHeader Pointer to an alleged FV file.
+
+Returns:
+
+ EFI_SUCCESS The FV header is valid.
+ EFI_VOLUME_CORRUPTED The FV header is not valid.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_ABORTED Operation aborted.
+
+--*/
+{
+ UINT16 Checksum;
+
+ //
+ // Verify input parameters
+ //
+ if (FvHeader == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FvHeader->Signature != EFI_FVH_SIGNATURE) {
+ Error (NULL, 0, 0006, "invalid FV header signature", NULL);
+ return EFI_VOLUME_CORRUPTED;
+ }
+ //
+ // Verify header checksum
+ //
+ Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+
+ if (Checksum != 0) {
+ Error (NULL, 0, 0006, "invalid FV header checksum", NULL);
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VerifyFfsFile (
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Verify the current pointer points to a FFS file header.
+
+Arguments:
+
+ FfsHeader Pointer to an alleged FFS file.
+
+Returns:
+
+ EFI_SUCCESS The Ffs header is valid.
+ EFI_NOT_FOUND This "file" is the beginning of free space.
+ EFI_VOLUME_CORRUPTED The Ffs header is not valid.
+ EFI_ABORTED The erase polarity is not known.
+
+--*/
+{
+ BOOLEAN ErasePolarity;
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER2 BlankHeader;
+ UINT8 Checksum;
+ UINT32 FileLength;
+ UINT8 SavedChecksum;
+ UINT8 SavedState;
+ UINT8 FileGuidString[80];
+ UINT32 FfsHeaderSize;
+
+ //
+ // Verify library has been initialized.
+ //
+ if (mFvHeader == NULL || mFvLength == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify FV header
+ //
+ Status = VerifyFv (mFvHeader);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ //
+ // Get the erase polarity.
+ //
+ Status = GetErasePolarity (&ErasePolarity);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+
+ FfsHeaderSize = GetFfsHeaderLength(FfsHeader);
+ //
+ // Check if we have free space
+ //
+ if (ErasePolarity) {
+ memset (&BlankHeader, -1, FfsHeaderSize);
+ } else {
+ memset (&BlankHeader, 0, FfsHeaderSize);
+ }
+
+ if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Convert the GUID to a string so we can at least report which file
+ // if we find an error.
+ //
+ PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE);
+ //
+ // Verify file header checksum
+ //
+ SavedState = FfsHeader->State;
+ FfsHeader->State = 0;
+ SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;
+ FfsHeader->IntegrityCheck.Checksum.File = 0;
+ Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize);
+ FfsHeader->State = SavedState;
+ FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;
+ if (Checksum != 0) {
+ Error (NULL, 0, 0006, "invalid FFS file header checksum", "Ffs file with Guid %s", FileGuidString);
+ return EFI_ABORTED;
+ }
+ //
+ // Verify file checksum
+ //
+ if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
+ //
+ // Verify file data checksum
+ //
+ FileLength = GetFfsFileLength (FfsHeader);
+ Checksum = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize);
+ Checksum = Checksum + FfsHeader->IntegrityCheck.Checksum.File;
+ if (Checksum != 0) {
+ Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString);
+ return EFI_ABORTED;
+ }
+ } else {
+ //
+ // File does not have a checksum
+ // Verify contents are 0xAA as spec'd
+ //
+ if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
+ Error (NULL, 0, 0006, "invalid fixed FFS file header checksum", "Ffs file with Guid %s", FileGuidString);
+ return EFI_ABORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT32
+GetFfsHeaderLength(
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+{
+ if (FfsHeader == NULL) {
+ return 0;
+ }
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return sizeof(EFI_FFS_FILE_HEADER2);
+ }
+ return sizeof(EFI_FFS_FILE_HEADER);
+}
+
+UINT32
+GetSectionHeaderLength(
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ if (GetLength(SectionHeader->Size) == 0xffffff) {
+ return sizeof(EFI_COMMON_SECTION_HEADER2);
+ }
+ return sizeof(EFI_COMMON_SECTION_HEADER);
+}
+
+UINT32
+GetFfsFileLength (
+ EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Get FFS file length including FFS header.
+
+Arguments:
+
+ FfsHeader Pointer to EFI_FFS_FILE_HEADER.
+
+Returns:
+
+ UINT32 Length of FFS file header.
+
+--*/
+{
+ if (FfsHeader == NULL) {
+ return 0;
+ }
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return (UINT32) ((EFI_FFS_FILE_HEADER2 *)FfsHeader)->ExtendedSize;
+ } else {
+ return GetLength(FfsHeader->Size);
+ }
+}
+
+UINT32
+GetSectionFileLength (
+ EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ UINT32 Length;
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ Length = GetLength(SectionHeader->Size);
+ if (Length == 0xffffff) {
+ Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
+ }
+ return Length;
+}
+
+UINT32
+GetLength (
+ UINT8 *ThreeByteLength
+ )
+/*++
+
+Routine Description:
+
+ Converts a three byte length value into a UINT32.
+
+Arguments:
+
+ ThreeByteLength Pointer to the first of the 3 byte length.
+
+Returns:
+
+ UINT32 Size of the section
+
+--*/
+{
+ UINT32 Length;
+
+ if (ThreeByteLength == NULL) {
+ return 0;
+ }
+
+ Length = *((UINT32 *) ThreeByteLength);
+ Length = Length & 0x00FFFFFF;
+
+ return Length;
+}
+
+EFI_STATUS
+GetErasePolarity (
+ OUT BOOLEAN *ErasePolarity
+ )
+/*++
+
+Routine Description:
+
+ This function returns with the FV erase polarity. If the erase polarity
+ for a bit is 1, the function return TRUE.
+
+Arguments:
+
+ ErasePolarity A pointer to the erase polarity.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED Operation aborted.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Verify library has been initialized.
+ //
+ if (mFvHeader == NULL || mFvLength == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify FV header
+ //
+ Status = VerifyFv (mFvHeader);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ //
+ // Verify input parameters.
+ //
+ if (ErasePolarity == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mFvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ *ErasePolarity = TRUE;
+ } else {
+ *ErasePolarity = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT8
+GetFileState (
+ IN BOOLEAN ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ This function returns a the highest state bit in the FFS that is set.
+ It in no way validate the FFS file.
+
+Arguments:
+
+ ErasePolarity The erase polarity for the file state bits.
+ FfsHeader Pointer to a FFS file.
+
+Returns:
+
+ UINT8 The hightest set state of the file.
+
+--*/
+{
+ UINT8 FileState;
+ UINT8 HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity) {
+ FileState = (UINT8)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.h
new file mode 100644
index 00000000..0128779e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/FvLib.h
@@ -0,0 +1,189 @@
+/** @file
+These functions assist in parsing and manipulating a Firmware Volume.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_FV_LIB_H
+#define _EFI_FV_LIB_H
+
+//
+// Include files
+//
+#include <string.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/PiFirmwareFile.h>
+#include <Common/PiFirmwareVolume.h>
+
+EFI_STATUS
+InitializeFvLib (
+ IN VOID *Fv,
+ IN UINT32 FvLength
+ )
+;
+
+EFI_STATUS
+GetFvHeader (
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader,
+ OUT UINT32 *FvLength
+ )
+;
+
+EFI_STATUS
+GetNextFile (
+ IN EFI_FFS_FILE_HEADER *CurrentFile,
+ OUT EFI_FFS_FILE_HEADER **NextFile
+ )
+;
+
+EFI_STATUS
+GetFileByName (
+ IN EFI_GUID *FileName,
+ OUT EFI_FFS_FILE_HEADER **File
+ )
+;
+
+EFI_STATUS
+GetFileByType (
+ IN EFI_FV_FILETYPE FileType,
+ IN UINTN Instance,
+ OUT EFI_FFS_FILE_HEADER **File
+ )
+;
+
+EFI_STATUS
+GetSectionByType (
+ IN EFI_FFS_FILE_HEADER *File,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_FILE_SECTION_POINTER *Section
+ )
+;
+//
+// will not parse compressed sections
+//
+EFI_STATUS
+VerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+;
+
+EFI_STATUS
+VerifyFfsFile (
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+;
+
+UINT32
+GetFfsFileLength (
+ EFI_FFS_FILE_HEADER *FfsHeader
+ )
+;
+
+UINT32
+GetSectionFileLength (
+ EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+;
+
+UINT32
+GetFfsHeaderLength(
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+;
+
+UINT32
+GetSectionHeaderLength(
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+;
+
+/*++
+
+Routine Description:
+
+ Verify the current pointer points to a FFS file header.
+
+Arguments:
+
+ FfsHeader Pointer to an alleged FFS file.
+
+Returns:
+
+ EFI_SUCCESS The Ffs header is valid.
+ EFI_NOT_FOUND This "file" is the beginning of free space.
+ EFI_VOLUME_CORRUPTED The Ffs header is not valid.
+
+--*/
+UINT32
+GetLength (
+ UINT8 *ThreeByteLength
+ )
+;
+
+/*++
+
+Routine Description:
+
+ Converts a three byte length value into a UINT32.
+
+Arguments:
+
+ ThreeByteLength Pointer to the first of the 3 byte length.
+
+Returns:
+
+ UINT32 Size of the section
+
+--*/
+EFI_STATUS
+GetErasePolarity (
+ OUT BOOLEAN *ErasePolarity
+ )
+;
+
+/*++
+
+Routine Description:
+
+ This function returns with the FV erase polarity. If the erase polarity
+ for a bit is 1, the function return TRUE.
+
+Arguments:
+
+ ErasePolarity A pointer to the erase polarity.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+
+--*/
+UINT8
+GetFileState (
+ IN BOOLEAN ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+;
+
+/*++
+
+Routine Description:
+
+ This function returns a the highest state bit in the FFS that is set.
+ It in no way validate the FFS file.
+
+Arguments:
+
+ ErasePolarity The erase polarity for the file state bits.
+ FfsHeader Pointer to a FFS file.
+
+Returns:
+
+ UINT8 The hightest set state of the file.
+
+--*/
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/GNUmakefile
new file mode 100644
index 00000000..a2ff48f3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/GNUmakefile
@@ -0,0 +1,33 @@
+## @file
+# GNU/Linux makefile for 'Common' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+# VPATH = ..
+
+LIBNAME = Common
+
+OBJECTS = \
+ BasePeCoff.o \
+ BinderFuncs.o \
+ CommonLib.o \
+ Crc32.o \
+ Decompress.o \
+ EfiCompress.o \
+ EfiUtilityMsgs.o \
+ FirmwareVolumeBuffer.o \
+ FvLib.o \
+ MemoryFile.o \
+ MyAlloc.o \
+ OsPath.o \
+ ParseGuidedSectionTools.o \
+ ParseInf.o \
+ PeCoffLoaderEx.o \
+ SimpleFileParsing.o \
+ StringFuncs.o \
+ TianoCompress.o
+
+include $(MAKEROOT)/Makefiles/lib.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile
new file mode 100644
index 00000000..971025f6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile
@@ -0,0 +1,36 @@
+## @file
+# Windows makefile for 'Common' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+# VPATH = ..
+
+LIBNAME = Common
+
+OBJECTS = \
+ BasePeCoff.obj \
+ BinderFuncs.obj \
+ CommonLib.obj \
+ Crc32.obj \
+ Decompress.obj \
+ EfiCompress.obj \
+ EfiUtilityMsgs.obj \
+ FirmwareVolumeBuffer.obj \
+ FvLib.obj \
+ MemoryFile.obj \
+ MyAlloc.obj \
+ OsPath.obj \
+ ParseGuidedSectionTools.obj \
+ ParseInf.obj \
+ PeCoffLoaderEx.obj \
+ SimpleFileParsing.obj \
+ StringFuncs.obj \
+ TianoCompress.obj
+
+!INCLUDE ..\Makefiles\ms.lib
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile.kmk
new file mode 100644
index 00000000..aab8f640
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/Makefile.kmk
@@ -0,0 +1,63 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI build tool common library.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+LIBRARIES += EfiBldCommonLib
+EfiBldCommonLib_TEMPLATE = VBoxEfiBldLib
+EfiBldCommonLib_SOURCES = \
+ BasePeCoff.c \
+ BinderFuncs.c \
+ CommonLib.c \
+ Crc32.c \
+ Decompress.c \
+ EfiCompress.c \
+ EfiUtilityMsgs.c \
+ FirmwareVolumeBuffer.c \
+ FvLib.c \
+ MemoryFile.c \
+ MyAlloc.c \
+ OsPath.c \
+ ParseGuidedSectionTools.c \
+ ParseInf.c \
+ PeCoffLoaderEx.c \
+ SimpleFileParsing.c \
+ StringFuncs.c \
+ TianoCompress.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.c
new file mode 100644
index 00000000..68277e98
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.c
@@ -0,0 +1,251 @@
+/** @file
+This contains some useful functions for accessing files.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "CommonLib.h"
+#include "MemoryFile.h"
+
+
+//
+// Local (static) function prototypes
+//
+STATIC
+VOID
+CheckMemoryFileState (
+ IN EFI_HANDLE InputMemoryFile
+ );
+
+//
+// Function implementations
+//
+
+EFI_STATUS
+GetMemoryFile (
+ IN CHAR8 *InputFileName,
+ OUT EFI_HANDLE *OutputMemoryFile
+ )
+/*++
+
+Routine Description:
+
+ This opens a file, reads it into memory and returns a memory file
+ object.
+
+Arguments:
+
+ InputFile Memory file image.
+ OutputMemoryFile Handle to memory file
+
+Returns:
+
+ EFI_STATUS
+ OutputMemoryFile is valid if !EFI_ERROR
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *InputFileImage;
+ UINT32 BytesRead;
+ MEMORY_FILE *NewMemoryFile;
+
+ Status = GetFileImage (InputFileName, &InputFileImage, &BytesRead);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ NewMemoryFile = malloc (sizeof (*NewMemoryFile));
+ if (NewMemoryFile == NULL) {
+ free (InputFileImage);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewMemoryFile->FileImage = InputFileImage;
+ NewMemoryFile->CurrentFilePointer = InputFileImage;
+ NewMemoryFile->Eof = InputFileImage + BytesRead;
+
+ *OutputMemoryFile = (EFI_HANDLE)NewMemoryFile;
+
+ CheckMemoryFileState (*OutputMemoryFile);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FreeMemoryFile (
+ IN EFI_HANDLE InputMemoryFile
+ )
+/*++
+
+Routine Description:
+
+ Frees all memory associated with the input memory file.
+
+Arguments:
+
+ InputMemoryFile Handle to memory file
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ MEMORY_FILE *MemoryFile;
+
+ CheckMemoryFileState (InputMemoryFile);
+
+ MemoryFile = (MEMORY_FILE*)InputMemoryFile;
+
+ free (MemoryFile->FileImage);
+
+ //
+ // Invalidate state of MEMORY_FILE structure to catch invalid usage.
+ //
+ memset (MemoryFile, 0xcc, sizeof (*MemoryFile));
+ MemoryFile->Eof -= 1;
+
+ free (MemoryFile);
+
+ return EFI_SUCCESS;
+}
+
+
+CHAR8 *
+ReadMemoryFileLine (
+ IN EFI_HANDLE InputMemoryFile
+ )
+/*++
+
+Routine Description:
+
+ This function reads a line from the memory file. The newline characters
+ are stripped and a null terminated string is returned.
+
+ If the string pointer returned is non-NULL, then the caller must free the
+ memory associated with this string.
+
+Arguments:
+
+ InputMemoryFile Handle to memory file
+
+Returns:
+
+ NULL if error or EOF
+ NULL character termincated string otherwise (MUST BE FREED BY CALLER)
+
+--*/
+{
+ CHAR8 *EndOfLine;
+ UINTN CharsToCopy;
+ MEMORY_FILE *InputFile;
+ UINTN BytesToEof;
+ CHAR8 *OutputString;
+
+ //
+ // Verify input parameters are not null
+ //
+ CheckMemoryFileState (InputMemoryFile);
+
+ InputFile = (MEMORY_FILE*)InputMemoryFile;
+
+ //
+ // Check for end of file condition
+ //
+ if (InputFile->CurrentFilePointer >= InputFile->Eof) {
+ return NULL;
+ }
+
+ //
+ // Determine the number of bytes remaining until the EOF
+ //
+ BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer;
+
+ //
+ // Find the next newline char
+ //
+ EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof);
+
+ //
+ // Determine the number of characters to copy.
+ //
+ if (EndOfLine == 0) {
+ //
+ // If no newline found, copy to the end of the file.
+ //
+ CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
+ } else {
+ //
+ // Newline found in the file.
+ //
+ CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;
+ }
+
+ OutputString = malloc (CharsToCopy + 1);
+ if (OutputString == NULL) {
+ return NULL;
+ }
+
+ //
+ // Copy the line.
+ //
+ memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy);
+
+ //
+ // Add the null termination over the 0x0D
+ //
+ if (OutputString[CharsToCopy - 1] == '\r') {
+
+ OutputString[CharsToCopy - 1] = '\0';
+
+ } else {
+
+ OutputString[CharsToCopy] = '\0';
+
+ }
+
+ //
+ // Increment the current file pointer (include the 0x0A)
+ //
+ InputFile->CurrentFilePointer += CharsToCopy + 1;
+ if (InputFile->CurrentFilePointer > InputFile->Eof) {
+ InputFile->CurrentFilePointer = InputFile->Eof;
+ }
+ CheckMemoryFileState (InputMemoryFile);
+
+ //
+ // Return the string
+ //
+ return OutputString;
+}
+
+
+STATIC
+VOID
+CheckMemoryFileState (
+ IN EFI_HANDLE InputMemoryFile
+ )
+{
+ MEMORY_FILE *MemoryFile;
+
+ assert (InputMemoryFile != NULL);
+
+ MemoryFile = (MEMORY_FILE*)InputMemoryFile;
+
+ assert (MemoryFile->FileImage != NULL);
+ assert (MemoryFile->CurrentFilePointer != NULL);
+ assert (MemoryFile->Eof != NULL);
+ assert (MemoryFile->Eof >= MemoryFile->FileImage);
+ assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage);
+ assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof);
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.h
new file mode 100644
index 00000000..56a11d89
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MemoryFile.h
@@ -0,0 +1,105 @@
+/** @file
+Header file for helper functions useful for accessing files.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_MEMORY_FILE_H
+#define _EFI_MEMORY_FILE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Common/UefiBaseTypes.h>
+
+//
+// Common data structures
+//
+typedef struct {
+ CHAR8 *FileImage;
+ CHAR8 *Eof;
+ CHAR8 *CurrentFilePointer;
+} MEMORY_FILE;
+
+
+//
+// Functions declarations
+//
+
+EFI_STATUS
+GetMemoryFile (
+ IN CHAR8 *InputFileName,
+ OUT EFI_HANDLE *OutputMemoryFile
+ )
+;
+/**
+
+Routine Description:
+
+ This opens a file, reads it into memory and returns a memory file
+ object.
+
+Arguments:
+
+ InputFile Memory file image.
+ OutputMemoryFile Handle to memory file
+
+Returns:
+
+ EFI_STATUS
+ OutputMemoryFile is valid if !EFI_ERROR
+
+**/
+
+
+EFI_STATUS
+FreeMemoryFile (
+ IN EFI_HANDLE InputMemoryFile
+ )
+;
+/**
+
+Routine Description:
+
+ Frees all memory associated with the input memory file.
+
+Arguments:
+
+ InputMemoryFile Handle to memory file
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+CHAR8 *
+ReadMemoryFileLine (
+ IN EFI_HANDLE InputMemoryFile
+ )
+;
+/**
+
+Routine Description:
+
+ This function reads a line from the memory file. The newline characters
+ are stripped and a null terminated string is returned.
+
+ If the string pointer returned is non-NULL, then the caller must free the
+ memory associated with this string.
+
+Arguments:
+
+ InputMemoryFile Handle to memory file
+
+Returns:
+
+ NULL if error or EOF
+ NULL character termincated string otherwise (MUST BE FREED BY CALLER)
+
+**/
+
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.c
new file mode 100644
index 00000000..dacb07ec
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.c
@@ -0,0 +1,548 @@
+/** @file
+File for memory allocation tracking functions.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MyAlloc.h"
+
+#if USE_MYALLOC
+//
+// Get back to original alloc/free calls.
+//
+#undef malloc
+#undef calloc
+#undef realloc
+#undef free
+//
+// Start of allocation list.
+//
+STATIC MY_ALLOC_STRUCT *MyAllocData = NULL;
+
+//
+//
+//
+STATIC UINT32 MyAllocHeadMagik = MYALLOC_HEAD_MAGIK;
+STATIC UINT32 MyAllocTailMagik = MYALLOC_TAIL_MAGIK;
+
+//
+// ////////////////////////////////////////////////////////////////////////////
+//
+//
+VOID
+MyCheck (
+ BOOLEAN Final,
+ UINT8 File[],
+ UINTN Line
+ )
+// *++
+// Description:
+//
+// Check for corruptions in the allocated memory chain. If a corruption
+// is detection program operation stops w/ an exit(1) call.
+//
+// Parameters:
+//
+// Final := When FALSE, MyCheck() returns if the allocated memory chain
+// has not been corrupted. When TRUE, MyCheck() returns if there
+// are no un-freed allocations. If there are un-freed allocations,
+// they are displayed and exit(1) is called.
+//
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// n/a
+//
+// --*/
+//
+{
+ MY_ALLOC_STRUCT *Tmp;
+
+ //
+ // Check parameters.
+ //
+ if (File == NULL) {
+ printf (
+ "\nMyCheck(Final=%u, File=NULL, Line=%u)"
+ "Invalid parameter(s).\n",
+ Final,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (Line == 0) {
+ printf (
+ "\nMyCheck(Final=%u, File=%s, Line=%u)"
+ "Invalid parameter(s).\n",
+ Final,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (strlen ((CHAR8 *)File) == 0) {
+ printf (
+ "\nMyCheck(Final=%u, File=%s, Line=%u)"
+ "Invalid parameter.\n",
+ Final,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Check structure contents.
+ //
+ for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {
+ if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) ||
+ memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) {
+ break;
+ }
+ }
+ //
+ // If Tmp is not NULL, the structure is corrupt.
+ //
+ if (Tmp != NULL) {
+ printf (
+ "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!"
+ "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",
+ Final,
+ File,
+ (unsigned)Line,
+ Tmp->File,
+ (unsigned) Tmp->Line,
+ (unsigned) Tmp->Size,
+ (unsigned) *(UINT32 *) (Tmp->Buffer),
+ (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])
+ );
+
+ exit (1);
+ }
+ //
+ // If Final is TRUE, display the state of the structure chain.
+ //
+ if (Final) {
+ if (MyAllocData != NULL) {
+ printf (
+ "\nMyCheck(Final=%u, File=%s, Line=%u)"
+ "\nSome allocated items have not been freed.\n",
+ Final,
+ File,
+ (unsigned)Line
+ );
+
+ for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {
+ printf (
+ "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",
+ Tmp->File,
+ (unsigned) Tmp->Line,
+ (unsigned) Tmp->Size,
+ (unsigned) *(UINT32 *) (Tmp->Buffer),
+ (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])
+ );
+ }
+ }
+ }
+}
+//
+// ////////////////////////////////////////////////////////////////////////////
+//
+//
+VOID *
+MyAlloc (
+ UINTN Size,
+ UINT8 File[],
+ UINTN Line
+ )
+// *++
+// Description:
+//
+// Allocate a new link in the allocation chain along with enough storage
+// for the File[] string, requested Size and alignment overhead. If
+// memory cannot be allocated or the allocation chain has been corrupted,
+// exit(1) will be called.
+//
+// Parameters:
+//
+// Size := Number of bytes (UINT8) requested by the called.
+// Size cannot be zero.
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// Pointer to the caller's buffer.
+//
+// --*/
+//
+{
+ MY_ALLOC_STRUCT *Tmp;
+ UINTN Len;
+
+ //
+ // Check for invalid parameters.
+ //
+ if (File == NULL) {
+ printf (
+ "\nMyAlloc(Size=%u, File=NULL, Line=%u)"
+ "\nInvalid parameter(s).\n",
+ (unsigned)Size,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (Size == 0 || Line == 0) {
+ printf (
+ "\nMyAlloc(Size=%u, File=%s, Line=%u)"
+ "\nInvalid parameter(s).\n",
+ (unsigned)Size,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ Len = strlen ((CHAR8 *)File);
+ if (Len == 0) {
+ printf (
+ "\nMyAlloc(Size=%u, File=%s, Line=%u)"
+ "\nInvalid parameter.\n",
+ (unsigned)Size,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Check the allocation list for corruption.
+ //
+ MyCheck (0, (UINT8 *)__FILE__, __LINE__);
+
+ //
+ // Allocate a new entry.
+ //
+ Tmp = calloc (
+ 1,
+ sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik)
+ );
+
+ if (Tmp == NULL) {
+ printf (
+ "\nMyAlloc(Size=%u, File=%s, Line=%u)"
+ "\nOut of memory.\n",
+ (unsigned)Size,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Fill in the new entry.
+ //
+ Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT);
+ strcpy ((CHAR8 *)Tmp->File, (CHAR8 *)File);
+ Tmp->Line = Line;
+ Tmp->Size = Size;
+ Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7);
+
+ memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik);
+
+ memcpy (
+ &Tmp->Buffer[Size + sizeof (UINT32)],
+ &MyAllocTailMagik,
+ sizeof MyAllocTailMagik
+ );
+
+ Tmp->Next = MyAllocData;
+ Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer);
+
+ MyAllocData = Tmp;
+
+ return Tmp->Buffer + sizeof (UINT32);
+}
+//
+// ////////////////////////////////////////////////////////////////////////////
+//
+//
+VOID *
+MyRealloc (
+ VOID *Ptr,
+ UINTN Size,
+ UINT8 File[],
+ UINTN Line
+ )
+// *++
+// Description:
+//
+// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization
+// for shrinking or expanding buffers. An invalid parameter will cause
+// MyRealloc() to fail with a call to exit(1).
+//
+// Parameters:
+//
+// Ptr := Pointer to the caller's buffer to be re-allocated.
+//
+// Size := Size of new buffer. Size cannot be zero.
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// Pointer to new caller's buffer.
+//
+// --*/
+//
+{
+ MY_ALLOC_STRUCT *Tmp;
+ VOID *Buffer;
+
+ //
+ // Check for invalid parameter(s).
+ //
+ if (File == NULL) {
+ printf (
+ "\nMyRealloc(Ptr=%p, Size=%u, File=NULL, Line=%u)"
+ "\nInvalid parameter(s).\n",
+ Ptr,
+ (unsigned)Size,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (Size == 0 || Line == 0) {
+ printf (
+ "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
+ "\nInvalid parameter(s).\n",
+ Ptr,
+ (unsigned)Size,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (strlen ((CHAR8 *)File) == 0) {
+ printf (
+ "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
+ "\nInvalid parameter.\n",
+ Ptr,
+ (unsigned)Size,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Find existing buffer in allocation list.
+ //
+ if (Ptr == NULL) {
+ Tmp = NULL;
+ } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {
+ Tmp = MyAllocData;
+ } else {
+ for (Tmp = MyAllocData;; Tmp = Tmp->Next) {
+ if (Tmp->Next == NULL) {
+ printf (
+ "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
+ "\nCould not find buffer.\n",
+ Ptr,
+ (unsigned)Size,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ Tmp = Tmp->Next;
+ }
+ }
+ //
+ // Allocate new buffer, copy old data, free old buffer.
+ //
+ Buffer = MyAlloc (Size, File, Line);
+
+ if (Buffer != NULL && Tmp != NULL) {
+ memcpy (
+ Buffer,
+ &Tmp->Buffer[sizeof (UINT32)],
+ ((Size <= Tmp->Size) ? Size : Tmp->Size)
+ );
+
+ MyFree (Ptr, (UINT8 *)__FILE__, __LINE__);
+ }
+
+ return Buffer;
+}
+//
+// ////////////////////////////////////////////////////////////////////////////
+//
+//
+VOID
+MyFree (
+ VOID *Ptr,
+ UINT8 File[],
+ UINTN Line
+ )
+// *++
+// Description:
+//
+// Release a previously allocated buffer. Invalid parameters will cause
+// MyFree() to fail with an exit(1) call.
+//
+// Parameters:
+//
+// Ptr := Pointer to the caller's buffer to be freed.
+// A NULL pointer will be ignored.
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// n/a
+//
+// --*/
+//
+{
+ MY_ALLOC_STRUCT *Tmp;
+ MY_ALLOC_STRUCT *Tmp2;
+
+ //
+ // Check for invalid parameter(s).
+ //
+ if (File == NULL) {
+ printf (
+ "\nMyFree(Ptr=%p, File=NULL, Line=%u)"
+ "\nInvalid parameter(s).\n",
+ Ptr,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (Line == 0) {
+ printf (
+ "\nMyFree(Ptr=%p, File=%s, Line=%u)"
+ "\nInvalid parameter(s).\n",
+ Ptr,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+
+ if (strlen ((CHAR8 *)File) == 0) {
+ printf (
+ "\nMyFree(Ptr=%p, File=%s, Line=%u)"
+ "\nInvalid parameter.\n",
+ Ptr,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Freeing NULL is always valid.
+ //
+ if (Ptr == NULL) {
+ return ;
+ }
+ //
+ // Fail if nothing is allocated.
+ //
+ if (MyAllocData == NULL) {
+ printf (
+ "\nMyFree(Ptr=%p, File=%s, Line=%u)"
+ "\nCalled before memory allocated.\n",
+ Ptr,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Check for corrupted allocation list.
+ //
+ MyCheck (0, (UINT8 *)__FILE__, __LINE__);
+
+ //
+ // Need special check for first item in list.
+ //
+ if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {
+ //
+ // Unlink first item in list.
+ //
+ Tmp = MyAllocData;
+ MyAllocData = MyAllocData->Next;
+ } else {
+ //
+ // Walk list looking for matching item.
+ //
+ for (Tmp = MyAllocData;; Tmp = Tmp->Next) {
+ //
+ // Fail if end of list is reached.
+ //
+ if (Tmp->Next == NULL) {
+ printf (
+ "\nMyFree(Ptr=%p, File=%s, Line=%u)\n"
+ "\nNot found.\n",
+ Ptr,
+ File,
+ (unsigned)Line
+ );
+
+ exit (1);
+ }
+ //
+ // Leave loop when match is found.
+ //
+ if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) {
+ break;
+ }
+ }
+ //
+ // Unlink item from list.
+ //
+ Tmp2 = Tmp->Next;
+ Tmp->Next = Tmp->Next->Next;
+ Tmp = Tmp2;
+ }
+ //
+ // Release item.
+ //
+ free (Tmp);
+}
+
+#endif /* USE_MYALLOC */
+
+/* eof - MyAlloc.c */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.h
new file mode 100644
index 00000000..005f477b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/MyAlloc.h
@@ -0,0 +1,209 @@
+/** @file
+Header file for memory allocation tracking functions.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MYALLOC_H_
+#define _MYALLOC_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Common/BaseTypes.h>
+
+//
+// Default operation is to use the memory allocation tracking functions.
+// To over-ride add "#define USE_MYALLOC 0" to your program header and/or
+// source files as needed. Or, just do not include this header file in
+// your project.
+//
+#ifndef USE_MYALLOC
+#define USE_MYALLOC 1
+#endif
+
+#if USE_MYALLOC
+//
+// Replace C library allocation routines with MyAlloc routines.
+//
+#define malloc(size) MyAlloc ((size), __FILE__, __LINE__)
+#define calloc(count, size) MyAlloc ((count) * (size), __FILE__, __LINE__)
+#define realloc(ptr, size) MyRealloc ((ptr), (size), __FILE__, __LINE__)
+#define free(ptr) MyFree ((ptr), __FILE__, __LINE__)
+#define alloc_check(final) MyCheck ((final), __FILE__, __LINE__)
+
+//
+// Structure for checking/tracking memory allocations.
+//
+typedef struct MyAllocStruct {
+ UINTN Cksum;
+ struct MyAllocStruct *Next;
+ UINTN Line;
+ UINTN Size;
+ UINT8 *File;
+ UINT8 *Buffer;
+} MY_ALLOC_STRUCT;
+//
+// Cksum := (UINTN)This + (UINTN)Next + Line + Size + (UINTN)File +
+// (UINTN)Buffer;
+//
+// Next := Pointer to next allocation structure in the list.
+//
+// Line := __LINE__
+//
+// Size := Size of allocation request.
+//
+// File := Pointer to __FILE__ string stored immediately following
+// MY_ALLOC_STRUCT in memory.
+//
+// Buffer := Pointer to UINT32 aligned storage immediately following
+// the NULL terminated __FILE__ string. This is UINT32
+// aligned because the underflow signature is 32-bits and
+// this will place the first caller address on a 64-bit
+// boundary.
+//
+//
+// Signatures used to check for buffer overflow/underflow conditions.
+//
+#define MYALLOC_HEAD_MAGIK 0xBADFACED
+#define MYALLOC_TAIL_MAGIK 0xDEADBEEF
+
+VOID
+MyCheck (
+ BOOLEAN Final,
+ UINT8 File[],
+ UINTN Line
+ )
+;
+//
+// *++
+// Description:
+//
+// Check for corruptions in the allocated memory chain. If a corruption
+// is detection program operation stops w/ an exit(1) call.
+//
+// Parameters:
+//
+// Final := When FALSE, MyCheck() returns if the allocated memory chain
+// has not been corrupted. When TRUE, MyCheck() returns if there
+// are no un-freed allocations. If there are un-freed allocations,
+// they are displayed and exit(1) is called.
+//
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// n/a
+//
+// --*/
+//
+VOID *
+MyAlloc (
+ UINTN Size,
+ UINT8 File[],
+ UINTN Line
+ )
+;
+//
+// *++
+// Description:
+//
+// Allocate a new link in the allocation chain along with enough storage
+// for the File[] string, requested Size and alignment overhead. If
+// memory cannot be allocated or the allocation chain has been corrupted,
+// exit(1) will be called.
+//
+// Parameters:
+//
+// Size := Number of bytes (UINT8) requested by the called.
+// Size cannot be zero.
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// Pointer to the caller's buffer.
+//
+// --*/
+//
+VOID *
+MyRealloc (
+ VOID *Ptr,
+ UINTN Size,
+ UINT8 File[],
+ UINTN Line
+ )
+;
+//
+// *++
+// Description:
+//
+// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization
+// for shrinking or expanding buffers. An invalid parameter will cause
+// MyRealloc() to fail with a call to exit(1).
+//
+// Parameters:
+//
+// Ptr := Pointer to the caller's buffer to be re-allocated.
+// Ptr cannot be NULL.
+//
+// Size := Size of new buffer. Size cannot be zero.
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// Pointer to new caller's buffer.
+//
+// --*/
+//
+VOID
+MyFree (
+ VOID *Ptr,
+ UINT8 File[],
+ UINTN Line
+ )
+;
+//
+// *++
+// Description:
+//
+// Release a previously allocated buffer. Invalid parameters will cause
+// MyFree() to fail with an exit(1) call.
+//
+// Parameters:
+//
+// Ptr := Pointer to the caller's buffer to be freed.
+// A NULL pointer will be ignored.
+//
+// File := Set to __FILE__ by macro expansion.
+//
+// Line := Set to __LINE__ by macro expansion.
+//
+// Returns:
+//
+// n/a
+//
+// --*/
+//
+#else /* USE_MYALLOC */
+
+//
+// Nothing to do when USE_MYALLOC is zero.
+//
+#define alloc_check(final)
+
+#endif /* USE_MYALLOC */
+#endif /* _MYALLOC_H_ */
+
+/* eof - MyAlloc.h */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.c
new file mode 100644
index 00000000..04e1557d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.c
@@ -0,0 +1,295 @@
+/** @file
+Functions useful to operate file directories by parsing file path.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "CommonLib.h"
+#include "OsPath.h"
+
+//
+// Functions implementations
+//
+
+#if 0
+ //
+ // BUGBUG: Not fully implemented yet.
+ //
+CHAR8*
+OsPathDirName (
+ IN CHAR8 *FilePath
+ )
+/*++
+
+Routine Description:
+
+ This function returns the directory path which contains the particular path.
+ Some examples:
+ "a/b/c" -> "a/b"
+ "a/b/c/" -> "a/b"
+ "a" -> "."
+ "." -> ".."
+ "/" -> NULL
+
+ This function does not check for the existence of the file.
+
+ The caller must free the string returned.
+
+Arguments:
+
+ FilePath Path name of file to get the parent directory for.
+
+Returns:
+
+ NULL if error
+
+--*/
+{
+ CHAR8 *Return;
+ CHAR8 *Pos;
+ CHAR8 Char;
+ UINTN Length;
+ INTN Offset;
+
+ Length = strlen (FilePath);
+
+ if (Length == 0) {
+ return NULL;
+ }
+
+ //
+ // Check for the root directory case
+ //
+ if (
+ (Length == 3 && isalpha (FilePath[0]) && (strcmp(FilePath + 1, ":\\") == 0)) ||
+ (strcmp(FilePath, "/") == 0)
+ ) {
+ return NULL;
+ }
+
+ //
+ // If the path ends with a path separator, then just append ".."
+ //
+ Char = FilePath[Length - 1];
+ if (Char == '/' || Char == '\\') {
+ return OsPathJoin (FilePath, "..");
+ }
+
+ //
+ //
+ //
+ for (Offset = Length; Offset > 0; Offset--) {
+ if ((Return[Offset] == '/') || (Return[Offset] == '\\')) {
+ Return[Offset] = '\0';
+ return Return;
+ }
+ }
+}
+#endif
+
+
+#if 0
+ //
+ // BUGBUG: Not fully implemented yet.
+ //
+VOID
+OsPathNormPathInPlace (
+ IN CHAR8 *Path
+ )
+/*++
+
+Routine Description:
+
+ This function returns the directory path which contains the particular path.
+ Some examples:
+ "a/b/../c" -> "a/c"
+ "a/b//c" -> "a/b/c"
+ "a/./b" -> "a/b"
+
+ This function does not check for the existence of the file.
+
+Arguments:
+
+ Path Path name of file to normalize
+
+Returns:
+
+ The string is altered in place.
+
+--*/
+{
+ CHAR8 *Pos;
+ INTN Offset;
+ BOOLEAN TryAgain;
+ UINTN Length;
+ UINTN Remaining;
+ UINTN SubLength;
+
+ do {
+ TryAgain = FALSE;
+ Length = strlen (Path);
+
+ for (Offset = 0; Offset < Length; Offset++) {
+ Remaining = Length - Offset;
+
+ //
+ // Collapse '//' -> '/'
+ //
+ if (
+ (Remaining >= 2) &&
+ ((Offset > 0) || (Path[0] != '\\')) &&
+ IsDirSep (Path[Offset]) && IsDirSep (Path[Offset + 1])
+ ) {
+ memmove (&Path[Offset], &Path[Offset + 1], Remaining);
+ TryAgain = TRUE;
+ break;
+ }
+
+ //
+ // Collapse '/./' -> '/'
+ //
+ if ((Remaining >= 3) && IsDirSep (Path[Offset]) &&
+ (Path[Offset + 1] == '.') && IsDirSep (Path[Offset + 2])
+ ) {
+ memmove (&Path[Offset], &Path[Offset + 1], Remaining);
+ TryAgain = TRUE;
+ break;
+ }
+
+ //
+ // Collapse 'a/../b' -> 'b'
+ //
+ // BUGBUG: Not implemented yet
+
+ }
+
+ } while (TryAgain);
+
+ Return = CloneString (FilePath);
+ if (Return == NULL) {
+ return NULL;
+ }
+
+ Length = strlen (Return);
+
+ //
+ // Check for the root directory case
+ //
+ if (
+ (Length == 3 && isalpha (Return[0]) && (strcmp(Return + 1, ":\\") == 0)) ||
+ (strcmp(Return, "/") == 0)
+ ) {
+ free (Return);
+ return NULL;
+ }
+
+ //
+ //
+ //
+ for (Offset = Length; Offset > 0; Offset--) {
+ if ((Return[Offset] == '/') || (Return[Offset] == '\\')) {
+ Return[Offset] = '\0';
+ return Return;
+ }
+ }
+}
+#endif
+
+
+CHAR8*
+OsPathPeerFilePath (
+ IN CHAR8 *OldPath,
+ IN CHAR8 *Peer
+ )
+/*++
+
+Routine Description:
+
+ This function replaces the final portion of a path with an alternative
+ 'peer' filename. For example:
+ "a/b/../c", "peer" -> "a/b/../peer"
+ "a/b/", "peer" -> "a/b/peer"
+ "/a", "peer" -> "/peer"
+ "a", "peer" -> "peer"
+
+ This function does not check for the existence of the file.
+
+Arguments:
+
+ OldPath Path name of replace the final segment
+ Peer The new path name to concatenate to become the peer path
+
+Returns:
+
+ A CHAR8* string, which must be freed by the caller
+
+--*/
+{
+ CHAR8 *Result;
+ INTN Offset;
+
+ Result = (CHAR8 *) malloc (strlen (OldPath) + strlen (Peer) + 1);
+ if (Result == NULL) {
+ return NULL;
+ }
+
+ strcpy (Result, OldPath);
+
+ //
+ // Search for the last '/' or '\' in the string. If found, replace
+ // everything following it with Peer
+ //
+ for (Offset = strlen (Result); Offset >= 0; Offset--) {
+ if ((Result[Offset] == '/') || (Result[Offset] == '\\')) {
+ Result[Offset + 1] = '\0';
+ strcat (Result, Peer);
+ return Result;
+ }
+ }
+
+ //
+ // Neither a '/' nor a '\' was found. Therefore, we simply return Peer.
+ //
+ strcpy (Result, Peer);
+ return Result;
+}
+
+
+BOOLEAN
+OsPathExists (
+ IN CHAR8 *InputFileName
+ )
+/*++
+
+Routine Description:
+
+ Checks if a file exists
+
+Arguments:
+
+ InputFileName The name of the file to check for existence
+
+Returns:
+
+ TRUE The file exists
+ FALSE The file does not exist
+
+--*/
+{
+ FILE *InputFile;
+ InputFile = fopen (LongFilePath (InputFileName), "rb");
+ if (InputFile == NULL) {
+ return FALSE;
+ } else {
+ fclose (InputFile);
+ return TRUE;
+ }
+}
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.h
new file mode 100644
index 00000000..1b0640bd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/OsPath.h
@@ -0,0 +1,133 @@
+/** @file
+Header file for helper functions useful to operate file directories by parsing
+file path.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_OS_PATH_H
+#define _EFI_OS_PATH_H
+
+#include <Common/UefiBaseTypes.h>
+
+//
+// Functions declarations
+//
+
+CHAR8*
+OsPathDirName (
+ IN CHAR8 *FilePath
+ )
+;
+/**
+
+Routine Description:
+
+ This function returns the directory path which contains the particular path.
+ Some examples:
+ "a/b/c" -> "a/b"
+ "a/b/c/" -> "a/b"
+ "a" -> "."
+ "." -> ".."
+ "/" -> NULL
+
+ This function does not check for the existence of the file.
+
+ The caller must free the string returned.
+
+Arguments:
+
+ FilePath Path name of file to get the parent directory for.
+
+Returns:
+
+ NULL if error
+
+**/
+
+
+VOID
+OsPathNormPathInPlace (
+ IN CHAR8 *Path
+ )
+;
+/**
+
+Routine Description:
+
+ This function returns the directory path which contains the particular path.
+ Some examples:
+ "a/b/../c" -> "a/c"
+ "a/b//c" -> "a/b/c"
+ "a/./b" -> "a/b"
+
+ This function does not check for the existence of the file.
+
+Arguments:
+
+ Path Path name of file to normalize
+
+Returns:
+
+ The string is altered in place.
+
+**/
+
+
+CHAR8*
+OsPathPeerFilePath (
+ IN CHAR8 *OldPath,
+ IN CHAR8 *Peer
+ )
+;
+/**
+
+Routine Description:
+
+ This function replaces the final portion of a path with an alternative
+ 'peer' filename. For example:
+ "a/b/../c", "peer" -> "a/b/../peer"
+ "a/b/", "peer" -> "a/b/peer"
+ "/a", "peer" -> "/peer"
+ "a", "peer" -> "peer"
+
+ This function does not check for the existence of the file.
+
+Arguments:
+
+ OldPath Path name of replace the final segment
+ Peer The new path name to concatenate to become the peer path
+
+Returns:
+
+ A CHAR8* string, which must be freed by the caller
+
+**/
+
+
+BOOLEAN
+OsPathExists (
+ IN CHAR8 *InputFileName
+ )
+;
+/**
+
+Routine Description:
+
+ Checks if a file exists
+
+Arguments:
+
+ InputFileName The name of the file to check for existence
+
+Returns:
+
+ TRUE The file exists
+ FALSE The file does not exist
+
+**/
+
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.c
new file mode 100644
index 00000000..f8b8f061
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.c
@@ -0,0 +1,205 @@
+/** @file
+Helper functions for parsing GuidedSectionTools.txt
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "MemoryFile.h"
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include "ParseGuidedSectionTools.h"
+#include "StringFuncs.h"
+
+
+//
+// Local types / structures
+//
+
+typedef struct _GUID_SEC_TOOL_ENTRY {
+ EFI_GUID Guid;
+ CHAR8* Name;
+ CHAR8* Path;
+ struct _GUID_SEC_TOOL_ENTRY *Next;
+} GUID_SEC_TOOL_ENTRY;
+
+//
+// Function Implementation
+//
+
+EFI_HANDLE
+ParseGuidedSectionToolsFile (
+ IN CHAR8 *InputFile
+ )
+/*++
+
+Routine Description:
+
+ This function parses the tools_def.txt file. It returns a
+ EFI_HANDLE object which can be used for the other library
+ functions and should be passed to FreeParsedGuidedSectionToolsHandle
+ to free resources when the tools_def.txt information is no
+ longer needed.
+
+Arguments:
+
+ InputFile Path name of file to read
+
+Returns:
+
+ NULL if error parsing
+ A non-NULL EFI_HANDLE otherwise
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE MemoryFile;
+ EFI_HANDLE ParsedGuidedSectionTools;
+
+ Status = GetMemoryFile (InputFile, &MemoryFile);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ ParsedGuidedSectionTools = ParseGuidedSectionToolsMemoryFile (MemoryFile);
+
+ FreeMemoryFile (MemoryFile);
+
+ return ParsedGuidedSectionTools;
+}
+
+
+EFI_HANDLE
+ParseGuidedSectionToolsMemoryFile (
+ IN EFI_HANDLE InputFile
+ )
+/*++
+
+Routine Description:
+
+ This function parses the tools_def.txt file. It returns a
+ EFI_HANDLE object which can be used for the other library
+ functions and should be passed to FreeParsedGuidedSectionToolsHandle
+ to free resources when the tools_def.txt information is no
+ longer needed.
+
+Arguments:
+
+ InputFile Memory file image.
+
+Returns:
+
+ NULL if error or EOF
+ InputBuffer otherwise
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *NextLine;
+ STRING_LIST *Tool;
+ EFI_GUID Guid;
+ GUID_SEC_TOOL_ENTRY *FirstGuidTool;
+ GUID_SEC_TOOL_ENTRY *LastGuidTool;
+ GUID_SEC_TOOL_ENTRY *NewGuidTool;
+
+ FirstGuidTool = NULL;
+ LastGuidTool = NULL;
+
+ while (TRUE) {
+ NextLine = ReadMemoryFileLine (InputFile);
+ if (NextLine == NULL) {
+ break;
+ }
+
+ Status = StripInfDscStringInPlace (NextLine);
+ if (EFI_ERROR (Status)) {
+ free (NextLine);
+ break;
+ }
+
+ if (NextLine[0] == '\0') {
+ free (NextLine);
+ continue;
+ }
+
+ Tool = SplitStringByWhitespace (NextLine);
+ if ((Tool != NULL) &&
+ (Tool->Count == 3)
+ ) {
+ Status = StringToGuid (Tool->Strings[0], &Guid);
+ if (!EFI_ERROR (Status)) {
+ NewGuidTool = malloc (sizeof (GUID_SEC_TOOL_ENTRY));
+ if (NewGuidTool != NULL) {
+ memcpy (&(NewGuidTool->Guid), &Guid, sizeof (Guid));
+ NewGuidTool->Name = CloneString(Tool->Strings[1]);
+ NewGuidTool->Path = CloneString(Tool->Strings[2]);
+ NewGuidTool->Next = NULL;
+
+ if (FirstGuidTool == NULL) {
+ FirstGuidTool = NewGuidTool;
+ } else {
+ LastGuidTool->Next = NewGuidTool;
+ }
+ LastGuidTool = NewGuidTool;
+ }
+ }
+ }
+
+ if (Tool != NULL) {
+ FreeStringList (Tool);
+ }
+ free (NextLine);
+ }
+
+ return FirstGuidTool;
+}
+
+
+CHAR8*
+LookupGuidedSectionToolPath (
+ IN EFI_HANDLE ParsedGuidedSectionToolsHandle,
+ IN EFI_GUID *SectionGuid
+ )
+/*++
+
+Routine Description:
+
+ This function looks up the appropriate tool to use for extracting
+ a GUID defined FV section.
+
+Arguments:
+
+ ParsedGuidedSectionToolsHandle A parsed GUID section tools handle.
+ SectionGuid The GUID for the section.
+
+Returns:
+
+ NULL - if no tool is found or there is another error
+ Non-NULL - The tool to use to access the section contents. (The caller
+ must free the memory associated with this string.)
+
+--*/
+{
+ GUID_SEC_TOOL_ENTRY *GuidTool;
+
+ GuidTool = (GUID_SEC_TOOL_ENTRY*)ParsedGuidedSectionToolsHandle;
+ if (GuidTool == NULL) {
+ return NULL;
+ }
+
+ for ( ; GuidTool != NULL; GuidTool = GuidTool->Next) {
+ if (CompareGuid (&(GuidTool->Guid), SectionGuid) == 0) {
+ return CloneString (GuidTool->Path);
+ }
+ }
+
+ return NULL;
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.h
new file mode 100644
index 00000000..6b7bf1a7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseGuidedSectionTools.h
@@ -0,0 +1,120 @@
+/** @file
+Header file for helper functions for parsing GuidedSectionTools.txt
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_PARSE_GUIDED_SECTION_TOOLS_H
+#define _EFI_PARSE_GUIDED_SECTION_TOOLS_H
+
+#include <Common/UefiBaseTypes.h>
+
+//
+// Functions declarations
+//
+
+EFI_HANDLE
+ParseGuidedSectionToolsFile (
+ IN CHAR8 *InputFile
+ )
+;
+/**
+
+Routine Description:
+
+ This function parses the tools_def.txt file. It returns a
+ EFI_HANDLE object which can be used for the other library
+ functions and should be passed to FreeParsedToolsDefHandle
+ to free resources when the tools_def.txt information is no
+ longer needed.
+
+Arguments:
+
+ InputFile Path name of file to read
+
+Returns:
+
+ NULL if error parsing
+ A non-NULL EFI_HANDLE otherwise
+
+**/
+
+
+EFI_HANDLE
+ParseGuidedSectionToolsMemoryFile (
+ IN EFI_HANDLE InputFile
+ )
+;
+/**
+
+Routine Description:
+
+ This function parses the tools_def.txt file. It returns a
+ EFI_HANDLE object which can be used for the other library
+ functions and should be passed to FreeParsedToolsDefHandle
+ to free resources when the tools_def.txt information is no
+ longer needed.
+
+Arguments:
+
+ InputFile Memory file image.
+
+Returns:
+
+ NULL if error parsing
+ A non-NULL EFI_HANDLE otherwise
+
+**/
+
+CHAR8*
+LookupGuidedSectionToolPath (
+ IN EFI_HANDLE ParsedGuidedSectionToolsHandle,
+ IN EFI_GUID *SectionGuid
+ )
+;
+/**
+
+Routine Description:
+
+ This function looks up the appropriate tool to use for extracting
+ a GUID defined FV section.
+
+Arguments:
+
+ ParsedGuidedSectionToolsHandle A parsed GUID section tools handle.
+ SectionGuid The GUID for the section.
+
+Returns:
+
+ NULL - if no tool is found or there is another error
+ Non-NULL - The tool to use to access the section contents. (The caller
+ must free the memory associated with this string.)
+
+**/
+
+EFI_STATUS
+FreeParsedGuidedSectionToolsHandle (
+ IN EFI_HANDLE ParsedGuidedSectionToolsHandle
+ )
+;
+/**
+
+Routine Description:
+
+ Frees resources that were allocated by ParseGuidedSectionToolsFile.
+ After freeing these resources, the information that was parsed
+ is no longer accessible.
+
+Arguments:
+
+ ParsedToolDefHandle Handle returned from ParseGuidedSectionToolsFile
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.c
new file mode 100644
index 00000000..cc0b04ad
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.c
@@ -0,0 +1,695 @@
+/** @file
+This contains some useful functions for parsing INF files.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include "CommonLib.h"
+
+CHAR8 *
+ReadLine (
+ IN MEMORY_FILE *InputFile,
+ IN OUT CHAR8 *InputBuffer,
+ IN UINTN MaxLength
+ )
+/*++
+
+Routine Description:
+
+ This function reads a line, stripping any comments.
+ The function reads a string from the input stream argument and stores it in
+ the input string. ReadLine reads characters from the current file position
+ to and including the first newline character, to the end of the stream, or
+ until the number of characters read is equal to MaxLength - 1, whichever
+ comes first. The newline character, if read, is replaced with a \0.
+
+Arguments:
+
+ InputFile Memory file image.
+ InputBuffer Buffer to read into, must be MaxLength size.
+ MaxLength The maximum size of the input buffer.
+
+Returns:
+
+ NULL if error or EOF
+ InputBuffer otherwise
+
+--*/
+{
+ CHAR8 *CharPtr;
+ CHAR8 *EndOfLine;
+ UINTN CharsToCopy;
+
+ //
+ // Verify input parameters are not null
+ //
+ assert (InputBuffer);
+ assert (InputFile->FileImage);
+ assert (InputFile->Eof);
+ assert (InputFile->CurrentFilePointer);
+
+ //
+ // Check for end of file condition
+ //
+ if (InputFile->CurrentFilePointer >= InputFile->Eof) {
+ return NULL;
+ }
+ //
+ // Find the next newline char
+ //
+ EndOfLine = strchr (InputFile->CurrentFilePointer, '\n');
+
+ //
+ // Determine the number of characters to copy.
+ //
+ if (EndOfLine == 0) {
+ //
+ // If no newline found, copy to the end of the file.
+ //
+ CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
+ } else if (EndOfLine >= InputFile->Eof) {
+ //
+ // If the newline found was beyond the end of file, copy to the eof.
+ //
+ CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;
+ } else {
+ //
+ // Newline found in the file.
+ //
+ CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;
+ }
+ //
+ // If the end of line is too big for the current buffer, set it to the max
+ // size of the buffer (leaving room for the \0.
+ //
+ if (CharsToCopy > MaxLength - 1) {
+ CharsToCopy = MaxLength - 1;
+ }
+ //
+ // Copy the line.
+ //
+ memcpy (InputBuffer, InputFile->CurrentFilePointer, CharsToCopy);
+
+ //
+ // Add the null termination over the 0x0D
+ //
+ if (InputBuffer[CharsToCopy - 1] == '\r') {
+
+ InputBuffer[CharsToCopy - 1] = '\0';
+
+ } else {
+
+ InputBuffer[CharsToCopy] = '\0';
+
+ }
+
+ //
+ // Increment the current file pointer (include the 0x0A)
+ //
+ InputFile->CurrentFilePointer += CharsToCopy + 1;
+
+ //
+ // Strip any comments
+ //
+ CharPtr = strstr (InputBuffer, "//");
+ if (CharPtr != 0) {
+ CharPtr[0] = 0;
+ }
+ //
+ // Return the string
+ //
+ return InputBuffer;
+}
+
+BOOLEAN
+FindSection (
+ IN MEMORY_FILE *InputFile,
+ IN CHAR8 *Section
+ )
+/*++
+
+Routine Description:
+
+ This function parses a file from the beginning to find a section.
+ The section string may be anywhere within a line.
+
+Arguments:
+
+ InputFile Memory file image.
+ Section Section to search for
+
+Returns:
+
+ FALSE if error or EOF
+ TRUE if section found
+
+--*/
+{
+ CHAR8 InputBuffer[MAX_LONG_FILE_PATH];
+ CHAR8 *CurrentToken;
+
+ //
+ // Verify input is not NULL
+ //
+ assert (InputFile->FileImage);
+ assert (InputFile->Eof);
+ assert (InputFile->CurrentFilePointer);
+ assert (Section);
+
+ //
+ // Rewind to beginning of file
+ //
+ InputFile->CurrentFilePointer = InputFile->FileImage;
+
+ //
+ // Read lines until the section is found
+ //
+ while (InputFile->CurrentFilePointer < InputFile->Eof) {
+ //
+ // Read a line
+ //
+ ReadLine (InputFile, InputBuffer, MAX_LONG_FILE_PATH);
+
+ //
+ // Check if the section is found
+ //
+ CurrentToken = strstr (InputBuffer, Section);
+ if (CurrentToken != NULL) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+FindToken (
+ IN MEMORY_FILE *InputFile,
+ IN CHAR8 *Section,
+ IN CHAR8 *Token,
+ IN UINTN Instance,
+ OUT CHAR8 *Value
+ )
+/*++
+
+Routine Description:
+
+ Finds a token value given the section and token to search for.
+
+Arguments:
+
+ InputFile Memory file image.
+ Section The section to search for, a string within [].
+ Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
+ Instance The instance of the token to search for. Zero is the first instance.
+ Value The string that holds the value following the =. Must be MAX_LONG_FILE_PATH in size.
+
+Returns:
+
+ EFI_SUCCESS Value found.
+ EFI_ABORTED Format error detected in INF file.
+ EFI_INVALID_PARAMETER Input argument was null.
+ EFI_LOAD_ERROR Error reading from the file.
+ EFI_NOT_FOUND Section/Token/Value not found.
+
+--*/
+{
+ CHAR8 InputBuffer[MAX_LONG_FILE_PATH];
+ CHAR8 *CurrentToken;
+ CHAR8 *Delimiter;
+ BOOLEAN ParseError;
+ BOOLEAN ReadError;
+ UINTN Occurrence;
+
+ //
+ // Check input parameters
+ //
+ if (InputFile->FileImage == NULL ||
+ InputFile->Eof == NULL ||
+ InputFile->CurrentFilePointer == NULL ||
+ Section == NULL ||
+ strlen (Section) == 0 ||
+ Token == NULL ||
+ strlen (Token) == 0 ||
+ Value == NULL
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Initialize error codes
+ //
+ ParseError = FALSE;
+ ReadError = FALSE;
+
+ //
+ // Initialize our instance counter for the search token
+ //
+ Occurrence = 0;
+
+ if (FindSection (InputFile, Section)) {
+ //
+ // Found the desired section, find and read the desired token
+ //
+ do {
+ //
+ // Read a line from the file
+ //
+ if (ReadLine (InputFile, InputBuffer, MAX_LONG_FILE_PATH) == NULL) {
+ //
+ // Error reading from input file
+ //
+ ReadError = TRUE;
+ break;
+ }
+ //
+ // Get the first non-whitespace string
+ //
+ Delimiter = strchr (InputBuffer, '=');
+ if (Delimiter != NULL) {
+ *Delimiter = 0;
+ }
+
+ CurrentToken = strtok (InputBuffer, " \t\n");
+ if (CurrentToken == NULL || Delimiter == NULL) {
+ //
+ // Whitespace line found (or comment) so continue
+ //
+ CurrentToken = InputBuffer;
+ continue;
+ }
+ //
+ // Make sure we have not reached the end of the current section
+ //
+ if (CurrentToken[0] == '[') {
+ break;
+ }
+ //
+ // Compare the current token with the desired token
+ //
+ if (strcmp (CurrentToken, Token) == 0) {
+ //
+ // Found it
+ //
+ //
+ // Check if it is the correct instance
+ //
+ if (Instance == Occurrence) {
+ //
+ // Copy the contents following the =
+ //
+ CurrentToken = Delimiter + 1;
+ if (*CurrentToken == 0) {
+ //
+ // Nothing found, parsing error
+ //
+ ParseError = TRUE;
+ } else {
+ //
+ // Strip leading white space
+ //
+ while (*CurrentToken == ' ' || *CurrentToken == '\t') {
+ CurrentToken++;
+ }
+ //
+ // Copy the current token to the output value
+ //
+ strcpy (Value, CurrentToken);
+ //
+ // Strip trailing white space
+ //
+ while (strlen(Value) > 0 && (*(Value + strlen(Value) - 1) == ' ' || *(Value + strlen(Value) - 1) == '\t')) {
+ *(Value + strlen(Value) - 1) = 0;
+ }
+ return EFI_SUCCESS;
+ }
+ } else {
+ //
+ // Increment the occurrence found
+ //
+ Occurrence++;
+ }
+ }
+ } while (
+ !ParseError &&
+ !ReadError &&
+ InputFile->CurrentFilePointer < InputFile->Eof &&
+ CurrentToken[0] != '[' &&
+ Occurrence <= Instance
+ );
+ }
+ //
+ // Distinguish between read errors and INF file format errors.
+ //
+ if (ReadError) {
+ return EFI_LOAD_ERROR;
+ }
+
+ if (ParseError) {
+ return EFI_ABORTED;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+StringToGuid (
+ IN CHAR8 *AsciiGuidBuffer,
+ OUT EFI_GUID *GuidBuffer
+ )
+/*++
+
+Routine Description:
+
+ Converts a string to an EFI_GUID. The string must be in the
+ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
+
+Arguments:
+
+ AsciiGuidBuffer - pointer to ascii string
+ GuidBuffer - pointer to destination Guid
+
+Returns:
+
+ EFI_ABORTED Could not convert the string
+ EFI_SUCCESS The string was successfully converted
+ EFI_INVALID_PARAMETER Input parameter is invalid.
+
+--*/
+{
+ INT32 Index;
+ int Data1;
+ int Data2;
+ int Data3;
+ int Data4[8];
+
+ if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Check Guid Format strictly xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ //
+ for (Index = 0; AsciiGuidBuffer[Index] != '\0' && Index < 37; Index ++) {
+ if (Index == 8 || Index == 13 || Index == 18 || Index == 23) {
+ if (AsciiGuidBuffer[Index] != '-') {
+ break;
+ }
+ } else {
+ if (((AsciiGuidBuffer[Index] >= '0') && (AsciiGuidBuffer[Index] <= '9')) ||
+ ((AsciiGuidBuffer[Index] >= 'a') && (AsciiGuidBuffer[Index] <= 'f')) ||
+ ((AsciiGuidBuffer[Index] >= 'A') && (AsciiGuidBuffer[Index] <= 'F'))) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (Index < 36 || AsciiGuidBuffer[36] != '\0') {
+ Error (NULL, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Scan the guid string into the buffer
+ //
+ Index = sscanf (
+ AsciiGuidBuffer,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ &Data1,
+ &Data2,
+ &Data3,
+ &Data4[0],
+ &Data4[1],
+ &Data4[2],
+ &Data4[3],
+ &Data4[4],
+ &Data4[5],
+ &Data4[6],
+ &Data4[7]
+ );
+
+ //
+ // Verify the correct number of items were scanned.
+ //
+ if (Index != 11) {
+ Error (NULL, 0, 1003, "Invalid option value", "Incorrect GUID \"%s\"\n Correct Format \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", AsciiGuidBuffer);
+ return EFI_ABORTED;
+ }
+ //
+ // Copy the data into our GUID.
+ //
+ GuidBuffer->Data1 = (UINT32) Data1;
+ GuidBuffer->Data2 = (UINT16) Data2;
+ GuidBuffer->Data3 = (UINT16) Data3;
+ GuidBuffer->Data4[0] = (UINT8) Data4[0];
+ GuidBuffer->Data4[1] = (UINT8) Data4[1];
+ GuidBuffer->Data4[2] = (UINT8) Data4[2];
+ GuidBuffer->Data4[3] = (UINT8) Data4[3];
+ GuidBuffer->Data4[4] = (UINT8) Data4[4];
+ GuidBuffer->Data4[5] = (UINT8) Data4[5];
+ GuidBuffer->Data4[6] = (UINT8) Data4[6];
+ GuidBuffer->Data4[7] = (UINT8) Data4[7];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AsciiStringToUint64 (
+ IN CONST CHAR8 *AsciiString,
+ IN BOOLEAN IsHex,
+ OUT UINT64 *ReturnValue
+ )
+/*++
+
+Routine Description:
+
+ Converts a null terminated ascii string that represents a number into a
+ UINT64 value. A hex number may be preceded by a 0x, but may not be
+ succeeded by an h. A number without 0x or 0X is considered to be base 10
+ unless the IsHex input is true.
+
+Arguments:
+
+ AsciiString The string to convert.
+ IsHex Force the string to be treated as a hex number.
+ ReturnValue The return value.
+
+Returns:
+
+ EFI_SUCCESS Number successfully converted.
+ EFI_ABORTED Invalid character encountered.
+
+--*/
+{
+ UINT8 Index;
+ UINT64 Value;
+ CHAR8 CurrentChar;
+
+ //
+ // Initialize the result
+ //
+ Value = 0;
+ Index = 0;
+
+ //
+ // Check input parameter
+ //
+ if (AsciiString == NULL || ReturnValue == NULL || strlen(AsciiString) > 0xFF) {
+ return EFI_INVALID_PARAMETER;
+ }
+ while (AsciiString[Index] == ' ') {
+ Index ++;
+ }
+
+ //
+ // Add each character to the result
+ //
+
+ //
+ // Skip first two chars only if the string starts with '0x' or '0X'
+ //
+ if (AsciiString[Index] == '0' && (AsciiString[Index + 1] == 'x' || AsciiString[Index + 1] == 'X')) {
+ IsHex = TRUE;
+ Index += 2;
+ }
+ if (IsHex) {
+ //
+ // Convert the hex string.
+ //
+ for (; AsciiString[Index] != '\0'; Index++) {
+ CurrentChar = AsciiString[Index];
+ if (CurrentChar == ' ') {
+ break;
+ }
+ //
+ // Verify Hex string
+ //
+ if (isxdigit ((int)CurrentChar) == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Add hex value
+ //
+ Value *= 16;
+ if (CurrentChar >= '0' && CurrentChar <= '9') {
+ Value += CurrentChar - '0';
+ } else if (CurrentChar >= 'a' && CurrentChar <= 'f') {
+ Value += CurrentChar - 'a' + 10;
+ } else if (CurrentChar >= 'A' && CurrentChar <= 'F') {
+ Value += CurrentChar - 'A' + 10;
+ }
+ }
+
+ *ReturnValue = Value;
+ } else {
+ //
+ // Convert dec string is a number
+ //
+ for (; Index < strlen (AsciiString); Index++) {
+ CurrentChar = AsciiString[Index];
+ if (CurrentChar == ' ') {
+ break;
+ }
+ //
+ // Verify Dec string
+ //
+ if (isdigit ((int)CurrentChar) == 0) {
+ return EFI_ABORTED;
+ }
+ //
+ // Add dec value
+ //
+ Value = Value * 10;
+ Value += CurrentChar - '0';
+ }
+
+ *ReturnValue = Value;
+ }
+
+ return EFI_SUCCESS;
+}
+
+CHAR8 *
+ReadLineInStream (
+ IN FILE *InputFile,
+ IN OUT CHAR8 *InputBuffer
+ )
+/*++
+
+Routine Description:
+
+ This function reads a line, stripping any comments.
+ // BUGBUG: This is obsolete once genmake goes away...
+
+Arguments:
+
+ InputFile Stream pointer.
+ InputBuffer Buffer to read into, must be MAX_LONG_FILE_PATH size.
+
+Returns:
+
+ NULL if error or EOF
+ InputBuffer otherwise
+
+--*/
+{
+ CHAR8 *CharPtr;
+
+ //
+ // Verify input parameters are not null
+ //
+ assert (InputFile);
+ assert (InputBuffer);
+
+ //
+ // Read a line
+ //
+ if (fgets (InputBuffer, MAX_LONG_FILE_PATH, InputFile) == NULL) {
+ return NULL;
+ }
+ //
+ // Strip any comments
+ //
+ CharPtr = strstr (InputBuffer, "//");
+ if (CharPtr != 0) {
+ CharPtr[0] = 0;
+ }
+
+ CharPtr = strstr (InputBuffer, "#");
+ if (CharPtr != 0) {
+ CharPtr[0] = 0;
+ }
+ //
+ // Return the string
+ //
+ return InputBuffer;
+}
+
+BOOLEAN
+FindSectionInStream (
+ IN FILE *InputFile,
+ IN CHAR8 *Section
+ )
+/*++
+
+Routine Description:
+
+ This function parses a stream file from the beginning to find a section.
+ The section string may be anywhere within a line.
+ // BUGBUG: This is obsolete once genmake goes away...
+
+Arguments:
+
+ InputFile Stream pointer.
+ Section Section to search for
+
+Returns:
+
+ FALSE if error or EOF
+ TRUE if section found
+
+--*/
+{
+ CHAR8 InputBuffer[MAX_LONG_FILE_PATH];
+ CHAR8 *CurrentToken;
+
+ //
+ // Verify input is not NULL
+ //
+ assert (InputFile);
+ assert (Section);
+
+ //
+ // Rewind to beginning of file
+ //
+ if (fseek (InputFile, 0, SEEK_SET) != 0) {
+ return FALSE;
+ }
+ //
+ // Read lines until the section is found
+ //
+ while (feof (InputFile) == 0) {
+ //
+ // Read a line
+ //
+ ReadLineInStream (InputFile, InputBuffer);
+
+ //
+ // Check if the section is found
+ //
+ CurrentToken = strstr (InputBuffer, Section);
+ if (CurrentToken != NULL) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.h
new file mode 100644
index 00000000..69c92cc1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/ParseInf.h
@@ -0,0 +1,220 @@
+/** @file
+Header file for helper functions useful for parsing INF files.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_PARSE_INF_H
+#define _EFI_PARSE_INF_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Common/UefiBaseTypes.h>
+#include <MemoryFile.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+//
+// Functions declarations
+//
+CHAR8 *
+ReadLine (
+ IN MEMORY_FILE *InputFile,
+ IN OUT CHAR8 *InputBuffer,
+ IN UINTN MaxLength
+ )
+;
+
+/*++
+
+Routine Description:
+
+ This function reads a line, stripping any comments.
+ The function reads a string from the input stream argument and stores it in
+ the input string. ReadLine reads characters from the current file position
+ to and including the first newline character, to the end of the stream, or
+ until the number of characters read is equal to MaxLength - 1, whichever
+ comes first. The newline character, if read, is replaced with a \0.
+
+Arguments:
+
+ InputFile Memory file image.
+ InputBuffer Buffer to read into, must be MaxLength size.
+ MaxLength The maximum size of the input buffer.
+
+Returns:
+
+ NULL if error or EOF
+ InputBuffer otherwise
+
+--*/
+BOOLEAN
+FindSection (
+ IN MEMORY_FILE *InputFile,
+ IN CHAR8 *Section
+ )
+;
+
+/*++
+
+Routine Description:
+
+ This function parses a file from the beginning to find a section.
+ The section string may be anywhere within a line.
+
+Arguments:
+
+ InputFile Memory file image.
+ Section Section to search for
+
+Returns:
+
+ FALSE if error or EOF
+ TRUE if section found
+
+--*/
+EFI_STATUS
+FindToken (
+ IN MEMORY_FILE *InputFile,
+ IN CHAR8 *Section,
+ IN CHAR8 *Token,
+ IN UINTN Instance,
+ OUT CHAR8 *Value
+ )
+;
+
+/*++
+
+Routine Description:
+
+ Finds a token value given the section and token to search for.
+
+Arguments:
+
+ InputFile Memory file image.
+ Section The section to search for, a string within [].
+ Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.
+ Instance The instance of the token to search for. Zero is the first instance.
+ Value The string that holds the value following the =. Must be MAX_LONG_FILE_PATH in size.
+
+Returns:
+
+ EFI_SUCCESS Value found.
+ EFI_ABORTED Format error detected in INF file.
+ EFI_INVALID_PARAMETER Input argument was null.
+ EFI_LOAD_ERROR Error reading from the file.
+ EFI_NOT_FOUND Section/Token/Value not found.
+
+--*/
+EFI_STATUS
+StringToGuid (
+ IN CHAR8 *AsciiGuidBuffer,
+ OUT EFI_GUID *GuidBuffer
+ )
+;
+
+/*++
+
+Routine Description:
+
+ Converts a string to an EFI_GUID. The string must be in the
+ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.
+
+Arguments:
+
+ GuidBuffer - pointer to destination Guid
+ AsciiGuidBuffer - pointer to ascii string
+
+Returns:
+
+ EFI_ABORTED Could not convert the string
+ EFI_SUCCESS The string was successfully converted
+
+--*/
+EFI_STATUS
+AsciiStringToUint64 (
+ IN CONST CHAR8 *AsciiString,
+ IN BOOLEAN IsHex,
+ OUT UINT64 *ReturnValue
+ )
+;
+
+/*++
+
+Routine Description:
+
+ Converts a null terminated ascii string that represents a number into a
+ UINT64 value. A hex number may be preceded by a 0x, but may not be
+ succeeded by an h. A number without 0x or 0X is considered to be base 10
+ unless the IsHex input is true.
+
+Arguments:
+
+ AsciiString The string to convert.
+ IsHex Force the string to be treated as a hex number.
+ ReturnValue The return value.
+
+Returns:
+
+ EFI_SUCCESS Number successfully converted.
+ EFI_ABORTED Invalid character encountered.
+
+--*/
+CHAR8 *
+ReadLineInStream (
+ IN FILE *InputFile,
+ IN OUT CHAR8 *InputBuffer
+ )
+;
+
+/*++
+
+Routine Description:
+
+ This function reads a line, stripping any comments.
+
+Arguments:
+
+ InputFile Stream pointer.
+ InputBuffer Buffer to read into, must be MAX_LONG_FILE_PATH size.
+
+Returns:
+
+ NULL if error or EOF
+ InputBuffer otherwise
+
+--*/
+BOOLEAN
+FindSectionInStream (
+ IN FILE *InputFile,
+ IN CHAR8 *Section
+ )
+;
+
+/*++
+
+Routine Description:
+
+ This function parses a stream file from the beginning to find a section.
+ The section string may be anywhere within a line.
+
+Arguments:
+
+ InputFile Stream pointer.
+ Section Section to search for
+
+Returns:
+
+ FALSE if error or EOF
+ TRUE if section found
+
+--*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.c
new file mode 100644
index 00000000..de3b7446
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.c
@@ -0,0 +1,779 @@
+/** @file
+This file contains the PcdValue structure definition.
+
+Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "CommonLib.h"
+#include "PcdValueCommon.h"
+
+typedef enum {
+ PcdDataTypeBoolean,
+ PcdDataTypeUint8,
+ PcdDataTypeUint16,
+ PcdDataTypeUint32,
+ PcdDataTypeUint64,
+ PcdDataTypePointer
+} PCD_DATA_TYPE;
+
+typedef struct {
+ CHAR8 *SkuName;
+ CHAR8 *DefaultValueName;
+ CHAR8 *TokenSpaceGuidName;
+ CHAR8 *TokenName;
+ CHAR8 *DataType;
+ CHAR8 *Value;
+ PCD_DATA_TYPE PcdDataType;
+} PCD_ENTRY;
+
+PCD_ENTRY *PcdList;
+UINT32 PcdListLength;
+
+VOID
+STATIC
+RecordToken (
+ UINT8 *FileBuffer,
+ UINT32 PcdIndex,
+ UINT32 TokenIndex,
+ UINT32 TokenStart,
+ UINT32 TokenEnd
+ )
+/*++
+
+Routine Description:
+
+ Record new token information
+
+Arguments:
+
+ FileBuffer File Buffer to be record
+ PcdIndex Index of PCD in database
+ TokenIndex Index of Token
+ TokenStart Start of Token
+ TokenEnd End of Token
+
+Returns:
+
+ None
+--*/
+{
+ CHAR8 *Token;
+
+ Token = malloc (TokenEnd - TokenStart + 1);
+ if (Token == NULL) {
+ return;
+ }
+ memcpy (Token, &FileBuffer[TokenStart], TokenEnd - TokenStart);
+ Token[TokenEnd - TokenStart] = 0;
+ switch (TokenIndex) {
+ case 0:
+ PcdList[PcdIndex].SkuName = Token;
+ break;
+ case 1:
+ PcdList[PcdIndex].DefaultValueName = Token;
+ break;
+ case 2:
+ PcdList[PcdIndex].TokenSpaceGuidName = Token;
+ break;
+ case 3:
+ PcdList[PcdIndex].TokenName = Token;
+ break;
+ case 4:
+ PcdList[PcdIndex].DataType = Token;
+ if (strcmp (Token, "BOOLEAN") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeBoolean;
+ } else if (strcmp (Token, "UINT8") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint8;
+ } else if (strcmp (Token, "UINT16") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint16;
+ } else if (strcmp (Token, "UINT32") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint32;
+ } else if (strcmp (Token, "UINT64") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint64;
+ } else {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypePointer;
+ }
+ break;
+ case 5:
+ PcdList[PcdIndex].Value = Token;
+ break;
+ default:
+ free (Token);
+ break;
+ }
+}
+
+int
+STATIC
+LookupPcdIndex (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName
+ )
+/*++
+
+Routine Description:
+
+ Get PCD index in Pcd database
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+
+Returns:
+
+ Index of PCD in Pcd database
+--*/
+{
+ UINT32 Index;
+
+ if (SkuName == NULL) {
+ SkuName = "DEFAULT";
+ }
+ if (DefaultValueName == NULL) {
+ DefaultValueName = "DEFAULT";
+ }
+ for (Index = 0; Index < PcdListLength; Index++) {
+ if (strcmp(PcdList[Index].TokenSpaceGuidName, TokenSpaceGuidName) != 0) {
+ continue;
+ }
+ if (strcmp(PcdList[Index].TokenName, TokenName) != 0) {
+ continue;
+ }
+ if (strcmp(PcdList[Index].SkuName, SkuName) != 0) {
+ continue;
+ }
+ if (strcmp(PcdList[Index].DefaultValueName, DefaultValueName) != 0) {
+ continue;
+ }
+ return Index;
+ }
+ return -1;
+}
+
+UINT64
+__PcdGet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName
+ )
+/*++
+
+Routine Description:
+
+ Get PCD value
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+
+Returns:
+
+ PCD value
+--*/
+{
+ int Index;
+ CHAR8 *End;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ case PcdDataTypeUint8:
+ case PcdDataTypeUint16:
+ case PcdDataTypeUint32:
+ return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
+ break;
+ case PcdDataTypeUint64:
+ return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
+ break;
+ case PcdDataTypePointer:
+ fprintf (stderr, "PCD %s.%s.%s.%s is structure. Use PcdGetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ }
+ return 0;
+}
+
+VOID
+__PcdSet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT64 Value
+ )
+/*++
+
+Routine Description:
+
+ Set PCD value
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+ Value PCD value to be set
+
+Returns:
+
+ None
+--*/
+{
+ int Index;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ free(PcdList[Index].Value);
+ PcdList[Index].Value = malloc(20);
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ if (Value == 0) {
+ strcpy (PcdList[Index].Value, "0x00");
+ } else {
+ strcpy (PcdList[Index].Value, "0x01");
+ }
+ break;
+ case PcdDataTypeUint8:
+ sprintf(PcdList[Index].Value, "0x%02x", (UINT8)(Value & 0xff));
+ break;
+ case PcdDataTypeUint16:
+ sprintf(PcdList[Index].Value, "0x%04x", (UINT16)(Value & 0xffff));
+ break;
+ case PcdDataTypeUint32:
+ sprintf(PcdList[Index].Value, "0x%08x", (UINT32)(Value & 0xffffffff));
+ break;
+ case PcdDataTypeUint64:
+ sprintf(PcdList[Index].Value, "0x%016llx", (unsigned long long)Value);
+ break;
+ case PcdDataTypePointer:
+ fprintf (stderr, "PCD %s.%s.%s.%s is structure. Use PcdSetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ }
+}
+
+VOID *
+__PcdGetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 *Size
+ )
+/*++
+
+Routine Description:
+
+ Get PCD value buffer
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+ Size Size of PCD value buffer
+
+Returns:
+
+ PCD value buffer
+--*/
+{
+ int Index;
+ CHAR8 *Value;
+ UINT8 *Buffer;
+ CHAR8 *End;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ case PcdDataTypeUint8:
+ case PcdDataTypeUint16:
+ case PcdDataTypeUint32:
+ case PcdDataTypeUint64:
+ fprintf (stderr, "PCD %s.%s.%s.%s is a value. Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ case PcdDataTypePointer:
+ Value = &PcdList[Index].Value[1];
+ for (*Size = 0, strtoul(Value, &End, 16); Value != End; strtoul(Value, &End, 16), *Size = *Size + 1) {
+ Value = End + 1;
+ }
+ Buffer = malloc(*Size + 1);
+ if (Buffer == NULL) {
+ *Size = 0;
+ return NULL;
+ }
+ Value = &PcdList[Index].Value[1];
+ for (*Size = 0, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16); Value != End; *Size = *Size + 1, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16)) {
+ Value = End + 1;
+ }
+ return Buffer;
+ }
+ *Size = 0;
+ return 0;
+}
+
+VOID
+__PcdSetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 Size,
+ UINT8 *Value
+ )
+/*++
+
+Routine Description:
+
+ Set PCD value buffer
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+ Size Size of PCD value
+ Value Pointer to the updated PCD value buffer
+
+Returns:
+
+ None
+--*/
+{
+ int Index;
+ UINT32 ValueIndex;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ case PcdDataTypeUint8:
+ case PcdDataTypeUint16:
+ case PcdDataTypeUint32:
+ case PcdDataTypeUint64:
+ fprintf (stderr, "PCD %s.%s.%s.%s is a value. Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ case PcdDataTypePointer:
+ free(PcdList[Index].Value);
+ PcdList[Index].Value = malloc(Size * 5 + 3);
+ PcdList[Index].Value[0] = '{';
+ for (ValueIndex = 0; ValueIndex < Size; ValueIndex++) {
+ sprintf(&PcdList[Index].Value[1 + ValueIndex * 5], "0x%02x,", Value[ValueIndex]);
+ }
+ PcdList[Index].Value[1 + Size * 5 - 1] = '}';
+ PcdList[Index].Value[1 + Size * 5 ] = 0;
+ break;
+ }
+}
+
+VOID
+STATIC
+ReadInputFile (
+ CHAR8 *InputFileName,
+ UINT8 **FileBuffer,
+ UINT32 *FileSize
+ )
+/*++
+
+Routine Description:
+
+ Read the file buffer from the input file.
+
+Arguments:
+
+ InputFileName Point to the input file name.
+ FileBuffer Point to the input file buffer.
+ FileSize Size of the file buffer.
+
+Returns:
+
+ None
+--*/
+{
+ FILE *InputFile;
+ UINT32 BytesRead;
+
+ //
+ // Open Input file and read file data.
+ //
+ InputFile = fopen (InputFileName, "rb");
+ if (InputFile == NULL) {
+ fprintf (stderr, "Error opening file %s\n", InputFileName);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Go to the end so that we can determine the file size
+ //
+ if (fseek (InputFile, 0, SEEK_END)) {
+ fprintf (stderr, "Error reading input file %s\n", InputFileName);
+ fclose (InputFile);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Get the file size
+ //
+ *FileSize = ftell (InputFile);
+ if (*FileSize == -1) {
+ fprintf (stderr, "Error parsing the input file %s\n", InputFileName);
+ fclose (InputFile);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Allocate a buffer
+ //
+ *FileBuffer = malloc (*FileSize);
+ if (*FileBuffer == NULL) {
+ fprintf (stderr, "Can not allocate buffer for input input file %s\n", InputFileName);
+ fclose (InputFile);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Reset to the beginning of the file
+ //
+ if (fseek (InputFile, 0, SEEK_SET)) {
+ fprintf (stderr, "Error reading the input file %s\n", InputFileName);
+ fclose (InputFile);
+ free (*FileBuffer);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Read all of the file contents.
+ //
+ BytesRead = (UINT32)fread (*FileBuffer, sizeof (UINT8), *FileSize, InputFile);
+ if (BytesRead != *FileSize * sizeof (UINT8)) {
+ fprintf (stderr, "Error reading the input file %s\n", InputFileName);
+ fclose (InputFile);
+ free (*FileBuffer);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Close the file
+ //
+ fclose (InputFile);
+}
+
+VOID
+STATIC
+ParseFile (
+ UINT8 *FileBuffer,
+ UINT32 FileSize
+ )
+/*++
+
+Routine Description:
+
+ Read the initial PCD value from the input file buffer.
+
+Arguments:
+
+ FileBuffer Point to the input file buffer.
+ FileSize Size of the file buffer.
+
+Returns:
+
+ None
+--*/
+{
+ UINT32 Index;
+ UINT32 NumLines;
+ UINT32 TokenIndex;
+ UINT32 TokenStart;
+
+ for (Index = 0, NumLines = 0; Index < FileSize; Index++) {
+ if (FileBuffer[Index] == '\n') {
+ NumLines++;
+ }
+ }
+ PcdList = malloc((NumLines + 1) * sizeof(PcdList[0]));
+
+ for (Index = 0, TokenIndex = 0, PcdListLength = 0, TokenStart = 0; Index < FileSize; Index++) {
+ if (FileBuffer[Index] == ' ') {
+ continue;
+ }
+ if (FileBuffer[Index] == '|' || FileBuffer[Index] == '.' || FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
+ RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
+ if (FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
+ if (TokenIndex != 0) {
+ PcdListLength++;
+ TokenIndex = 0;
+ }
+ } else {
+ TokenIndex++;
+ }
+ TokenStart = Index + 1;
+ continue;
+ }
+ }
+ if (Index > TokenStart) {
+ RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
+ if (TokenIndex != 0) {
+ PcdListLength++;
+ }
+ }
+}
+
+VOID
+STATIC
+WriteOutputFile (
+ CHAR8 *OutputFileName
+ )
+/*++
+
+Routine Description:
+
+ Write the updated PCD value into the output file name.
+
+Arguments:
+
+ OutputFileName Point to the output file name.
+
+Returns:
+
+ None
+--*/
+{
+ FILE *OutputFile;
+ UINT32 Index;
+
+ //
+ // Open output file
+ //
+ OutputFile = fopen (OutputFileName, "wb");
+ if (OutputFile == NULL) {
+ fprintf (stderr, "Error opening file %s\n", OutputFileName);
+ exit (EXIT_FAILURE);
+ }
+
+ for (Index = 0; Index < PcdListLength; Index++) {
+ fprintf (
+ OutputFile,
+ "%s.%s.%s.%s|%s|%s\n",
+ PcdList[Index].SkuName,
+ PcdList[Index].DefaultValueName,
+ PcdList[Index].TokenSpaceGuidName,
+ PcdList[Index].TokenName,
+ PcdList[Index].DataType,
+ PcdList[Index].Value
+ );
+ }
+
+ //
+ // Done, write output file.
+ //
+ if (OutputFile != NULL) {
+ fclose (OutputFile);
+ }
+}
+
+VOID
+STATIC
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "Usage: -i <input_file> -o <output_file>\n\n");
+ fprintf (stdout, "optional arguments:\n");
+ fprintf (stdout, " -h, --help Show this help message and exit\n");
+ fprintf (stdout, " -i INPUT_FILENAME, --input INPUT_FILENAME\n\
+ PCD Database Input file name\n");
+ fprintf (stdout, " -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
+ PCD Database Output file name\n");
+}
+
+VOID
+STATIC
+ParseArguments (
+ int argc,
+ char *argv[],
+ CHAR8 **InputFileName,
+ CHAR8 **OutputFileName
+ )
+/*++
+
+Routine Description:
+
+ Parse the input parameters to get the input/output file name.
+
+Arguments:
+
+ argc Number of command line parameters.
+ argv Array of pointers to parameter strings.
+ InputFileName Point to the input file name.
+ OutputFileName Point to the output file name.
+
+Returns:
+
+ None
+--*/
+{
+ if (argc == 1) {
+ fprintf (stderr, "Missing options\n");
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Parse command line
+ //
+ argc--;
+ argv++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Usage ();
+ exit (EXIT_SUCCESS);
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--input") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ fprintf (stderr, "Invalid option value. Input File name is missing for -i option\n");
+ exit (EXIT_FAILURE);
+ }
+ *InputFileName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ fprintf (stderr, "Invalid option value. Output File name is missing for -i option\n");
+ exit (EXIT_FAILURE);
+ }
+ *OutputFileName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (argv[0][0] == '-') {
+ fprintf (stderr, "Unknown option %s\n", argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ argc --;
+ argv ++;
+ }
+
+ //
+ // Check Input parameters
+ //
+ if (*InputFileName == NULL) {
+ fprintf (stderr, "Missing option. Input files is not specified\n");
+ exit (EXIT_FAILURE);
+ }
+
+ if (*OutputFileName == NULL) {
+ fprintf (stderr, "Missing option. Output file is not specified\n");
+ exit (EXIT_FAILURE);
+ }
+}
+
+int
+PcdValueMain (
+ int argc,
+ char *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main function updates PCD values.
+
+Arguments:
+
+ argc Number of command line parameters.
+ argv Array of pointers to parameter strings.
+
+Returns:
+ EXIT_SUCCESS
+--*/
+{
+ CHAR8 *InputFileName;
+ CHAR8 *OutputFileName;
+ UINT8 *FileBuffer;
+ UINT32 FileSize;
+
+ InputFileName = NULL;
+ OutputFileName = NULL;
+
+ //
+ // Parse the input arguments
+ //
+ ParseArguments (argc, argv, &InputFileName, &OutputFileName);
+
+ //
+ // Open Input file and read file data.
+ //
+ ReadInputFile (InputFileName, &FileBuffer, &FileSize);
+
+ //
+ // Read the initial Pcd value
+ //
+ ParseFile (FileBuffer, FileSize);
+
+ //
+ // Customize PCD values in the PCD Database
+ //
+ PcdEntryPoint ();
+
+ //
+ // Save the updated PCD value
+ //
+ WriteOutputFile (OutputFileName);
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.h
new file mode 100644
index 00000000..f53d8a4b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PcdValueCommon.h
@@ -0,0 +1,185 @@
+/** @file
+Header file for PcdValue structure definition.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCD_VALUE_COMMON_H
+#define _PCD_VALUE_COMMON_H
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/UefiInternalFormRepresentation.h>
+
+#define __FIELD_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field)
+#define __ARRAY_ELEMENT_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field[0])
+#define __OFFSET_OF(TYPE, Field) ((UINT32)(size_t) &(((TYPE *)0)->Field))
+#define __FLEXIBLE_SIZE(Size, TYPE, Field, MaxIndex) if (__FIELD_SIZE(TYPE, Field) == 0) Size = MAX((__OFFSET_OF(TYPE, Field) + __ARRAY_ELEMENT_SIZE(TYPE, Field) * (MaxIndex)), Size)
+#define __ARRAY_SIZE(Array) (sizeof(Array)/sizeof(Array[0]))
+
+#if defined(_MSC_EXTENSIONS)
+#define __STATIC_ASSERT static_assert
+#else
+#define __STATIC_ASSERT _Static_assert
+#endif
+
+VOID
+PcdEntryPoint (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Main function updates PCD values. It is auto generated by Build
+
+Arguments:
+
+ None
+
+Returns:
+ None
+--*/
+;
+
+int
+PcdValueMain (
+ int argc,
+ char *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main function updates PCD values.
+
+Arguments:
+
+ argc Number of command line parameters.
+ argv Array of pointers to parameter strings.
+
+Returns:
+ EXIT_SUCCESS
+--*/
+;
+
+VOID
+__PcdSet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT64 Value
+ )
+/*++
+
+Routine Description:
+
+ Get PCD value
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+
+Returns:
+
+ PCD value
+--*/
+;
+
+VOID
+__PcdSet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT64 Value
+ )
+/*++
+
+Routine Description:
+
+ Set PCD value
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+ Value PCD value to be set
+
+Returns:
+
+ None
+--*/
+;
+
+VOID *
+__PcdGetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 *Size
+ )
+/*++
+
+Routine Description:
+
+ Get PCD value buffer
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+ Size Size of PCD value buffer
+
+Returns:
+
+ PCD value buffer
+--*/
+;
+
+VOID
+__PcdSetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 Size,
+ UINT8 *Value
+ )
+/*++
+
+Routine Description:
+
+ Set PCD value buffer
+
+Arguments:
+
+ SkuName SkuName String
+ DefaultValueName DefaultValueName String
+ TokenSpaceGuidName TokenSpaceGuidName String
+ TokenName TokenName String
+ Size Size of PCD value
+ Value Pointer to the updated PCD value buffer
+
+Returns:
+
+ None
+--*/
+;
+
+#define PcdGet(A, B, C, D) __PcdGet(#A, #B, #C, #D)
+#define PcdSet(A, B, C, D, Value) __PcdSet(#A, #B, #C, #D, Value)
+#define PcdGetPtr(A, B, C, D, Size) __PcdGetPtr(#A, #B, #C, #D, Size)
+#define PcdSetPtr(A, B, C, D, Size, Value) __PcdSetPtr(#A, #B, #C, #D, Size, Value)
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLib.h
new file mode 100644
index 00000000..b625f6ac
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLib.h
@@ -0,0 +1,213 @@
+/** @file
+ Function prototypes and defines on Memory Only PE COFF loader
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __BASE_PE_COFF_LIB_H__
+#define __BASE_PE_COFF_LIB_H__
+
+//
+// Return status codes from the PE/COFF Loader services
+// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes
+//
+#define IMAGE_ERROR_SUCCESS 0
+#define IMAGE_ERROR_IMAGE_READ 1
+#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2
+#define IMAGE_ERROR_INVALID_MACHINE_TYPE 3
+#define IMAGE_ERROR_INVALID_SUBSYSTEM 4
+#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5
+#define IMAGE_ERROR_INVALID_IMAGE_SIZE 6
+#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7
+#define IMAGE_ERROR_SECTION_NOT_LOADED 8
+#define IMAGE_ERROR_FAILED_RELOCATION 9
+#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10
+
+//
+// Macro definitions for RISC-V architecture.
+//
+#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
+#define RISCV_IMM_BITS 12
+#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
+#define RISCV_CONST_HIGH_PART(VALUE) \
+ (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
+
+//
+// PE/COFF Loader Read Function passed in by caller
+//
+typedef
+RETURN_STATUS
+(EFIAPI *PE_COFF_LOADER_READ_FILE) (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ );
+
+//
+// Context structure used while PE/COFF image is being loaded and relocated
+//
+typedef struct {
+ PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ PHYSICAL_ADDRESS DestinationAddress;
+ PHYSICAL_ADDRESS EntryPoint;
+ PE_COFF_LOADER_READ_FILE ImageRead;
+ VOID *Handle;
+ VOID *FixupData;
+ UINT32 SectionAlignment;
+ UINT32 PeCoffHeaderOffset;
+ UINT32 DebugDirectoryEntryRva;
+ VOID *CodeView;
+ CHAR8 *PdbPointer;
+ UINTN SizeOfHeaders;
+ UINT32 ImageCodeMemoryType;
+ UINT32 ImageDataMemoryType;
+ UINT32 ImageError;
+ UINTN FixupDataSize;
+ UINT16 Machine;
+ UINT16 ImageType;
+ BOOLEAN RelocationsStripped;
+ BOOLEAN IsTeImage;
+} PE_COFF_LOADER_IMAGE_CONTEXT;
+
+
+/**
+ Retrieves information on a PE/COFF image
+
+ @param ImageContext The context of the image being loaded
+
+ @retval EFI_SUCCESS The information on the PE/COFF image was collected.
+ @retval EFI_INVALID_PARAMETER ImageContext is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image is not supported.
+ @retval Otherwise The error status from reading the PE/COFF image using the
+ ImageContext->ImageRead() function
+
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderGetImageInfo (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+;
+
+/**
+ Relocates a PE/COFF image in memory
+
+ @param ImageContext Contains information on the loaded image to relocate
+
+ @retval EFI_SUCCESS if the PE/COFF image was relocated
+ @retval EFI_LOAD_ERROR if the image is not a valid PE/COFF image
+ @retval EFI_UNSUPPORTED not support
+
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderRelocateImage (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+;
+
+/**
+ Loads a PE/COFF image into memory
+
+ @param ImageContext Contains information on image to load into memory
+
+ @retval EFI_SUCCESS if the PE/COFF image was loaded
+ @retval EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer
+ @retval EFI_LOAD_ERROR if the image is a runtime driver with no relocations
+ @retval EFI_INVALID_PARAMETER if the image address is invalid
+
+**/
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderLoadImage (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+;
+
+VOID *
+EFIAPI
+PeCoffLoaderGetPdbPointer (
+ IN VOID *Pe32Data
+ )
+;
+
+RETURN_STATUS
+EFIAPI
+PeCoffLoaderGetEntryPoint (
+ IN VOID *Pe32Data,
+ OUT VOID **EntryPoint,
+ OUT VOID **BaseOfImage
+ )
+;
+
+//
+// These functions are used by the ARM PE/COFF relocation code and by
+// the ELF to PE/COFF converter so that is why they are public
+//
+
+/**
+ Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
+ return the immediate data encoded in the instruction
+
+ @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
+
+ @return Immediate address encoded in the instruction
+
+**/
+UINT16
+EFIAPI
+ThumbMovtImmediateAddress (
+ IN UINT16 *Instruction
+ );
+
+/**
+ Update an ARM MOVT or MOVW immediate instruction immediate data.
+
+ @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
+ @param Address New address to patch into the instruction
+
+**/
+VOID
+EFIAPI
+ThumbMovtImmediatePatch (
+ IN OUT UINT16 *Instruction,
+ IN UINT16 Address
+ );
+
+
+/**
+ Pass in a pointer to an ARM MOVW/MOVT instruction pair and
+ return the immediate data encoded in the two` instruction
+
+ @param Instructions Pointer to ARM MOVW/MOVT instruction pair
+
+ @return Immediate address encoded in the instructions
+
+**/
+UINT32
+EFIAPI
+ThumbMovwMovtImmediateAddress (
+ IN UINT16 *Instructions
+ );
+
+/**
+ Update an ARM MOVW/MOVT immediate instruction instruction pair.
+
+ @param Instructions Pointer to ARM MOVW/MOVT instruction pair
+ @param Address New address to patch into the instructions
+**/
+VOID
+EFIAPI
+ThumbMovwMovtImmediatePatch (
+ IN OUT UINT16 *Instructions,
+ IN UINT32 Address
+ );
+
+
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLoaderEx.c
new file mode 100644
index 00000000..b7492998
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/PeCoffLoaderEx.c
@@ -0,0 +1,334 @@
+/** @file
+IA32 and X64 Specific relocation fixups
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+--*/
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h>
+#include "PeCoffLib.h"
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+
+
+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
+ Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
+
+#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
+ *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
+ ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
+
+#define IMM64_IMM7B_INST_WORD_X 3
+#define IMM64_IMM7B_SIZE_X 7
+#define IMM64_IMM7B_INST_WORD_POS_X 4
+#define IMM64_IMM7B_VAL_POS_X 0
+
+#define IMM64_IMM9D_INST_WORD_X 3
+#define IMM64_IMM9D_SIZE_X 9
+#define IMM64_IMM9D_INST_WORD_POS_X 18
+#define IMM64_IMM9D_VAL_POS_X 7
+
+#define IMM64_IMM5C_INST_WORD_X 3
+#define IMM64_IMM5C_SIZE_X 5
+#define IMM64_IMM5C_INST_WORD_POS_X 13
+#define IMM64_IMM5C_VAL_POS_X 16
+
+#define IMM64_IC_INST_WORD_X 3
+#define IMM64_IC_SIZE_X 1
+#define IMM64_IC_INST_WORD_POS_X 12
+#define IMM64_IC_VAL_POS_X 21
+
+#define IMM64_IMM41a_INST_WORD_X 1
+#define IMM64_IMM41a_SIZE_X 10
+#define IMM64_IMM41a_INST_WORD_POS_X 14
+#define IMM64_IMM41a_VAL_POS_X 22
+
+#define IMM64_IMM41b_INST_WORD_X 1
+#define IMM64_IMM41b_SIZE_X 8
+#define IMM64_IMM41b_INST_WORD_POS_X 24
+#define IMM64_IMM41b_VAL_POS_X 32
+
+#define IMM64_IMM41c_INST_WORD_X 2
+#define IMM64_IMM41c_SIZE_X 23
+#define IMM64_IMM41c_INST_WORD_POS_X 0
+#define IMM64_IMM41c_VAL_POS_X 40
+
+#define IMM64_SIGN_INST_WORD_X 3
+#define IMM64_SIGN_SIZE_X 1
+#define IMM64_SIGN_INST_WORD_POS_X 27
+#define IMM64_SIGN_VAL_POS_X 63
+
+UINT32 *RiscVHi20Fixup = NULL;
+
+RETURN_STATUS
+PeCoffLoaderRelocateIa32Image (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - Unsupported now
+
+--*/
+{
+ return RETURN_UNSUPPORTED;
+}
+
+/*++
+
+Routine Description:
+
+ Performs an RISC-V specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ Status code
+
+--*/
+RETURN_STATUS
+PeCoffLoaderRelocateRiscVImage (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+{
+ UINT32 Value;
+ UINT32 Value2;
+
+ switch ((*Reloc) >> 12) {
+ case EFI_IMAGE_REL_BASED_RISCV_HI20:
+ RiscVHi20Fixup = (UINT32 *) Fixup;
+ break;
+
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12I:
+ if (RiscVHi20Fixup != NULL) {
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value += (UINT32)Adjust;
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
+ *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \
+ (RV_X (*(UINT32 *)Fixup, 0, 20));
+ }
+ RiscVHi20Fixup = NULL;
+ break;
+
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12S:
+ if (RiscVHi20Fixup != NULL) {
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value += (UINT32)Adjust;
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
+ Value2 = *(UINT32 *)Fixup & 0x01fff07f;
+ Value &= RISCV_IMM_REACH - 1;
+ *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
+ }
+ RiscVHi20Fixup = NULL;
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
+ return the immediate data encoded in the instruction
+
+ @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
+
+ @return Immediate address encoded in the instruction
+
+**/
+UINT16
+ThumbMovtImmediateAddress (
+ IN UINT16 *Instruction
+ )
+{
+ UINT32 Movt;
+ UINT16 Address;
+
+ // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction
+ // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000
+ Movt = (*Instruction << 16) | (*(Instruction + 1));
+
+ // imm16 = imm4:i:imm3:imm8
+ // imm4 -> Bit19:Bit16
+ // i -> Bit26
+ // imm3 -> Bit14:Bit12
+ // imm8 -> Bit7:Bit0
+ Address = (UINT16)(Movt & 0x000000ff); // imm8
+ Address |= (UINT16)((Movt >> 4) & 0x0000f700); // imm4 imm3
+ Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i
+ return Address;
+}
+
+
+/**
+ Update an ARM MOVT or MOVW immediate instruction immediate data.
+
+ @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
+ @param Address New address to patch into the instruction
+**/
+VOID
+ThumbMovtImmediatePatch (
+ IN OUT UINT16 *Instruction,
+ IN UINT16 Address
+ )
+{
+ UINT16 Patch;
+
+ // First 16-bit chunk of instruction
+ Patch = ((Address >> 12) & 0x000f); // imm4
+ Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i
+ *Instruction = (*Instruction & ~0x040f) | Patch;
+
+ // Second 16-bit chunk of instruction
+ Patch = Address & 0x000000ff; // imm8
+ Patch |= ((Address << 4) & 0x00007000); // imm3
+ Instruction++;
+ *Instruction = (*Instruction & ~0x70ff) | Patch;
+}
+
+/**
+ Pass in a pointer to an ARM MOVW/MOVT instruction pair and
+ return the immediate data encoded in the two` instruction
+
+ @param Instructions Pointer to ARM MOVW/MOVT instruction pair
+
+ @return Immediate address encoded in the instructions
+
+**/
+UINT32
+EFIAPI
+ThumbMovwMovtImmediateAddress (
+ IN UINT16 *Instructions
+ )
+{
+ UINT16 *Word;
+ UINT16 *Top;
+
+ Word = Instructions; // MOVW
+ Top = Word + 2; // MOVT
+
+ return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);
+}
+
+
+/**
+ Update an ARM MOVW/MOVT immediate instruction instruction pair.
+
+ @param Instructions Pointer to ARM MOVW/MOVT instruction pair
+ @param Address New address to patch into the instructions
+**/
+VOID
+EFIAPI
+ThumbMovwMovtImmediatePatch (
+ IN OUT UINT16 *Instructions,
+ IN UINT32 Address
+ )
+{
+ UINT16 *Word;
+ UINT16 *Top;
+
+ Word = (UINT16 *)Instructions; // MOVW
+ Top = Word + 2; // MOVT
+
+ ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));
+ ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));
+}
+
+
+/**
+ Performs an ARM-based specific relocation fixup and is a no-op on other
+ instruction sets.
+
+ @param Reloc Pointer to the relocation record.
+ @param Fixup Pointer to the address to fix up.
+ @param FixupData Pointer to a buffer to log the fixups.
+ @param Adjust The offset to adjust the fixup.
+
+ @return Status code.
+
+**/
+RETURN_STATUS
+PeCoffLoaderRelocateArmImage (
+ IN UINT16 **Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+{
+ UINT16 *Fixup16;
+ UINT32 FixupVal;
+
+ Fixup16 = (UINT16 *) Fixup;
+
+ switch ((**Reloc) >> 12) {
+
+ case EFI_IMAGE_REL_BASED_ARM_MOV32T:
+ FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;
+ ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);
+
+
+ if (*FixupData != NULL) {
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
+ CopyMem (*FixupData, Fixup16, sizeof (UINT64));
+ *FixupData = *FixupData + sizeof(UINT64);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_ARM_MOV32A:
+ // break omitted - ARM instruction encoding not implemented
+ default:
+ return RETURN_UNSUPPORTED;
+ }
+
+ return RETURN_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.c
new file mode 100644
index 00000000..337899ed
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.c
@@ -0,0 +1,1429 @@
+/** @file
+Generic but simple file parsing routines.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+--*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "SimpleFileParsing.h"
+
+#ifndef MAX_PATH
+#define MAX_PATH 255
+#endif
+//
+// just in case we get in an endless loop.
+//
+#define MAX_NEST_DEPTH 20
+//
+// number of wchars
+//
+#define MAX_STRING_IDENTIFIER_NAME 100
+
+#define T_CHAR_SPACE ' '
+#define T_CHAR_NULL 0
+#define T_CHAR_CR '\r'
+#define T_CHAR_TAB '\t'
+#define T_CHAR_LF '\n'
+#define T_CHAR_SLASH '/'
+#define T_CHAR_BACKSLASH '\\'
+#define T_CHAR_DOUBLE_QUOTE '"'
+#define T_CHAR_LC_X 'x'
+#define T_CHAR_0 '0'
+#define T_CHAR_STAR '*'
+
+//
+// We keep a linked list of these for the source files we process
+//
+typedef struct _SOURCE_FILE {
+ FILE *Fptr;
+ CHAR8 *FileBuffer;
+ CHAR8 *FileBufferPtr;
+ UINTN FileSize;
+ CHAR8 FileName[MAX_PATH];
+ UINTN LineNum;
+ BOOLEAN EndOfFile;
+ BOOLEAN SkipToHash;
+ struct _SOURCE_FILE *Previous;
+ struct _SOURCE_FILE *Next;
+ CHAR8 ControlCharacter;
+} SOURCE_FILE;
+
+typedef struct {
+ CHAR8 *FileBufferPtr;
+} FILE_POSITION;
+
+//
+// Keep all our module globals in this structure
+//
+STATIC struct {
+ SOURCE_FILE SourceFile;
+ BOOLEAN VerboseFile;
+ BOOLEAN VerboseToken;
+} mGlobals;
+
+STATIC
+UINTN
+t_strcmp (
+ CHAR8 *Buffer,
+ CHAR8 *Str
+ );
+
+STATIC
+UINTN
+t_strncmp (
+ CHAR8 *Str1,
+ CHAR8 *Str2,
+ INTN Len
+ );
+
+STATIC
+UINTN
+t_strlen (
+ CHAR8 *Str
+ );
+
+STATIC
+VOID
+RewindFile (
+ SOURCE_FILE *SourceFile
+ );
+
+STATIC
+BOOLEAN
+IsWhiteSpace (
+ SOURCE_FILE *SourceFile
+ );
+
+STATIC
+UINTN
+SkipWhiteSpace (
+ SOURCE_FILE *SourceFile
+ );
+
+STATIC
+BOOLEAN
+EndOfFile (
+ SOURCE_FILE *SourceFile
+ );
+
+STATIC
+VOID
+PreprocessFile (
+ SOURCE_FILE *SourceFile
+ );
+
+STATIC
+CHAR8 *
+t_strcpy (
+ CHAR8 *Dest,
+ CHAR8 *Src
+ );
+
+STATIC
+STATUS
+ProcessIncludeFile (
+ SOURCE_FILE *SourceFile,
+ SOURCE_FILE *ParentSourceFile
+ );
+
+STATIC
+STATUS
+ProcessFile (
+ SOURCE_FILE *SourceFile
+ );
+
+STATIC
+STATUS
+GetFilePosition (
+ FILE_POSITION *Fpos
+ );
+
+STATIC
+STATUS
+SetFilePosition (
+ FILE_POSITION *Fpos
+ );
+
+STATUS
+SFPInit (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+ None.
+
+Returns:
+ STATUS_SUCCESS always
+
+--*/
+{
+ memset ((VOID *) &mGlobals, 0, sizeof (mGlobals));
+ return STATUS_SUCCESS;
+}
+
+UINTN
+SFPGetLineNumber (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Return the line number of the file we're parsing. Used
+ for error reporting purposes.
+
+Arguments:
+ None.
+
+Returns:
+ The line number, or 0 if no file is being processed
+
+--*/
+{
+ return mGlobals.SourceFile.LineNum;
+}
+
+CHAR8 *
+SFPGetFileName (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Return the name of the file we're parsing. Used
+ for error reporting purposes.
+
+Arguments:
+ None.
+
+Returns:
+ A pointer to the file name. Null if no file is being
+ processed.
+
+--*/
+{
+ if (mGlobals.SourceFile.FileName[0]) {
+ return mGlobals.SourceFile.FileName;
+ }
+
+ return NULL;
+}
+
+STATUS
+SFPOpenFile (
+ CHAR8 *FileName
+ )
+/*++
+
+Routine Description:
+ Open a file for parsing.
+
+Arguments:
+ FileName - name of the file to parse
+
+Returns:
+
+
+--*/
+{
+ STATUS Status;
+ t_strcpy (mGlobals.SourceFile.FileName, FileName);
+ Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL);
+ return Status;
+}
+
+BOOLEAN
+SFPIsToken (
+ CHAR8 *Str
+ )
+/*++
+
+Routine Description:
+ Check to see if the specified token is found at
+ the current position in the input file.
+
+Arguments:
+ Str - the token to look for
+
+Returns:
+ TRUE - the token is next
+ FALSE - the token is not next
+
+Notes:
+ We do a simple string comparison on this function. It is
+ the responsibility of the caller to ensure that the token
+ is not a subset of some other token.
+
+ The file pointer is advanced past the token in the input file.
+
+--*/
+{
+ UINTN Len;
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+
+ if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {
+ mGlobals.SourceFile.FileBufferPtr += Len;
+ if (mGlobals.VerboseToken) {
+ printf ("Token: '%s'\n", Str);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+SFPIsKeyword (
+ CHAR8 *Str
+ )
+/*++
+
+Routine Description:
+ Check to see if the specified keyword is found at
+ the current position in the input file.
+
+Arguments:
+ Str - keyword to look for
+
+Returns:
+ TRUE - the keyword is next
+ FALSE - the keyword is not next
+
+Notes:
+ A keyword is defined as a "special" string that has a non-alphanumeric
+ character following it.
+
+--*/
+{
+ UINTN Len;
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+
+ if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {
+ if (isalnum ((int)mGlobals.SourceFile.FileBufferPtr[Len])) {
+ return FALSE;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr += Len;
+ if (mGlobals.VerboseToken) {
+ printf ("Token: '%s'\n", Str);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+SFPGetNextToken (
+ CHAR8 *Str,
+ UINTN Len
+ )
+/*++
+
+Routine Description:
+ Get the next token from the input stream.
+
+Arguments:
+ Str - pointer to a copy of the next token
+ Len - size of buffer pointed to by Str
+
+Returns:
+ TRUE - next token successfully returned
+ FALSE - otherwise
+
+Notes:
+ Preceding white space is ignored.
+ The parser's buffer pointer is advanced past the end of the
+ token.
+
+--*/
+{
+ UINTN Index;
+ CHAR8 TempChar;
+
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+ //
+ // Have to have enough string for at least one char and a null-terminator
+ //
+ if (Len < 2) {
+ return FALSE;
+ }
+ //
+ // Look at the first character. If it's an identifier, then treat it
+ // as such
+ //
+ TempChar = mGlobals.SourceFile.FileBufferPtr[0];
+ if (((TempChar >= 'a') && (TempChar <= 'z')) || ((TempChar >= 'A') && (TempChar <= 'Z')) || (TempChar == '_')) {
+ Str[0] = TempChar;
+ mGlobals.SourceFile.FileBufferPtr++;
+ Index = 1;
+ while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {
+ TempChar = mGlobals.SourceFile.FileBufferPtr[0];
+ if (((TempChar >= 'a') && (TempChar <= 'z')) ||
+ ((TempChar >= 'A') && (TempChar <= 'Z')) ||
+ ((TempChar >= '0') && (TempChar <= '9')) ||
+ (TempChar == '_')
+ ) {
+ Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];
+ mGlobals.SourceFile.FileBufferPtr++;
+ Index++;
+ } else {
+ //
+ // Invalid character for symbol name, so break out
+ //
+ break;
+ }
+ }
+ //
+ // Null terminate and return success
+ //
+ Str[Index] = 0;
+ return TRUE;
+ } else if ((TempChar == ')') || (TempChar == '(') || (TempChar == '*')) {
+ Str[0] = mGlobals.SourceFile.FileBufferPtr[0];
+ mGlobals.SourceFile.FileBufferPtr++;
+ Str[1] = 0;
+ return TRUE;
+ } else {
+ //
+ // Everything else is white-space (or EOF) separated
+ //
+ Index = 0;
+ while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {
+ if (IsWhiteSpace (&mGlobals.SourceFile)) {
+ if (Index > 0) {
+ Str[Index] = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+ } else {
+ Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];
+ mGlobals.SourceFile.FileBufferPtr++;
+ Index++;
+ }
+ }
+ //
+ // See if we just ran out of file contents, but did find a token
+ //
+ if ((Index > 0) && EndOfFile (&mGlobals.SourceFile)) {
+ Str[Index] = 0;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+SFPGetGuidToken (
+ CHAR8 *Str,
+ UINT32 Len
+ )
+/*++
+
+Routine Description:
+ Parse a GUID from the input stream. Stop when you discover white space.
+
+Arguments:
+ Str - pointer to a copy of the next token
+ Len - size of buffer pointed to by Str
+
+Returns:
+ TRUE - GUID string returned successfully
+ FALSE - otherwise
+
+--*/
+{
+ UINT32 Index;
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+
+ Index = 0;
+ while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {
+ if (IsWhiteSpace (&mGlobals.SourceFile)) {
+ if (Index > 0) {
+ Str[Index] = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+ } else {
+ Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];
+ mGlobals.SourceFile.FileBufferPtr++;
+ Index++;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+SFPSkipToToken (
+ CHAR8 *Str
+ )
+{
+ UINTN Len;
+ CHAR8 *SavePos;
+ Len = t_strlen (Str);
+ SavePos = mGlobals.SourceFile.FileBufferPtr;
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ while (!EndOfFile (&mGlobals.SourceFile)) {
+ if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) {
+ mGlobals.SourceFile.FileBufferPtr += Len;
+ return TRUE;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr++;
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ }
+
+ mGlobals.SourceFile.FileBufferPtr = SavePos;
+ return FALSE;
+}
+
+BOOLEAN
+SFPGetNumber (
+ UINTN *Value
+ )
+/*++
+
+Routine Description:
+ Check the token at the current file position for a numeric value.
+ May be either decimal or hex.
+
+Arguments:
+ Value - pointer where to store the value
+
+Returns:
+ FALSE - current token is not a number
+ TRUE - current token is a number
+
+--*/
+{
+ int Val;
+
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+
+ if (isdigit ((int)mGlobals.SourceFile.FileBufferPtr[0])) {
+ //
+ // Check for hex value
+ //
+ if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) {
+ if (!isxdigit ((int)mGlobals.SourceFile.FileBufferPtr[2])) {
+ return FALSE;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr += 2;
+ sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", &Val);
+ *Value = (UINT32) Val;
+ while (isxdigit ((int)mGlobals.SourceFile.FileBufferPtr[0])) {
+ mGlobals.SourceFile.FileBufferPtr++;
+ }
+
+ return TRUE;
+ } else {
+ *Value = atoi (mGlobals.SourceFile.FileBufferPtr);
+ while (isdigit ((int)mGlobals.SourceFile.FileBufferPtr[0])) {
+ mGlobals.SourceFile.FileBufferPtr++;
+ }
+
+ return TRUE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+STATUS
+SFPCloseFile (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Close the file being parsed.
+
+Arguments:
+ None.
+
+Returns:
+ STATUS_SUCCESS - the file was closed
+ STATUS_ERROR - no file is currently open
+
+--*/
+{
+ if (mGlobals.SourceFile.FileBuffer != NULL) {
+ free (mGlobals.SourceFile.FileBuffer);
+ memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile));
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_ERROR;
+}
+
+STATIC
+STATUS
+ProcessIncludeFile (
+ SOURCE_FILE *SourceFile,
+ SOURCE_FILE *ParentSourceFile
+ )
+/*++
+
+Routine Description:
+
+ Given a source file, open the file and parse it
+
+Arguments:
+
+ SourceFile - name of file to parse
+ ParentSourceFile - for error reporting purposes, the file that #included SourceFile.
+
+Returns:
+
+ Standard status.
+
+--*/
+{
+ STATIC UINTN NestDepth = 0;
+ CHAR8 FoundFileName[MAX_PATH];
+ STATUS Status;
+
+ Status = STATUS_SUCCESS;
+ NestDepth++;
+ //
+ // Print the file being processed. Indent so you can tell the include nesting
+ // depth.
+ //
+ if (mGlobals.VerboseFile) {
+ fprintf (stdout, "%*cProcessing file '%s'\n", (int)NestDepth * 2, ' ', SourceFile->FileName);
+ fprintf (stdout, "Parent source file = '%s'\n", ParentSourceFile->FileName);
+ }
+
+ //
+ // Make sure we didn't exceed our maximum nesting depth
+ //
+ if (NestDepth > MAX_NEST_DEPTH) {
+ Error (NULL, 0, 3001, "Not Supported", "%s exceeds max nesting depth (%u)", SourceFile->FileName, (unsigned) NestDepth);
+ Status = STATUS_ERROR;
+ goto Finish;
+ }
+ //
+ // Try to open the file locally, and if that fails try along our include paths.
+ //
+ strcpy (FoundFileName, SourceFile->FileName);
+ if ((SourceFile->Fptr = fopen (LongFilePath (FoundFileName), "rb")) == NULL) {
+ return STATUS_ERROR;
+ }
+ //
+ // Process the file found
+ //
+ ProcessFile (SourceFile);
+Finish:
+ //
+ // Close open files and return status
+ //
+ if (SourceFile->Fptr != NULL) {
+ fclose (SourceFile->Fptr);
+ SourceFile->Fptr = NULL;
+ }
+
+ return Status;
+}
+
+STATIC
+STATUS
+ProcessFile (
+ SOURCE_FILE *SourceFile
+ )
+/*++
+
+Routine Description:
+
+ Given a source file that's been opened, read the contents into an internal
+ buffer and pre-process it to remove comments.
+
+Arguments:
+
+ SourceFile - structure containing info on the file to process
+
+Returns:
+
+ Standard status.
+
+--*/
+{
+ //
+ // Get the file size, and then read the entire thing into memory.
+ // Allocate extra space for a terminator character.
+ //
+ fseek (SourceFile->Fptr, 0, SEEK_END);
+ SourceFile->FileSize = ftell (SourceFile->Fptr);
+ if (mGlobals.VerboseFile) {
+ printf ("FileSize = %u (0x%X)\n", (unsigned) SourceFile->FileSize, (unsigned) SourceFile->FileSize);
+ }
+
+ fseek (SourceFile->Fptr, 0, SEEK_SET);
+ SourceFile->FileBuffer = (CHAR8 *) malloc (SourceFile->FileSize + sizeof (CHAR8 ));
+ if (SourceFile->FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource: memory cannot be allocated", NULL);
+ return STATUS_ERROR;
+ }
+
+ fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);
+ SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (CHAR8 ))] = T_CHAR_NULL;
+ //
+ // Pre-process the file to replace comments with spaces
+ //
+ PreprocessFile (SourceFile);
+ SourceFile->LineNum = 1;
+ return STATUS_SUCCESS;
+}
+
+STATIC
+VOID
+PreprocessFile (
+ SOURCE_FILE *SourceFile
+ )
+/*++
+
+Routine Description:
+ Preprocess a file to replace all carriage returns with NULLs so
+ we can print lines (as part of error messages) from the file to the screen.
+
+Arguments:
+ SourceFile - structure that we use to keep track of an input file.
+
+Returns:
+ Nothing.
+
+--*/
+{
+ BOOLEAN InComment;
+ BOOLEAN SlashSlashComment;
+ int LineNum;
+
+ RewindFile (SourceFile);
+ InComment = FALSE;
+ SlashSlashComment = FALSE;
+ while (!EndOfFile (SourceFile)) {
+ //
+ // If a line-feed, then no longer in a comment if we're in a // comment
+ //
+ if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {
+ SourceFile->FileBufferPtr++;
+ SourceFile->LineNum++;
+ if (InComment && SlashSlashComment) {
+ InComment = FALSE;
+ SlashSlashComment = FALSE;
+ }
+ } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {
+ //
+ // Replace all carriage returns with a NULL so we can print stuff
+ //
+ SourceFile->FileBufferPtr[0] = 0;
+ SourceFile->FileBufferPtr++;
+ //
+ // Check for */ comment end
+ //
+ } else if (InComment &&
+ !SlashSlashComment &&
+ (SourceFile->FileBufferPtr[0] == T_CHAR_STAR) &&
+ (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)
+ ) {
+ SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;
+ SourceFile->FileBufferPtr++;
+ SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;
+ SourceFile->FileBufferPtr++;
+ InComment = FALSE;
+ } else if (InComment) {
+ SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;
+ SourceFile->FileBufferPtr++;
+ //
+ // Check for // comments
+ //
+ } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) {
+ InComment = TRUE;
+ SlashSlashComment = TRUE;
+ //
+ // Check for /* comment start
+ //
+ } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_STAR)) {
+ SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;
+ SourceFile->FileBufferPtr++;
+ SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;
+ SourceFile->FileBufferPtr++;
+ SlashSlashComment = FALSE;
+ InComment = TRUE;
+ } else {
+ SourceFile->FileBufferPtr++;
+ }
+ }
+ //
+ // Could check for end-of-file and still in a comment, but
+ // should not be necessary. So just restore the file pointers.
+ //
+ RewindFile (SourceFile);
+ //
+ // Dump the reformatted file if verbose mode
+ //
+ if (mGlobals.VerboseFile) {
+ LineNum = 1;
+ printf ("%04d: ", LineNum);
+ while (!EndOfFile (SourceFile)) {
+ if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {
+ printf ("'\n%04d: '", ++LineNum);
+ } else {
+ printf ("%c", SourceFile->FileBufferPtr[0]);
+ }
+
+ SourceFile->FileBufferPtr++;
+ }
+
+ printf ("'\n");
+ printf ("FileSize = %u (0x%X)\n", (unsigned)SourceFile->FileSize, (unsigned)SourceFile->FileSize);
+ RewindFile (SourceFile);
+ }
+}
+
+BOOLEAN
+SFPGetQuotedString (
+ CHAR8 *Str,
+ INTN Length
+ )
+/*++
+
+Routine Description:
+ Retrieve a quoted-string from the input file.
+
+Arguments:
+ Str - pointer to a copy of the quoted string parsed
+ Length - size of buffer pointed to by Str
+
+Returns:
+ TRUE - next token in input stream was a quoted string, and
+ the string value was returned in Str
+ FALSE - otherwise
+
+--*/
+{
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+
+ if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {
+ mGlobals.SourceFile.FileBufferPtr++;
+ while (Length > 0) {
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+ //
+ // Check for closing quote
+ //
+ if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {
+ mGlobals.SourceFile.FileBufferPtr++;
+ *Str = 0;
+ return TRUE;
+ }
+
+ *Str = mGlobals.SourceFile.FileBufferPtr[0];
+ Str++;
+ Length--;
+ mGlobals.SourceFile.FileBufferPtr++;
+ }
+ }
+ //
+ // First character was not a quote, or the input string length was
+ // insufficient to contain the quoted string, so return failure code.
+ //
+ return FALSE;
+}
+
+BOOLEAN
+SFPIsEOF (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Return TRUE of FALSE to indicate whether or not we've reached the end of the
+ file we're parsing.
+
+Arguments:
+ NA
+
+Returns:
+ TRUE - EOF reached
+ FALSE - otherwise
+
+--*/
+{
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ return EndOfFile (&mGlobals.SourceFile);
+}
+
+#if 0
+STATIC
+CHAR8 *
+GetQuotedString (
+ SOURCE_FILE *SourceFile,
+ BOOLEAN Optional
+ )
+{
+ CHAR8 *String;
+ CHAR8 *Start;
+ CHAR8 *Ptr;
+ UINTN Len;
+ BOOLEAN PreviousBackslash;
+
+ if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {
+ if (Optional == FALSE) {
+ Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);
+ }
+
+ return NULL;
+ }
+
+ Len = 0;
+ SourceFile->FileBufferPtr++;
+ Start = Ptr = SourceFile->FileBufferPtr;
+ PreviousBackslash = FALSE;
+ while (!EndOfFile (SourceFile)) {
+ if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (PreviousBackslash == FALSE)) {
+ break;
+ } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {
+ Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);
+ PreviousBackslash = FALSE;
+ } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) {
+ PreviousBackslash = TRUE;
+ } else {
+ PreviousBackslash = FALSE;
+ }
+
+ SourceFile->FileBufferPtr++;
+ Len++;
+ }
+
+ if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {
+ Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);
+ } else {
+ SourceFile->FileBufferPtr++;
+ }
+ //
+ // Now allocate memory for the string and save it off
+ //
+ String = (CHAR8 *) malloc ((Len + 1) * sizeof (CHAR8 ));
+ if (String == NULL) {
+ Error (NULL, 0, 4001, "Resource: memory cannot be allocated", NULL);
+ return NULL;
+ }
+ //
+ // Copy the string from the file buffer to the local copy.
+ // We do no reformatting of it whatsoever at this point.
+ //
+ Ptr = String;
+ while (Len > 0) {
+ *Ptr = *Start;
+ Start++;
+ Ptr++;
+ Len--;
+ }
+
+ *Ptr = 0;
+ return String;
+}
+#endif
+STATIC
+BOOLEAN
+EndOfFile (
+ SOURCE_FILE *SourceFile
+ )
+{
+ //
+ // The file buffer pointer will typically get updated before the End-of-file flag in the
+ // source file structure, so check it first.
+ //
+ if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (CHAR8 )) {
+ SourceFile->EndOfFile = TRUE;
+ return TRUE;
+ }
+
+ if (SourceFile->EndOfFile) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#if 0
+STATIC
+VOID
+ProcessTokenInclude (
+ SOURCE_FILE *SourceFile
+ )
+{
+ CHAR8 IncludeFileName[MAX_PATH];
+ CHAR8 *To;
+ UINTN Len;
+ BOOLEAN ReportedError;
+ SOURCE_FILE IncludedSourceFile;
+
+ ReportedError = FALSE;
+ if (SkipWhiteSpace (SourceFile) == 0) {
+ Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);
+ }
+ //
+ // Should be quoted file name
+ //
+ if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {
+ Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);
+ goto FailDone;
+ }
+
+ SourceFile->FileBufferPtr++;
+ //
+ // Copy the filename as ascii to our local string
+ //
+ To = IncludeFileName;
+ Len = 0;
+ while (!EndOfFile (SourceFile)) {
+ if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) {
+ Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);
+ goto FailDone;
+ }
+
+ if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {
+ SourceFile->FileBufferPtr++;
+ break;
+ }
+ //
+ // If too long, then report the error once and process until the closing quote
+ //
+ Len++;
+ if (!ReportedError && (Len >= sizeof (IncludeFileName))) {
+ Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);
+ ReportedError = TRUE;
+ }
+
+ if (!ReportedError) {
+ *To = (CHAR8 ) SourceFile->FileBufferPtr[0];
+ To++;
+ }
+
+ SourceFile->FileBufferPtr++;
+ }
+
+ if (!ReportedError) {
+ *To = 0;
+ memset ((CHAR8 *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));
+ strcpy (IncludedSourceFile.FileName, IncludeFileName);
+ ProcessIncludeFile (&IncludedSourceFile, SourceFile);
+ }
+
+ return ;
+FailDone:
+ //
+ // Error recovery -- skip to next #
+ //
+ SourceFile->SkipToHash = TRUE;
+}
+#endif
+STATIC
+BOOLEAN
+IsWhiteSpace (
+ SOURCE_FILE *SourceFile
+ )
+{
+ switch (*SourceFile->FileBufferPtr) {
+ case T_CHAR_NULL:
+ case T_CHAR_CR:
+ case T_CHAR_SPACE:
+ case T_CHAR_TAB:
+ case T_CHAR_LF:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+UINTN
+SkipWhiteSpace (
+ SOURCE_FILE *SourceFile
+ )
+{
+ UINTN Count;
+
+ Count = 0;
+ while (!EndOfFile (SourceFile)) {
+ Count++;
+ switch (*SourceFile->FileBufferPtr) {
+ case T_CHAR_NULL:
+ case T_CHAR_CR:
+ case T_CHAR_SPACE:
+ case T_CHAR_TAB:
+ SourceFile->FileBufferPtr++;
+ break;
+
+ case T_CHAR_LF:
+ SourceFile->FileBufferPtr++;
+ SourceFile->LineNum++;
+ break;
+
+ default:
+ return Count - 1;
+ }
+ }
+ //
+ // Some tokens require trailing whitespace. If we're at the end of the
+ // file, then we count that as well.
+ //
+ if ((Count == 0) && (EndOfFile (SourceFile))) {
+ Count++;
+ }
+
+ return Count;
+}
+
+STATIC
+UINTN
+t_strcmp (
+ CHAR8 *Buffer,
+ CHAR8 *Str
+ )
+/*++
+
+Routine Description:
+ Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,
+ so only compare up to the length of Str.
+
+Arguments:
+ Buffer - pointer to first (possibly not null-terminated) string
+ Str - pointer to null-terminated string to compare to Buffer
+
+Returns:
+ Number of bytes matched if exact match
+ 0 if Buffer does not start with Str
+
+--*/
+{
+ UINTN Len;
+
+ Len = 0;
+ while (*Str && (*Str == *Buffer)) {
+ Buffer++;
+ Str++;
+ Len++;
+ }
+
+ if (*Str) {
+ return 0;
+ }
+
+ return Len;
+}
+
+STATIC
+UINTN
+t_strlen (
+ CHAR8 *Str
+ )
+{
+ UINTN Len;
+ Len = 0;
+ while (*Str) {
+ Len++;
+ Str++;
+ }
+
+ return Len;
+}
+
+STATIC
+UINTN
+t_strncmp (
+ CHAR8 *Str1,
+ CHAR8 *Str2,
+ INTN Len
+ )
+{
+ while (Len > 0) {
+ if (*Str1 != *Str2) {
+ return Len;
+ }
+
+ Len--;
+ Str1++;
+ Str2++;
+ }
+
+ return 0;
+}
+
+STATIC
+CHAR8 *
+t_strcpy (
+ CHAR8 *Dest,
+ CHAR8 *Src
+ )
+{
+ CHAR8 *SaveDest;
+ SaveDest = Dest;
+ while (*Src) {
+ *Dest = *Src;
+ Dest++;
+ Src++;
+ }
+
+ *Dest = 0;
+ return SaveDest;
+}
+
+STATIC
+VOID
+RewindFile (
+ SOURCE_FILE *SourceFile
+ )
+{
+ SourceFile->LineNum = 1;
+ SourceFile->FileBufferPtr = SourceFile->FileBuffer;
+ SourceFile->EndOfFile = 0;
+}
+
+STATIC
+UINT32
+GetHexChars (
+ CHAR8 *Buffer,
+ UINT32 BufferLen
+ )
+{
+ UINT32 Len;
+ Len = 0;
+ while (!EndOfFile (&mGlobals.SourceFile) && (Len < BufferLen)) {
+ if (isxdigit ((int)mGlobals.SourceFile.FileBufferPtr[0])) {
+ Buffer[Len] = mGlobals.SourceFile.FileBufferPtr[0];
+ Len++;
+ mGlobals.SourceFile.FileBufferPtr++;
+ } else {
+ break;
+ }
+ }
+ //
+ // Null terminate if we can
+ //
+ if ((Len > 0) && (Len < BufferLen)) {
+ Buffer[Len] = 0;
+ }
+
+ return Len;
+}
+
+BOOLEAN
+SFPGetGuid (
+ INTN GuidStyle,
+ EFI_GUID *Value
+ )
+/*++
+
+Routine Description:
+ Parse a GUID from the input stream. Stop when you discover white space.
+
+Arguments:
+ GuidStyle - Style of the following GUID token
+ Value - pointer to EFI_GUID struct for output
+
+Returns:
+ TRUE - GUID string parsed successfully
+ FALSE - otherwise
+
+ GUID styles
+ Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
+
+--*/
+{
+ INT32 Value32;
+ UINT32 Index;
+ FILE_POSITION FPos;
+ CHAR8 TempString[20];
+ CHAR8 TempString2[3];
+ CHAR8 *From;
+ CHAR8 *To;
+ UINT32 Len;
+ BOOLEAN Status;
+
+ Status = FALSE;
+ //
+ // Skip white space, then start parsing
+ //
+ SkipWhiteSpace (&mGlobals.SourceFile);
+ GetFilePosition (&FPos);
+ if (EndOfFile (&mGlobals.SourceFile)) {
+ return FALSE;
+ }
+
+ if (GuidStyle == PARSE_GUID_STYLE_5_FIELDS) {
+ //
+ // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD
+ //
+ Len = GetHexChars (TempString, sizeof (TempString));
+ if ((Len == 0) || (Len > 8)) {
+ goto Done;
+ }
+
+ sscanf (TempString, "%x", &Value32);
+ Value->Data1 = Value32;
+ //
+ // Next two UINT16 fields
+ //
+ if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {
+ goto Done;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr++;
+ Len = GetHexChars (TempString, sizeof (TempString));
+ if ((Len == 0) || (Len > 4)) {
+ goto Done;
+ }
+
+ sscanf (TempString, "%x", &Value32);
+ Value->Data2 = (UINT16) Value32;
+
+ if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {
+ goto Done;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr++;
+ Len = GetHexChars (TempString, sizeof (TempString));
+ if ((Len == 0) || (Len > 4)) {
+ goto Done;
+ }
+
+ sscanf (TempString, "%x", &Value32);
+ Value->Data3 = (UINT16) Value32;
+ //
+ // Parse the "AAAA" as two bytes
+ //
+ if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {
+ goto Done;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr++;
+ Len = GetHexChars (TempString, sizeof (TempString));
+ if ((Len == 0) || (Len > 4)) {
+ goto Done;
+ }
+
+ sscanf (TempString, "%x", &Value32);
+ Value->Data4[0] = (UINT8) (Value32 >> 8);
+ Value->Data4[1] = (UINT8) Value32;
+ if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {
+ goto Done;
+ }
+
+ mGlobals.SourceFile.FileBufferPtr++;
+ //
+ // Read the last 6 bytes of the GUID
+ //
+ //
+ Len = GetHexChars (TempString, sizeof (TempString));
+ if ((Len == 0) || (Len > 12)) {
+ goto Done;
+ }
+ //
+ // Insert leading 0's to make life easier
+ //
+ if (Len != 12) {
+ From = TempString + Len - 1;
+ To = TempString + 11;
+ TempString[12] = 0;
+ while (From >= TempString) {
+ *To = *From;
+ To--;
+ From--;
+ }
+
+ while (To >= TempString) {
+ *To = '0';
+ To--;
+ }
+ }
+ //
+ // Now parse each byte
+ //
+ TempString2[2] = 0;
+ for (Index = 0; Index < 6; Index++) {
+ //
+ // Copy the two characters from the input string to something
+ // we can parse.
+ //
+ TempString2[0] = TempString[Index * 2];
+ TempString2[1] = TempString[Index * 2 + 1];
+ sscanf (TempString2, "%x", &Value32);
+ Value->Data4[Index + 2] = (UINT8) Value32;
+ }
+
+ Status = TRUE;
+ } else {
+ //
+ // Unsupported GUID style
+ //
+ return FALSE;
+ }
+
+Done:
+ if (Status == FALSE) {
+ SetFilePosition (&FPos);
+ }
+
+ return Status;
+}
+
+STATIC
+STATUS
+GetFilePosition (
+ FILE_POSITION *Fpos
+ )
+{
+ Fpos->FileBufferPtr = mGlobals.SourceFile.FileBufferPtr;
+ return STATUS_SUCCESS;
+}
+
+STATIC
+STATUS
+SetFilePosition (
+ FILE_POSITION *Fpos
+ )
+{
+ //
+ // Should check range of pointer
+ //
+ mGlobals.SourceFile.FileBufferPtr = Fpos->FileBufferPtr;
+ return STATUS_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.h
new file mode 100644
index 00000000..e699f050
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/SimpleFileParsing.h
@@ -0,0 +1,104 @@
+/** @file
+Function prototypes and defines for the simple file parsing routines.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SIMPLE_FILE_PARSING_H_
+#define _SIMPLE_FILE_PARSING_H_
+
+#include <Common/UefiBaseTypes.h>
+
+STATUS
+SFPInit (
+ VOID
+ )
+;
+
+STATUS
+SFPOpenFile (
+ CHAR8 *FileName
+ )
+;
+
+BOOLEAN
+SFPIsKeyword (
+ CHAR8 *Str
+ )
+;
+
+BOOLEAN
+SFPIsToken (
+ CHAR8 *Str
+ )
+;
+
+BOOLEAN
+SFPGetNextToken (
+ CHAR8 *Str,
+ UINTN Len
+ )
+;
+
+BOOLEAN
+SFPGetGuidToken (
+ CHAR8 *Str,
+ UINT32 Len
+ )
+;
+
+#define PARSE_GUID_STYLE_5_FIELDS 0
+
+BOOLEAN
+SFPGetGuid (
+ INTN GuidStyle,
+ EFI_GUID *Value
+ )
+;
+
+BOOLEAN
+SFPSkipToToken (
+ CHAR8 *Str
+ )
+;
+
+BOOLEAN
+SFPGetNumber (
+ UINTN *Value
+ )
+;
+
+BOOLEAN
+SFPGetQuotedString (
+ CHAR8 *Str,
+ INTN Length
+ )
+;
+
+BOOLEAN
+SFPIsEOF (
+ VOID
+ )
+;
+
+STATUS
+SFPCloseFile (
+ VOID
+ )
+;
+
+UINTN
+SFPGetLineNumber (
+ VOID
+ )
+;
+
+CHAR8 *
+SFPGetFileName (
+ VOID
+ )
+;
+
+#endif // #ifndef _SIMPLE_FILE_PARSING_H_
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.c
new file mode 100644
index 00000000..2d092869
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.c
@@ -0,0 +1,413 @@
+/** @file
+Function prototypes and defines for string routines.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <string.h>
+#include <ctype.h>
+#include "StringFuncs.h"
+
+//
+// Functions implementations
+//
+
+CHAR8*
+CloneString (
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+
+ Allocates a new string and copies 'String' to clone it
+
+Arguments:
+
+ String The string to clone
+
+Returns:
+
+ CHAR8* - NULL if there are not enough resources
+
+--*/
+{
+ CHAR8* NewString;
+
+ NewString = malloc (strlen (String) + 1);
+ if (NewString != NULL) {
+ strcpy (NewString, String);
+ }
+
+ return NewString;
+}
+
+
+EFI_STATUS
+StripInfDscStringInPlace (
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+
+ Remove all comments, leading and trailing whitespace from the string.
+
+Arguments:
+
+ String The string to 'strip'
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ CHAR8 *Pos;
+
+ if (String == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Remove leading whitespace
+ //
+ for (Pos = String; isspace ((int)*Pos); Pos++) {
+ }
+ if (Pos != String) {
+ memmove (String, Pos, strlen (Pos) + 1);
+ }
+
+ //
+ // Comment BUGBUGs!
+ //
+ // What about strings? Comment characters are okay in strings.
+ // What about multiline comments?
+ //
+
+ Pos = (CHAR8 *) strstr (String, "//");
+ if (Pos != NULL) {
+ *Pos = '\0';
+ }
+
+ Pos = (CHAR8 *) strchr (String, '#');
+ if (Pos != NULL) {
+ *Pos = '\0';
+ }
+
+ //
+ // Remove trailing whitespace
+ //
+ for (Pos = String + strlen (String);
+ ((Pos - 1) >= String) && (isspace ((int)*(Pos - 1)));
+ Pos--
+ ) {
+ }
+ *Pos = '\0';
+
+ return EFI_SUCCESS;
+}
+
+
+STRING_LIST*
+SplitStringByWhitespace (
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+
+ Creates and returns a 'split' STRING_LIST by splitting the string
+ on whitespace boundaries.
+
+Arguments:
+
+ String The string to 'split'
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ CHAR8 *Pos;
+ CHAR8 *EndOfSubString;
+ CHAR8 *EndOfString;
+ STRING_LIST *Output;
+ UINTN Item;
+
+ String = CloneString (String);
+ if (String == NULL) {
+ return NULL;
+ }
+ EndOfString = String + strlen (String);
+
+ Output = NewStringList ();
+
+ for (Pos = String, Item = 0; Pos < EndOfString; Item++) {
+ while (isspace ((int)*Pos)) {
+ Pos++;
+ }
+
+ for (EndOfSubString=Pos;
+ (*EndOfSubString != '\0') && !isspace ((int)*EndOfSubString);
+ EndOfSubString++
+ ) {
+ }
+
+ if (EndOfSubString == Pos) {
+ break;
+ }
+
+ *EndOfSubString = '\0';
+
+ AppendCopyOfStringToList (&Output, Pos);
+
+ Pos = EndOfSubString + 1;
+ }
+
+ free (String);
+ return Output;
+}
+
+
+STRING_LIST*
+NewStringList (
+ )
+/*++
+
+Routine Description:
+
+ Creates a new STRING_LIST with 0 strings.
+
+Returns:
+
+ STRING_LIST* - Null if there is not enough resources to create the object.
+
+--*/
+{
+ STRING_LIST *NewList;
+ NewList = AllocateStringListStruct (0);
+ if (NewList != NULL) {
+ NewList->Count = 0;
+ }
+ return NewList;
+}
+
+
+EFI_STATUS
+AppendCopyOfStringToList (
+ IN OUT STRING_LIST **StringList,
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+
+ Adds String to StringList. A new copy of String is made before it is
+ added to StringList.
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ STRING_LIST *OldList;
+ STRING_LIST *NewList;
+ CHAR8 *NewString;
+
+ OldList = *StringList;
+ NewList = AllocateStringListStruct (OldList->Count + 1);
+ if (NewList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewString = CloneString (String);
+ if (NewString == NULL) {
+ free (NewList);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ memcpy (
+ NewList->Strings,
+ OldList->Strings,
+ sizeof (OldList->Strings[0]) * OldList->Count
+ );
+ NewList->Count = OldList->Count + 1;
+ NewList->Strings[OldList->Count] = NewString;
+
+ *StringList = NewList;
+ free (OldList);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+RemoveLastStringFromList (
+ IN STRING_LIST *StringList
+ )
+/*++
+
+Routine Description:
+
+ Removes the last string from StringList and frees the memory associated
+ with it.
+
+Arguments:
+
+ StringList The string list to remove the string from
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ if (StringList->Count == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ free (StringList->Strings[StringList->Count - 1]);
+ StringList->Count--;
+ return EFI_SUCCESS;
+}
+
+
+STRING_LIST*
+AllocateStringListStruct (
+ IN UINTN StringCount
+ )
+/*++
+
+Routine Description:
+
+ Allocates a STRING_LIST structure that can store StringCount strings.
+
+Arguments:
+
+ StringCount The number of strings that need to be stored
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ return malloc (OFFSET_OF(STRING_LIST, Strings[StringCount + 1]));
+}
+
+
+VOID
+FreeStringList (
+ IN STRING_LIST *StringList
+ )
+/*++
+
+Routine Description:
+
+ Frees all memory associated with StringList.
+
+Arguments:
+
+ StringList The string list to free
+
+Returns:
+
+ VOID
+--*/
+{
+ while (StringList->Count > 0) {
+ RemoveLastStringFromList (StringList);
+ }
+
+ free (StringList);
+}
+
+
+CHAR8*
+StringListToString (
+ IN STRING_LIST *StringList
+ )
+/*++
+
+Routine Description:
+
+ Generates a string that represents the STRING_LIST
+
+Arguments:
+
+ StringList The string list to convert to a string
+
+Returns:
+
+ CHAR8* - The string list represented with a single string. The returned
+ string must be freed by the caller.
+
+--*/
+{
+ UINTN Count;
+ UINTN Length;
+ CHAR8 *NewString;
+
+ Length = 2;
+ for (Count = 0; Count < StringList->Count; Count++) {
+ if (Count > 0) {
+ Length += 2;
+ }
+ Length += strlen (StringList->Strings[Count]) + 2;
+ }
+
+ NewString = malloc (Length + 1);
+ if (NewString == NULL) {
+ return NewString;
+ }
+ NewString[0] = '\0';
+
+ strcat (NewString, "[");
+ for (Count = 0; Count < StringList->Count; Count++) {
+ if (Count > 0) {
+ strcat (NewString, ", ");
+ }
+ strcat (NewString, "\"");
+ strcat (NewString, StringList->Strings[Count]);
+ strcat (NewString, "\"");
+ }
+ strcat (NewString, "]");
+
+ return NewString;
+}
+
+
+VOID
+PrintStringList (
+ IN STRING_LIST *StringList
+ )
+/*++
+
+Routine Description:
+
+ Prints out the string list
+
+Arguments:
+
+ StringList The string list to print
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ CHAR8* String;
+ String = StringListToString (StringList);
+ if (String != NULL) {
+ printf ("%s", String);
+ free (String);
+ }
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.h
new file mode 100644
index 00000000..937abcd9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/StringFuncs.h
@@ -0,0 +1,244 @@
+/** @file
+String routines implementation
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_STRING_FUNCS_H
+#define _EFI_STRING_FUNCS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Common/UefiBaseTypes.h>
+
+//
+// Common data structures
+//
+typedef struct {
+ UINTN Count;
+ //
+ // Actually this array can be 0 or more items (based on Count)
+ //
+ CHAR8* Strings[1];
+} STRING_LIST;
+
+
+//
+// Functions declarations
+//
+
+CHAR8*
+CloneString (
+ IN CHAR8 *String
+ )
+;
+/**
+
+Routine Description:
+
+ Allocates a new string and copies 'String' to clone it
+
+Arguments:
+
+ String The string to clone
+
+Returns:
+
+ CHAR8* - NULL if there are not enough resources
+
+**/
+
+
+EFI_STATUS
+StripInfDscStringInPlace (
+ IN CHAR8 *String
+ )
+;
+/**
+
+Routine Description:
+
+ Remove all comments, leading and trailing whitespace from the string.
+
+Arguments:
+
+ String The string to 'strip'
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+STRING_LIST*
+SplitStringByWhitespace (
+ IN CHAR8 *String
+ )
+;
+/**
+
+Routine Description:
+
+ Creates and returns a 'split' STRING_LIST by splitting the string
+ on whitespace boundaries.
+
+Arguments:
+
+ String The string to 'split'
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+STRING_LIST*
+NewStringList (
+ )
+;
+/**
+
+Routine Description:
+
+ Creates a new STRING_LIST with 0 strings.
+
+Returns:
+
+ STRING_LIST* - Null if there is not enough resources to create the object.
+
+**/
+
+
+EFI_STATUS
+AppendCopyOfStringToList (
+ IN OUT STRING_LIST **StringList,
+ IN CHAR8 *String
+ )
+;
+/**
+
+Routine Description:
+
+ Adds String to StringList. A new copy of String is made before it is
+ added to StringList.
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+EFI_STATUS
+RemoveLastStringFromList (
+ IN STRING_LIST *StringList
+ )
+;
+/**
+
+Routine Description:
+
+ Removes the last string from StringList and frees the memory associated
+ with it.
+
+Arguments:
+
+ StringList The string list to remove the string from
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+STRING_LIST*
+AllocateStringListStruct (
+ IN UINTN StringCount
+ )
+;
+/**
+
+Routine Description:
+
+ Allocates a STRING_LIST structure that can store StringCount strings.
+
+Arguments:
+
+ StringCount The number of strings that need to be stored
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+VOID
+FreeStringList (
+ IN STRING_LIST *StringList
+ )
+;
+/**
+
+Routine Description:
+
+ Frees all memory associated with StringList.
+
+Arguments:
+
+ StringList The string list to free
+
+Returns:
+
+ EFI_STATUS
+
+**/
+
+
+CHAR8*
+StringListToString (
+ IN STRING_LIST *StringList
+ )
+;
+/**
+
+Routine Description:
+
+ Generates a string that represents the STRING_LIST
+
+Arguments:
+
+ StringList The string list to convert to a string
+
+Returns:
+
+ CHAR8* - The string list represented with a single string. The returned
+ string must be freed by the caller.
+
+**/
+
+
+VOID
+PrintStringList (
+ IN STRING_LIST *StringList
+ )
+;
+/**
+
+Routine Description:
+
+ Prints out the string list
+
+Arguments:
+
+ StringList The string list to print
+
+**/
+
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/TianoCompress.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/TianoCompress.c
new file mode 100644
index 00000000..b5aea760
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/TianoCompress.c
@@ -0,0 +1,1746 @@
+/** @file
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman
+coding. LZ77 transforms the source data into a sequence of Original Characters
+and Pointers to repeated strings. This sequence is further divided into Blocks
+and Huffman codings are applied to each Block.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Compress.h"
+
+//
+// Macro Definitions
+//
+#undef UINT8_MAX
+typedef INT32 NODE;
+#define UINT8_MAX 0xff
+#define UINT8_BIT 8
+#define THRESHOLD 3
+#define INIT_CRC 0
+#define WNDBIT 19
+#define WNDSIZ (1U << WNDBIT)
+#define MAXMATCH 256
+#define BLKSIZ (1U << 14) // 16 * 1024U
+#define PERC_FLAG 0x80000000U
+#define CODE_BIT 16
+#define NIL 0
+#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
+#define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
+#define CRCPOLY 0xA001
+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
+
+//
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set
+//
+#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9
+#define NP (WNDBIT + 1)
+#define PBIT 5
+#define NT (CODE_BIT + 3)
+#define TBIT 5
+#if NT > NP
+#define NPT NT
+#else
+#define NPT NP
+#endif
+//
+// Function Prototypes
+//
+
+STATIC
+VOID
+PutDword(
+ IN UINT32 Data
+ );
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+ VOID
+ );
+
+STATIC
+VOID
+FreeMemory (
+ VOID
+ );
+
+STATIC
+VOID
+InitSlide (
+ VOID
+ );
+
+STATIC
+NODE
+Child (
+ IN NODE NodeQ,
+ IN UINT8 CharC
+ );
+
+STATIC
+VOID
+MakeChild (
+ IN NODE NodeQ,
+ IN UINT8 CharC,
+ IN NODE NodeR
+ );
+
+STATIC
+VOID
+Split (
+ IN NODE Old
+ );
+
+STATIC
+VOID
+InsertNode (
+ VOID
+ );
+
+STATIC
+VOID
+DeleteNode (
+ VOID
+ );
+
+STATIC
+VOID
+GetNextMatch (
+ VOID
+ );
+
+STATIC
+EFI_STATUS
+Encode (
+ VOID
+ );
+
+STATIC
+VOID
+CountTFreq (
+ VOID
+ );
+
+STATIC
+VOID
+WritePTLen (
+ IN INT32 Number,
+ IN INT32 nbit,
+ IN INT32 Special
+ );
+
+STATIC
+VOID
+WriteCLen (
+ VOID
+ );
+
+STATIC
+VOID
+EncodeC (
+ IN INT32 Value
+ );
+
+STATIC
+VOID
+EncodeP (
+ IN UINT32 Value
+ );
+
+STATIC
+VOID
+SendBlock (
+ VOID
+ );
+
+STATIC
+VOID
+Output (
+ IN UINT32 c,
+ IN UINT32 p
+ );
+
+STATIC
+VOID
+HufEncodeStart (
+ VOID
+ );
+
+STATIC
+VOID
+HufEncodeEnd (
+ VOID
+ );
+
+STATIC
+VOID
+MakeCrcTable (
+ VOID
+ );
+
+STATIC
+VOID
+PutBits (
+ IN INT32 Number,
+ IN UINT32 Value
+ );
+
+STATIC
+INT32
+FreadCrc (
+ OUT UINT8 *Pointer,
+ IN INT32 Number
+ );
+
+STATIC
+VOID
+InitPutBits (
+ VOID
+ );
+
+STATIC
+VOID
+CountLen (
+ IN INT32 Index
+ );
+
+STATIC
+VOID
+MakeLen (
+ IN INT32 Root
+ );
+
+STATIC
+VOID
+DownHeap (
+ IN INT32 Index
+ );
+
+STATIC
+VOID
+MakeCode (
+ IN INT32 Number,
+ IN UINT8 Len[ ],
+ OUT UINT16 Code[]
+ );
+
+STATIC
+INT32
+MakeTree (
+ IN INT32 NParm,
+ IN UINT16 FreqParm[],
+ OUT UINT8 LenParm[ ],
+ OUT UINT16 CodeParm[]
+ );
+
+//
+// Global Variables
+//
+STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
+
+STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
+STATIC INT16 mHeap[NC + 1];
+STATIC INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
+STATIC UINT32 mCompSize, mOrigSize;
+
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],
+ mCFreq[2 * NC - 1], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
+
+STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
+
+//
+// functions
+//
+EFI_STATUS
+TianoCompress (
+ IN UINT8 *SrcBuffer,
+ IN UINT32 SrcSize,
+ IN UINT8 *DstBuffer,
+ IN OUT UINT32 *DstSize
+ )
+/*++
+
+Routine Description:
+
+ The internal implementation of [Efi/Tiano]Compress().
+
+Arguments:
+
+ SrcBuffer - The buffer storing the source data
+ SrcSize - The size of source data
+ DstBuffer - The buffer to store the compressed data
+ DstSize - On input, the size of DstBuffer; On output,
+ the size of the actual compressed data.
+ Version - The version of de/compression algorithm.
+ Version 1 for UEFI 2.0 de/compression algorithm.
+ Version 2 for Tiano de/compression algorithm.
+
+Returns:
+
+ EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
+ DstSize contains the size needed.
+ EFI_SUCCESS - Compression is successful.
+ EFI_OUT_OF_RESOURCES - No resource to complete function.
+ EFI_INVALID_PARAMETER - Parameter supplied is wrong.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Initializations
+ //
+ mBufSiz = 0;
+ mBuf = NULL;
+ mText = NULL;
+ mLevel = NULL;
+ mChildCount = NULL;
+ mPosition = NULL;
+ mParent = NULL;
+ mPrev = NULL;
+ mNext = NULL;
+
+ mSrc = SrcBuffer;
+ mSrcUpperLimit = mSrc + SrcSize;
+ mDst = DstBuffer;
+ mDstUpperLimit = mDst +*DstSize;
+
+ PutDword (0L);
+ PutDword (0L);
+
+ MakeCrcTable ();
+
+ mOrigSize = mCompSize = 0;
+ mCrc = INIT_CRC;
+
+ //
+ // Compress it
+ //
+ Status = Encode ();
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Null terminate the compressed data
+ //
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = 0;
+ }
+ //
+ // Fill in compressed size and original size
+ //
+ mDst = DstBuffer;
+ PutDword (mCompSize + 1);
+ PutDword (mOrigSize);
+
+ //
+ // Return
+ //
+ if (mCompSize + 1 + 8 > *DstSize) {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_SUCCESS;
+ }
+
+}
+
+STATIC
+VOID
+PutDword (
+ IN UINT32 Data
+ )
+/*++
+
+Routine Description:
+
+ Put a dword to output stream
+
+Arguments:
+
+ Data - the dword to put
+
+Returns: (VOID)
+
+--*/
+{
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);
+ }
+}
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Allocate memory spaces for data structures used in compression process
+
+Arguments:
+ VOID
+
+Returns:
+
+ EFI_SUCCESS - Memory is allocated successfully
+ EFI_OUT_OF_RESOURCES - Allocation fails
+
+--*/
+{
+ UINT32 Index;
+
+ mText = malloc (WNDSIZ * 2 + MAXMATCH);
+ if (mText == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {
+ mText[Index] = 0;
+ }
+
+ mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
+ mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
+ mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
+ mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
+ mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
+ mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
+ if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||
+ mParent == NULL || mPrev == NULL || mNext == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mBufSiz = BLKSIZ;
+ mBuf = malloc (mBufSiz);
+ while (mBuf == NULL) {
+ mBufSiz = (mBufSiz / 10U) * 9U;
+ if (mBufSiz < 4 * 1024U) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mBuf = malloc (mBufSiz);
+ }
+
+ mBuf[0] = 0;
+
+ return EFI_SUCCESS;
+}
+
+VOID
+FreeMemory (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Called when compression is completed to free memory previously allocated.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ if (mText != NULL) {
+ free (mText);
+ }
+
+ if (mLevel != NULL) {
+ free (mLevel);
+ }
+
+ if (mChildCount != NULL) {
+ free (mChildCount);
+ }
+
+ if (mPosition != NULL) {
+ free (mPosition);
+ }
+
+ if (mParent != NULL) {
+ free (mParent);
+ }
+
+ if (mPrev != NULL) {
+ free (mPrev);
+ }
+
+ if (mNext != NULL) {
+ free (mNext);
+ }
+
+ if (mBuf != NULL) {
+ free (mBuf);
+ }
+
+ return ;
+}
+
+STATIC
+VOID
+InitSlide (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize String Info Log data structures
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE Index;
+
+ for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) {
+ mLevel[Index] = 1;
+ mPosition[Index] = NIL; /* sentinel */
+ }
+
+ for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) {
+ mParent[Index] = NIL;
+ }
+
+ mAvail = 1;
+ for (Index = 1; Index < WNDSIZ - 1; Index++) {
+ mNext[Index] = (NODE) (Index + 1);
+ }
+
+ mNext[WNDSIZ - 1] = NIL;
+ for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) {
+ mNext[Index] = NIL;
+ }
+}
+
+STATIC
+NODE
+Child (
+ IN NODE NodeQ,
+ IN UINT8 CharC
+ )
+/*++
+
+Routine Description:
+
+ Find child node given the parent node and the edge character
+
+Arguments:
+
+ NodeQ - the parent node
+ CharC - the edge character
+
+Returns:
+
+ The child node (NIL if not found)
+
+--*/
+{
+ NODE NodeR;
+
+ NodeR = mNext[HASH (NodeQ, CharC)];
+ //
+ // sentinel
+ //
+ mParent[NIL] = NodeQ;
+ while (mParent[NodeR] != NodeQ) {
+ NodeR = mNext[NodeR];
+ }
+
+ return NodeR;
+}
+
+STATIC
+VOID
+MakeChild (
+ IN NODE Parent,
+ IN UINT8 CharC,
+ IN NODE Child
+ )
+/*++
+
+Routine Description:
+
+ Create a new child for a given parent node.
+
+Arguments:
+
+ Parent - the parent node
+ CharC - the edge character
+ Child - the child node
+
+Returns: (VOID)
+
+--*/
+{
+ NODE Node1;
+ NODE Node2;
+
+ Node1 = (NODE) HASH (Parent, CharC);
+ Node2 = mNext[Node1];
+ mNext[Node1] = Child;
+ mNext[Child] = Node2;
+ mPrev[Node2] = Child;
+ mPrev[Child] = Node1;
+ mParent[Child] = Parent;
+ mChildCount[Parent]++;
+}
+
+STATIC
+VOID
+Split (
+ NODE Old
+ )
+/*++
+
+Routine Description:
+
+ Split a node.
+
+Arguments:
+
+ Old - the node to split
+
+Returns: (VOID)
+
+--*/
+{
+ NODE New;
+ NODE TempNode;
+
+ New = mAvail;
+ mAvail = mNext[New];
+ mChildCount[New] = 0;
+ TempNode = mPrev[Old];
+ mPrev[New] = TempNode;
+ mNext[TempNode] = New;
+ TempNode = mNext[Old];
+ mNext[New] = TempNode;
+ mPrev[TempNode] = New;
+ mParent[New] = mParent[Old];
+ mLevel[New] = (UINT8) mMatchLen;
+ mPosition[New] = mPos;
+ MakeChild (New, mText[mMatchPos + mMatchLen], Old);
+ MakeChild (New, mText[mPos + mMatchLen], mPos);
+}
+
+STATIC
+VOID
+InsertNode (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Insert string info for current position into the String Info Log
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE NodeQ;
+ NODE NodeR;
+ NODE Index2;
+ NODE NodeT;
+ UINT8 CharC;
+ UINT8 *t1;
+ UINT8 *t2;
+
+ if (mMatchLen >= 4) {
+ //
+ // We have just got a long match, the target tree
+ // can be located by MatchPos + 1. Traverse the tree
+ // from bottom up to get to a proper starting point.
+ // The usage of PERC_FLAG ensures proper node deletion
+ // in DeleteNode() later.
+ //
+ mMatchLen--;
+ NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ);
+ NodeQ = mParent[NodeR];
+ while (NodeQ == NIL) {
+ NodeR = mNext[NodeR];
+ NodeQ = mParent[NodeR];
+ }
+
+ while (mLevel[NodeQ] >= mMatchLen) {
+ NodeR = NodeQ;
+ NodeQ = mParent[NodeQ];
+ }
+
+ NodeT = NodeQ;
+ while (mPosition[NodeT] < 0) {
+ mPosition[NodeT] = mPos;
+ NodeT = mParent[NodeT];
+ }
+
+ if (NodeT < WNDSIZ) {
+ mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG);
+ }
+ } else {
+ //
+ // Locate the target tree
+ //
+ NodeQ = (NODE) (mText[mPos] + WNDSIZ);
+ CharC = mText[mPos + 1];
+ NodeR = Child (NodeQ, CharC);
+ if (NodeR == NIL) {
+ MakeChild (NodeQ, CharC, mPos);
+ mMatchLen = 1;
+ return ;
+ }
+
+ mMatchLen = 2;
+ }
+ //
+ // Traverse down the tree to find a match.
+ // Update Position value along the route.
+ // Node split or creation is involved.
+ //
+ for (;;) {
+ if (NodeR >= WNDSIZ) {
+ Index2 = MAXMATCH;
+ mMatchPos = NodeR;
+ } else {
+ Index2 = mLevel[NodeR];
+ mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
+ }
+
+ if (mMatchPos >= mPos) {
+ mMatchPos -= WNDSIZ;
+ }
+
+ t1 = &mText[mPos + mMatchLen];
+ t2 = &mText[mMatchPos + mMatchLen];
+ while (mMatchLen < Index2) {
+ if (*t1 != *t2) {
+ Split (NodeR);
+ return ;
+ }
+
+ mMatchLen++;
+ t1++;
+ t2++;
+ }
+
+ if (mMatchLen >= MAXMATCH) {
+ break;
+ }
+
+ mPosition[NodeR] = mPos;
+ NodeQ = NodeR;
+ NodeR = Child (NodeQ, *t1);
+ if (NodeR == NIL) {
+ MakeChild (NodeQ, *t1, mPos);
+ return ;
+ }
+
+ mMatchLen++;
+ }
+
+ NodeT = mPrev[NodeR];
+ mPrev[mPos] = NodeT;
+ mNext[NodeT] = mPos;
+ NodeT = mNext[NodeR];
+ mNext[mPos] = NodeT;
+ mPrev[NodeT] = mPos;
+ mParent[mPos] = NodeQ;
+ mParent[NodeR] = NIL;
+
+ //
+ // Special usage of 'next'
+ //
+ mNext[NodeR] = mPos;
+
+}
+
+STATIC
+VOID
+DeleteNode (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Delete outdated string info. (The Usage of PERC_FLAG
+ ensures a clean deletion)
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE NodeQ;
+ NODE NodeR;
+ NODE NodeS;
+ NODE NodeT;
+ NODE NodeU;
+
+ if (mParent[mPos] == NIL) {
+ return ;
+ }
+
+ NodeR = mPrev[mPos];
+ NodeS = mNext[mPos];
+ mNext[NodeR] = NodeS;
+ mPrev[NodeS] = NodeR;
+ NodeR = mParent[mPos];
+ mParent[mPos] = NIL;
+ if (NodeR >= WNDSIZ) {
+ return ;
+ }
+
+ mChildCount[NodeR]--;
+ if (mChildCount[NodeR] > 1) {
+ return ;
+ }
+
+ NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
+ if (NodeT >= mPos) {
+ NodeT -= WNDSIZ;
+ }
+
+ NodeS = NodeT;
+ NodeQ = mParent[NodeR];
+ NodeU = mPosition[NodeQ];
+ while (NodeU & (UINT32) PERC_FLAG) {
+ NodeU &= (UINT32)~PERC_FLAG;
+ if (NodeU >= mPos) {
+ NodeU -= WNDSIZ;
+ }
+
+ if (NodeU > NodeS) {
+ NodeS = NodeU;
+ }
+
+ mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ);
+ NodeQ = mParent[NodeQ];
+ NodeU = mPosition[NodeQ];
+ }
+
+ if (NodeQ < WNDSIZ) {
+ if (NodeU >= mPos) {
+ NodeU -= WNDSIZ;
+ }
+
+ if (NodeU > NodeS) {
+ NodeS = NodeU;
+ }
+
+ mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG);
+ }
+
+ NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]);
+ NodeT = mPrev[NodeS];
+ NodeU = mNext[NodeS];
+ mNext[NodeT] = NodeU;
+ mPrev[NodeU] = NodeT;
+ NodeT = mPrev[NodeR];
+ mNext[NodeT] = NodeS;
+ mPrev[NodeS] = NodeT;
+ NodeT = mNext[NodeR];
+ mPrev[NodeT] = NodeS;
+ mNext[NodeS] = NodeT;
+ mParent[NodeS] = mParent[NodeR];
+ mParent[NodeR] = NIL;
+ mNext[NodeR] = mAvail;
+ mAvail = NodeR;
+}
+
+STATIC
+VOID
+GetNextMatch (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Advance the current position (read in new data if needed).
+ Delete outdated string info. Find a match string for current position.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Number;
+
+ mRemainder--;
+ mPos++;
+ if (mPos == WNDSIZ * 2) {
+ memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);
+ Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);
+ mRemainder += Number;
+ mPos = WNDSIZ;
+ }
+
+ DeleteNode ();
+ InsertNode ();
+}
+
+STATIC
+EFI_STATUS
+Encode (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ The main controlling routine for compression process.
+
+Arguments: (VOID)
+
+Returns:
+
+ EFI_SUCCESS - The compression is successful
+ EFI_OUT_0F_RESOURCES - Not enough memory for compression process
+
+--*/
+{
+ EFI_STATUS Status;
+ INT32 LastMatchLen;
+ NODE LastMatchPos;
+
+ Status = AllocateMemory ();
+ if (EFI_ERROR (Status)) {
+ FreeMemory ();
+ return Status;
+ }
+
+ InitSlide ();
+
+ HufEncodeStart ();
+
+ mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);
+
+ mMatchLen = 0;
+ mPos = WNDSIZ;
+ InsertNode ();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ while (mRemainder > 0) {
+ LastMatchLen = mMatchLen;
+ LastMatchPos = mMatchPos;
+ GetNextMatch ();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
+ //
+ // Not enough benefits are gained by outputting a pointer,
+ // so just output the original character
+ //
+ Output (mText[mPos - 1], 0);
+
+ } else {
+
+ if (LastMatchLen == THRESHOLD) {
+ if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) {
+ Output (mText[mPos - 1], 0);
+ continue;
+ }
+ }
+ //
+ // Outputting a pointer is beneficial enough, do it.
+ //
+ Output (
+ LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
+ (mPos - LastMatchPos - 2) & (WNDSIZ - 1)
+ );
+ LastMatchLen--;
+ while (LastMatchLen > 0) {
+ GetNextMatch ();
+ LastMatchLen--;
+ }
+
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+ }
+ }
+
+ HufEncodeEnd ();
+ FreeMemory ();
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+CountTFreq (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Count the frequencies for the Extra Set
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+ INT32 Number;
+ INT32 Count;
+
+ for (Index = 0; Index < NT; Index++) {
+ mTFreq[Index] = 0;
+ }
+
+ Number = NC;
+ while (Number > 0 && mCLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mCLen[Index++];
+ if (Index3 == 0) {
+ Count = 1;
+ while (Index < Number && mCLen[Index] == 0) {
+ Index++;
+ Count++;
+ }
+
+ if (Count <= 2) {
+ mTFreq[0] = (UINT16) (mTFreq[0] + Count);
+ } else if (Count <= 18) {
+ mTFreq[1]++;
+ } else if (Count == 19) {
+ mTFreq[0]++;
+ mTFreq[1]++;
+ } else {
+ mTFreq[2]++;
+ }
+ } else {
+ mTFreq[Index3 + 2]++;
+ }
+ }
+}
+
+STATIC
+VOID
+WritePTLen (
+ IN INT32 Number,
+ IN INT32 nbit,
+ IN INT32 Special
+ )
+/*++
+
+Routine Description:
+
+ Outputs the code length array for the Extra Set or the Position Set.
+
+Arguments:
+
+ Number - the number of symbols
+ nbit - the number of bits needed to represent 'n'
+ Special - the special symbol that needs to be take care of
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+
+ while (Number > 0 && mPTLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ PutBits (nbit, Number);
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mPTLen[Index++];
+ if (Index3 <= 6) {
+ PutBits (3, Index3);
+ } else {
+ PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2);
+ }
+
+ if (Index == Special) {
+ while (Index < 6 && mPTLen[Index] == 0) {
+ Index++;
+ }
+
+ PutBits (2, (Index - 3) & 3);
+ }
+ }
+}
+
+STATIC
+VOID
+WriteCLen (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Outputs the code length array for Char&Length Set
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+ INT32 Number;
+ INT32 Count;
+
+ Number = NC;
+ while (Number > 0 && mCLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ PutBits (CBIT, Number);
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mCLen[Index++];
+ if (Index3 == 0) {
+ Count = 1;
+ while (Index < Number && mCLen[Index] == 0) {
+ Index++;
+ Count++;
+ }
+
+ if (Count <= 2) {
+ for (Index3 = 0; Index3 < Count; Index3++) {
+ PutBits (mPTLen[0], mPTCode[0]);
+ }
+ } else if (Count <= 18) {
+ PutBits (mPTLen[1], mPTCode[1]);
+ PutBits (4, Count - 3);
+ } else if (Count == 19) {
+ PutBits (mPTLen[0], mPTCode[0]);
+ PutBits (mPTLen[1], mPTCode[1]);
+ PutBits (4, 15);
+ } else {
+ PutBits (mPTLen[2], mPTCode[2]);
+ PutBits (CBIT, Count - 20);
+ }
+ } else {
+ PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]);
+ }
+ }
+}
+
+STATIC
+VOID
+EncodeC (
+ IN INT32 Value
+ )
+{
+ PutBits (mCLen[Value], mCCode[Value]);
+}
+
+STATIC
+VOID
+EncodeP (
+ IN UINT32 Value
+ )
+{
+ UINT32 Index;
+ UINT32 NodeQ;
+
+ Index = 0;
+ NodeQ = Value;
+ while (NodeQ) {
+ NodeQ >>= 1;
+ Index++;
+ }
+
+ PutBits (mPTLen[Index], mPTCode[Index]);
+ if (Index > 1) {
+ PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1)));
+ }
+}
+
+STATIC
+VOID
+SendBlock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Huffman code the block and output it.
+
+Arguments:
+ (VOID)
+
+Returns:
+ (VOID)
+
+--*/
+{
+ UINT32 Index;
+ UINT32 Index2;
+ UINT32 Index3;
+ UINT32 Flags;
+ UINT32 Root;
+ UINT32 Pos;
+ UINT32 Size;
+ Flags = 0;
+
+ Root = MakeTree (NC, mCFreq, mCLen, mCCode);
+ Size = mCFreq[Root];
+ PutBits (16, Size);
+ if (Root >= NC) {
+ CountTFreq ();
+ Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);
+ if (Root >= NT) {
+ WritePTLen (NT, TBIT, 3);
+ } else {
+ PutBits (TBIT, 0);
+ PutBits (TBIT, Root);
+ }
+
+ WriteCLen ();
+ } else {
+ PutBits (TBIT, 0);
+ PutBits (TBIT, 0);
+ PutBits (CBIT, 0);
+ PutBits (CBIT, Root);
+ }
+
+ Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);
+ if (Root >= NP) {
+ WritePTLen (NP, PBIT, -1);
+ } else {
+ PutBits (PBIT, 0);
+ PutBits (PBIT, Root);
+ }
+
+ Pos = 0;
+ for (Index = 0; Index < Size; Index++) {
+ if (Index % UINT8_BIT == 0) {
+ Flags = mBuf[Pos++];
+ } else {
+ Flags <<= 1;
+ }
+
+ if (Flags & (1U << (UINT8_BIT - 1))) {
+ EncodeC (mBuf[Pos++] + (1U << UINT8_BIT));
+ Index3 = mBuf[Pos++];
+ for (Index2 = 0; Index2 < 3; Index2++) {
+ Index3 <<= UINT8_BIT;
+ Index3 += mBuf[Pos++];
+ }
+
+ EncodeP (Index3);
+ } else {
+ EncodeC (mBuf[Pos++]);
+ }
+ }
+
+ for (Index = 0; Index < NC; Index++) {
+ mCFreq[Index] = 0;
+ }
+
+ for (Index = 0; Index < NP; Index++) {
+ mPFreq[Index] = 0;
+ }
+}
+
+STATIC
+VOID
+Output (
+ IN UINT32 CharC,
+ IN UINT32 Pos
+ )
+/*++
+
+Routine Description:
+
+ Outputs an Original Character or a Pointer
+
+Arguments:
+
+ CharC - The original character or the 'String Length' element of a Pointer
+ Pos - The 'Position' field of a Pointer
+
+Returns: (VOID)
+
+--*/
+{
+ STATIC UINT32 CPos;
+
+ if ((mOutputMask >>= 1) == 0) {
+ mOutputMask = 1U << (UINT8_BIT - 1);
+ //
+ // Check the buffer overflow per outputing UINT8_BIT symbols
+ // which is an Original Character or a Pointer. The biggest
+ // symbol is a Pointer which occupies 5 bytes.
+ //
+ if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) {
+ SendBlock ();
+ mOutputPos = 0;
+ }
+
+ CPos = mOutputPos++;
+ mBuf[CPos] = 0;
+ }
+
+ mBuf[mOutputPos++] = (UINT8) CharC;
+ mCFreq[CharC]++;
+ if (CharC >= (1U << UINT8_BIT)) {
+ mBuf[CPos] |= mOutputMask;
+ mBuf[mOutputPos++] = (UINT8) (Pos >> 24);
+ mBuf[mOutputPos++] = (UINT8) (Pos >> 16);
+ mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT));
+ mBuf[mOutputPos++] = (UINT8) Pos;
+ CharC = 0;
+ while (Pos) {
+ Pos >>= 1;
+ CharC++;
+ }
+
+ mPFreq[CharC]++;
+ }
+}
+
+STATIC
+VOID
+HufEncodeStart (
+ VOID
+ )
+{
+ INT32 Index;
+
+ for (Index = 0; Index < NC; Index++) {
+ mCFreq[Index] = 0;
+ }
+
+ for (Index = 0; Index < NP; Index++) {
+ mPFreq[Index] = 0;
+ }
+
+ mOutputPos = mOutputMask = 0;
+ InitPutBits ();
+ return ;
+}
+
+STATIC
+VOID
+HufEncodeEnd (
+ VOID
+ )
+{
+ SendBlock ();
+
+ //
+ // Flush remaining bits
+ //
+ PutBits (UINT8_BIT - 1, 0);
+
+ return ;
+}
+
+STATIC
+VOID
+MakeCrcTable (
+ VOID
+ )
+{
+ UINT32 Index;
+ UINT32 Index2;
+ UINT32 Temp;
+
+ for (Index = 0; Index <= UINT8_MAX; Index++) {
+ Temp = Index;
+ for (Index2 = 0; Index2 < UINT8_BIT; Index2++) {
+ if (Temp & 1) {
+ Temp = (Temp >> 1) ^ CRCPOLY;
+ } else {
+ Temp >>= 1;
+ }
+ }
+
+ mCrcTable[Index] = (UINT16) Temp;
+ }
+}
+
+STATIC
+VOID
+PutBits (
+ IN INT32 Number,
+ IN UINT32 Value
+ )
+/*++
+
+Routine Description:
+
+ Outputs rightmost n bits of x
+
+Arguments:
+
+ Number - the rightmost n bits of the data is used
+ x - the data
+
+Returns: (VOID)
+
+--*/
+{
+ UINT8 Temp;
+
+ while (Number >= mBitCount) {
+ //
+ // Number -= mBitCount should never equal to 32
+ //
+ Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount)));
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = Temp;
+ }
+
+ mCompSize++;
+ mSubBitBuf = 0;
+ mBitCount = UINT8_BIT;
+ }
+
+ mSubBitBuf |= Value << (mBitCount -= Number);
+}
+
+STATIC
+INT32
+FreadCrc (
+ OUT UINT8 *Pointer,
+ IN INT32 Number
+ )
+/*++
+
+Routine Description:
+
+ Read in source data
+
+Arguments:
+
+ Pointer - the buffer to hold the data
+ Number - number of bytes to read
+
+Returns:
+
+ number of bytes actually read
+
+--*/
+{
+ INT32 Index;
+
+ for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) {
+ *Pointer++ = *mSrc++;
+ }
+
+ Number = Index;
+
+ Pointer -= Number;
+ mOrigSize += Number;
+ Index--;
+ while (Index >= 0) {
+ UPDATE_CRC (*Pointer++);
+ Index--;
+ }
+
+ return Number;
+}
+
+STATIC
+VOID
+InitPutBits (
+ VOID
+ )
+{
+ mBitCount = UINT8_BIT;
+ mSubBitBuf = 0;
+}
+
+STATIC
+VOID
+CountLen (
+ IN INT32 Index
+ )
+/*++
+
+Routine Description:
+
+ Count the number of each code length for a Huffman tree.
+
+Arguments:
+
+ Index - the top node
+
+Returns: (VOID)
+
+--*/
+{
+ STATIC INT32 Depth = 0;
+
+ if (Index < mN) {
+ mLenCnt[(Depth < 16) ? Depth : 16]++;
+ } else {
+ Depth++;
+ CountLen (mLeft[Index]);
+ CountLen (mRight[Index]);
+ Depth--;
+ }
+}
+
+STATIC
+VOID
+MakeLen (
+ IN INT32 Root
+ )
+/*++
+
+Routine Description:
+
+ Create code length array for a Huffman tree
+
+Arguments:
+
+ Root - the root of the tree
+
+Returns:
+
+ VOID
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+ UINT32 Cum;
+
+ for (Index = 0; Index <= 16; Index++) {
+ mLenCnt[Index] = 0;
+ }
+
+ CountLen (Root);
+
+ //
+ // Adjust the length count array so that
+ // no code will be generated longer than its designated length
+ //
+ Cum = 0;
+ for (Index = 16; Index > 0; Index--) {
+ Cum += mLenCnt[Index] << (16 - Index);
+ }
+
+ while (Cum != (1U << 16)) {
+ mLenCnt[16]--;
+ for (Index = 15; Index > 0; Index--) {
+ if (mLenCnt[Index] != 0) {
+ mLenCnt[Index]--;
+ mLenCnt[Index + 1] += 2;
+ break;
+ }
+ }
+
+ Cum--;
+ }
+
+ for (Index = 16; Index > 0; Index--) {
+ Index3 = mLenCnt[Index];
+ Index3--;
+ while (Index3 >= 0) {
+ mLen[*mSortPtr++] = (UINT8) Index;
+ Index3--;
+ }
+ }
+}
+
+STATIC
+VOID
+DownHeap (
+ IN INT32 Index
+ )
+{
+ INT32 Index2;
+ INT32 Index3;
+
+ //
+ // priority queue: send Index-th entry down heap
+ //
+ Index3 = mHeap[Index];
+ Index2 = 2 * Index;
+ while (Index2 <= mHeapSize) {
+ if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) {
+ Index2++;
+ }
+
+ if (mFreq[Index3] <= mFreq[mHeap[Index2]]) {
+ break;
+ }
+
+ mHeap[Index] = mHeap[Index2];
+ Index = Index2;
+ Index2 = 2 * Index;
+ }
+
+ mHeap[Index] = (INT16) Index3;
+}
+
+STATIC
+VOID
+MakeCode (
+ IN INT32 Number,
+ IN UINT8 Len[ ],
+ OUT UINT16 Code[]
+ )
+/*++
+
+Routine Description:
+
+ Assign code to each symbol based on the code length array
+
+Arguments:
+
+ Number - number of symbols
+ Len - the code length array
+ Code - stores codes for each symbol
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ UINT16 Start[18];
+
+ Start[1] = 0;
+ for (Index = 1; Index <= 16; Index++) {
+ Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1);
+ }
+
+ for (Index = 0; Index < Number; Index++) {
+ Code[Index] = Start[Len[Index]]++;
+ }
+}
+
+STATIC
+INT32
+MakeTree (
+ IN INT32 NParm,
+ IN UINT16 FreqParm[],
+ OUT UINT8 LenParm[ ],
+ OUT UINT16 CodeParm[]
+ )
+/*++
+
+Routine Description:
+
+ Generates Huffman codes given a frequency distribution of symbols
+
+Arguments:
+
+ NParm - number of symbols
+ FreqParm - frequency of each symbol
+ LenParm - code length for each symbol
+ CodeParm - code for each symbol
+
+Returns:
+
+ Root of the Huffman tree.
+
+--*/
+{
+ INT32 Index;
+ INT32 Index2;
+ INT32 Index3;
+ INT32 Avail;
+
+ //
+ // make tree, calculate len[], return root
+ //
+ mN = NParm;
+ mFreq = FreqParm;
+ mLen = LenParm;
+ Avail = mN;
+ mHeapSize = 0;
+ mHeap[1] = 0;
+ for (Index = 0; Index < mN; Index++) {
+ mLen[Index] = 0;
+ if (mFreq[Index]) {
+ mHeapSize++;
+ mHeap[mHeapSize] = (INT16) Index;
+ }
+ }
+
+ if (mHeapSize < 2) {
+ CodeParm[mHeap[1]] = 0;
+ return mHeap[1];
+ }
+
+ for (Index = mHeapSize / 2; Index >= 1; Index--) {
+ //
+ // make priority queue
+ //
+ DownHeap (Index);
+ }
+
+ mSortPtr = CodeParm;
+ do {
+ Index = mHeap[1];
+ if (Index < mN) {
+ *mSortPtr++ = (UINT16) Index;
+ }
+
+ mHeap[1] = mHeap[mHeapSize--];
+ DownHeap (1);
+ Index2 = mHeap[1];
+ if (Index2 < mN) {
+ *mSortPtr++ = (UINT16) Index2;
+ }
+
+ Index3 = Avail++;
+ mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]);
+ mHeap[1] = (INT16) Index3;
+ DownHeap (1);
+ mLeft[Index3] = (UINT16) Index;
+ mRight[Index3] = (UINT16) Index2;
+ } while (mHeapSize > 1);
+
+ mSortPtr = CodeParm;
+ MakeLen (Index3);
+ MakeCode (NParm, LenParm, CodeParm);
+
+ //
+ // return root
+ //
+ return Index3;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/WinNtInclude.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/WinNtInclude.h
new file mode 100644
index 00000000..b3c58497
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Common/WinNtInclude.h
@@ -0,0 +1,78 @@
+/** @file
+Include file for the WinNt Library
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __WIN_NT_INCLUDE_H__
+#define __WIN_NT_INCLUDE_H__
+
+#define GUID _WINNT_DUP_GUID_____
+#define _LIST_ENTRY _WINNT_DUP_LIST_ENTRY_FORWARD
+#define LIST_ENTRY _WINNT_DUP_LIST_ENTRY
+
+#ifndef VBOX
+#if (_MSC_VER < 1800)
+#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement
+#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement
+#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64
+#endif
+#endif
+
+#undef UNALIGNED
+#undef CONST
+#undef VOID
+
+#ifndef __GNUC__
+# ifdef VBOX
+# define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION
+# endif
+#ifdef VBOX
+#include <iprt/win/windows.h>
+#else
+#include "windows.h"
+#endif
+
+//
+// Win32 include files do not compile clean with /W4, so we use the warning
+// pragma to suppress the warnings for Win32 only. This way our code can still
+// compile at /W4 (highest warning level) with /WX (warnings cause build
+// errors).
+//
+#pragma warning(disable : 4115)
+#pragma warning(disable : 4201)
+#pragma warning(disable : 4214)
+#pragma warning(disable : 4028)
+#pragma warning(disable : 4133)
+
+//
+// Set the warnings back on as the EFI code must be /W4.
+//
+#pragma warning(default : 4115)
+#pragma warning(default : 4201)
+#pragma warning(default : 4214)
+
+# ifdef VBOX
+# undef RUNTIME_FUNCTION
+# endif
+#endif
+
+#undef GUID
+#undef _LIST_ENTRY
+#undef LIST_ENTRY
+#undef InterlockedIncrement
+#undef InterlockedDecrement
+#undef InterlockedCompareExchange64
+#undef InterlockedCompareExchangePointer
+
+#define VOID void
+
+//
+// Prevent collisions with Windows API name macros that deal with Unicode/Not issues
+//
+#undef LoadImage
+#undef CreateEvent
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePath.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePath.c
new file mode 100644
index 00000000..7c45b367
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePath.c
@@ -0,0 +1,194 @@
+/** @file
+ Definition for Device Path Tool.
+
+Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+//
+// Utility Name
+//
+#define UTILITY_NAME "DevicePath"
+
+//
+// Utility version information
+//
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+EFI_GUID gEfiDebugPortProtocolGuid = DEVICE_PATH_MESSAGING_DEBUGPORT;
+EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID;
+EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID;
+EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID;
+EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID;
+EFI_GUID gEfiUartDevicePathGuid = EFI_UART_DEVICE_PATH_GUID;
+EFI_GUID gEfiSasDevicePathGuid = EFI_SAS_DEVICE_PATH_GUID;
+EFI_GUID gEfiVirtualDiskGuid = EFI_VIRTUAL_DISK_GUID;
+EFI_GUID gEfiVirtualCdGuid = EFI_VIRTUAL_CD_GUID;
+EFI_GUID gEfiPersistentVirtualDiskGuid = EFI_PERSISTENT_VIRTUAL_DISK_GUID;
+EFI_GUID gEfiPersistentVirtualCdGuid = EFI_PERSISTENT_VIRTUAL_CD_GUID;
+
+STATIC
+VOID
+Version (
+ VOID
+)
+/*++
+
+Routine Description:
+
+ Displays the standard utility information to SDTOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2017, Intel Corporation. All rights reserved.\n\n");
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " DevicePathString Device Path string is specified, no space character.\n"
+ " Example: \"PciRoot(0)/Pci(0,0)\"\n");
+
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
+}
+
+
+STATIC
+VOID
+PrintMem (
+ CONST VOID *Buffer,
+ UINTN Count
+ )
+{
+ CONST UINT8 *Bytes;
+ UINTN Idx;
+
+ Bytes = Buffer;
+ for (Idx = 0; Idx < Count; Idx++) {
+ printf("0x%02x ", Bytes[Idx]);
+ }
+}
+
+VOID
+Ascii2UnicodeString (
+ CHAR8 *String,
+ CHAR16 *UniString
+ )
+/*++
+
+Routine Description:
+
+ Write ascii string as unicode string format to FILE
+
+Arguments:
+
+ String - Pointer to string that is written to FILE.
+ UniString - Pointer to unicode string
+
+Returns:
+
+ NULL
+
+--*/
+{
+ while (*String != '\0') {
+ *(UniString++) = (CHAR16) *(String++);
+ }
+ //
+ // End the UniString with a NULL.
+ //
+ *UniString = '\0';
+}
+
+int main(int argc, CHAR8 *argv[])
+{
+ CHAR8 * Str;
+ CHAR16* Str16;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No input options specified.");
+ Usage ();
+ return STATUS_ERROR;
+ }
+ if ((stricmp (argv[1], "-h") == 0) || (stricmp (argv[1], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[1], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+ Str = argv[1];
+ if (Str == NULL) {
+ fprintf(stderr, "Invalid option value, Device Path can't be NULL");
+ return STATUS_ERROR;
+ }
+ Str16 = (CHAR16 *)malloc(1024);
+ if (Str16 == NULL) {
+ fprintf(stderr, "Resource, memory cannot be allocated");
+ return STATUS_ERROR;
+ }
+ Ascii2UnicodeString(Str, Str16);
+ DevicePath = UefiDevicePathLibConvertTextToDevicePath(Str16);
+ if (DevicePath == NULL) {
+ fprintf(stderr, "Convert fail, Cannot convert text to a device path");
+ free(Str16);
+ return STATUS_ERROR;
+ }
+ while (!((DevicePath->Type == END_DEVICE_PATH_TYPE) && (DevicePath->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) )
+ {
+ PrintMem (DevicePath, DevicePath->Length[0] | DevicePath->Length[1] << 8);
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePath + (DevicePath->Length[0] | DevicePath->Length[1] << 8));
+ }
+ PrintMem (DevicePath, DevicePath->Length[0] | DevicePath->Length[1] << 8);
+ putchar('\n');
+ free(Str16);
+ return STATUS_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathFromText.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathFromText.c
new file mode 100644
index 00000000..dc49998d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathFromText.c
@@ -0,0 +1,3524 @@
+/** @file
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+/**
+
+ Duplicates a string.
+
+ @param Src Source string.
+
+ @return The duplicated string.
+
+**/
+CHAR16 *
+UefiDevicePathLibStrDuplicate (
+ CONST CHAR16 *Src
+ )
+{
+ return AllocateCopyPool (StrSize (Src), Src);
+}
+
+/**
+
+ Get parameter in a pair of parentheses follow the given node name.
+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+ @param Str Device Path Text.
+ @param NodeName Name of the node.
+
+ @return Parameter text for the node.
+
+**/
+CHAR16 *
+GetParamByNodeName (
+ CHAR16 *Str,
+ CHAR16 *NodeName
+ )
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
+ return NULL;
+ }
+
+ ParamStr = Str + NodeNameLength;
+ if (!IS_LEFT_PARENTH (*ParamStr)) {
+ return NULL;
+ }
+
+ //
+ // Skip the found '(' and find first occurrence of ')'
+ //
+ ParamStr++;
+ ParameterLength = 0;
+ StrPointer = ParamStr;
+ while (!IS_NULL (*StrPointer)) {
+ if (IS_RIGHT_PARENTH (*StrPointer)) {
+ break;
+ }
+ StrPointer++;
+ ParameterLength++;
+ }
+ if (IS_NULL (*StrPointer)) {
+ //
+ // ')' not found
+ //
+ return NULL;
+ }
+
+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+ if (ParamStr == NULL) {
+ return NULL;
+ }
+ //
+ // Terminate the parameter string
+ //
+ ParamStr[ParameterLength] = L'\0';
+
+ return ParamStr;
+}
+
+/**
+ Gets the next parameter string from the list.
+
+ @param List A string list separated by the specified separator
+
+ @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+GetNextParamStr (
+ CHAR16 **List
+ )
+{
+ //
+ // The separator is comma
+ //
+ return SplitStr (List, L',');
+}
+
+/**
+ Get one device node from entire device path text.
+
+ @param DevicePath On input, the current Device Path node; on output, the next device path node
+ @param IsInstanceEnd This node is the end of a device path instance
+
+ @return A device node text or NULL if no more device node available
+
+**/
+CHAR16 *
+GetNextDeviceNodeStr (
+ CHAR16 **DevicePath,
+ BOOLEAN *IsInstanceEnd
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+ UINTN ParenthesesStack;
+
+ Str = *DevicePath;
+ if (IS_NULL (*Str)) {
+ return NULL;
+ }
+
+ //
+ // Skip the leading '/', '(', ')' and ','
+ //
+ while (!IS_NULL (*Str)) {
+ if (!IS_SLASH (*Str) &&
+ !IS_COMMA (*Str) &&
+ !IS_LEFT_PARENTH (*Str) &&
+ !IS_RIGHT_PARENTH (*Str)) {
+ break;
+ }
+ Str++;
+ }
+
+ ReturnStr = Str;
+
+ //
+ // Scan for the separator of this device node, '/' or ','
+ //
+ ParenthesesStack = 0;
+ while (!IS_NULL (*Str)) {
+ if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+ break;
+ }
+
+ if (IS_LEFT_PARENTH (*Str)) {
+ ParenthesesStack++;
+ } else if (IS_RIGHT_PARENTH (*Str)) {
+ ParenthesesStack--;
+ }
+
+ Str++;
+ }
+
+ if (ParenthesesStack != 0) {
+ //
+ // The '(' doesn't pair with ')', invalid device path text
+ //
+ return NULL;
+ }
+
+ if (IS_COMMA (*Str)) {
+ *IsInstanceEnd = TRUE;
+ *Str = L'\0';
+ Str++;
+ } else {
+ *IsInstanceEnd = FALSE;
+ if (!IS_NULL (*Str)) {
+ *Str = L'\0';
+ Str++;
+ }
+ }
+
+ *DevicePath = Str;
+
+ return ReturnStr;
+}
+
+/**
+ Converts a generic text device path node to device path structure.
+
+ @param Type The type of the device path node.
+ @param TextDeviceNode The input text device path node.
+
+ @return A pointer to device path structure.
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextGenericPath (
+ UINT8 Type,
+ CHAR16 *TextDeviceNode
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ CHAR16 *SubtypeStr;
+ CHAR16 *DataStr;
+ UINTN DataLength;
+
+ SubtypeStr = GetNextParamStr (&TextDeviceNode);
+ DataStr = GetNextParamStr (&TextDeviceNode);
+
+ if (DataStr == NULL) {
+ DataLength = 0;
+ } else {
+ DataLength = StrLen (DataStr) / 2;
+ }
+ Node = CreateDeviceNode (
+ Type,
+ (UINT8) Strtoi (SubtypeStr),
+ (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength)
+ );
+
+ StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength);
+ return Node;
+}
+
+/**
+ Converts a generic text device path node to device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+
+ return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode);
+}
+
+/**
+ Converts a generic hardware text device path node to Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHardwarePath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to Hardware PCI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PCI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionStr;
+ CHAR16 *DeviceStr;
+ PCI_DEVICE_PATH *Pci;
+
+ DeviceStr = GetNextParamStr (&TextDeviceNode);
+ FunctionStr = GetNextParamStr (&TextDeviceNode);
+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ (UINT16) sizeof (PCI_DEVICE_PATH)
+ );
+
+ Pci->Function = (UINT8) Strtoi (FunctionStr);
+ Pci->Device = (UINT8) Strtoi (DeviceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+/**
+ Converts a text device path node to Hardware PC card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PC card device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionNumberStr;
+ PCCARD_DEVICE_PATH *Pccard;
+
+ FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+ Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCCARD_DP,
+ (UINT16) sizeof (PCCARD_DEVICE_PATH)
+ );
+
+ Pccard->FunctionNumber = (UINT8) Strtoi (FunctionNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+/**
+ Converts a text device path node to Hardware memory map device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware memory map device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *MemoryTypeStr;
+ CHAR16 *StartingAddressStr;
+ CHAR16 *EndingAddressStr;
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemoryTypeStr = GetNextParamStr (&TextDeviceNode);
+ StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddressStr = GetNextParamStr (&TextDeviceNode);
+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ (UINT16) sizeof (MEMMAP_DEVICE_PATH)
+ );
+
+ MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr);
+ Strtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+ Strtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+/**
+ Converts a text device path node to Vendor device path structure based on the input Type
+ and SubType.
+
+ @param TextDeviceNode The input Text device path node.
+ @param Type The type of device path node.
+ @param SubType The subtype of device path node.
+
+ @return A pointer to the newly-created Vendor device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+ CHAR16 *TextDeviceNode,
+ UINT8 Type,
+ UINT8 SubType
+ )
+{
+ CHAR16 *GuidStr;
+ CHAR16 *DataStr;
+ UINTN Length;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+
+ DataStr = GetNextParamStr (&TextDeviceNode);
+ Length = StrLen (DataStr);
+ //
+ // Two hex characters make up 1 buffer byte
+ //
+ Length = (Length + 1) / 2;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ Type,
+ SubType,
+ (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
+ );
+
+ StrToGuid (GuidStr, &Vendor->Guid);
+ StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor Hardware device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Hardware Controller device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Controller device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ControllerStr;
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ ControllerStr = GetNextParamStr (&TextDeviceNode);
+ Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ (UINT16) sizeof (CONTROLLER_DEVICE_PATH)
+ );
+ Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+/**
+ Converts a text device path node to BMC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BMC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBmc (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *InterfaceTypeStr;
+ CHAR16 *BaseAddressStr;
+ BMC_DEVICE_PATH *BmcDp;
+
+ InterfaceTypeStr = GetNextParamStr (&TextDeviceNode);
+ BaseAddressStr = GetNextParamStr (&TextDeviceNode);
+ BmcDp = (BMC_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_BMC_DP,
+ (UINT16) sizeof (BMC_DEVICE_PATH)
+ );
+
+ BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr);
+ WriteUnaligned64 (
+ (UINT64 *) (&BmcDp->BaseAddress),
+ StrHexToUint64 (BaseAddressStr)
+ );
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp;
+}
+
+/**
+ Converts a generic ACPI text device path node to ACPI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to ACPI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a string to EisaId.
+
+ @param Text The input string.
+
+ @return UINT32 EISA ID.
+**/
+UINT32
+EisaIdFromText (
+ CHAR16 *Text
+ )
+{
+ return (((Text[0] - 'A' + 1) & 0x1f) << 10)
+ + (((Text[1] - 'A' + 1) & 0x1f) << 5)
+ + (((Text[2] - 'A' + 1) & 0x1f) << 0)
+ + (UINT32) (StrHexToUint64 (&Text[3]) << 16)
+ ;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EisaIdFromText (HIDStr);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param PnPId The input plug and play identification.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+ CHAR16 *TextDeviceNode,
+ UINT32 PnPId
+ )
+{
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EFI_PNP_ID (PnPId);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to PCI root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCI root device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a03);
+}
+
+/**
+ Converts a text device path node to PCIE root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCIE root device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcieRoot (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a08);
+}
+
+/**
+ Converts a text device path node to Floppy device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Floppy device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0604);
+}
+
+/**
+ Converts a text device path node to Keyboard device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Keyboard device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0301);
+}
+
+/**
+ Converts a text device path node to Serial device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0501);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0401);
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDStr;
+ CHAR16 *HIDSTRStr;
+ CHAR16 *CIDSTRStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
+ AcpiEx->UID = (UINT32) Strtoi (UIDStr);
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ StrToAscii (HIDSTRStr, &AsciiStr);
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ StrToAscii (CIDSTRStr, &AsciiStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ //
+ // According to UEFI spec, the CID parametr is optional and has a default value of 0.
+ // So when the CID parametr is not specified or specified as 0 in the text device node.
+ // Set the CID to 0 in the ACPI extension device path structure.
+ //
+ if (*CIDStr == L'\0' || *CIDStr == L'0') {
+ AcpiEx->CID = 0;
+ } else {
+ AcpiEx->CID = EisaIdFromText (CIDStr);
+ }
+ AcpiEx->UID = 0;
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ //
+ // HID string is NULL
+ //
+ *AsciiStr = '\0';
+ //
+ // Convert UID string
+ //
+ AsciiStr++;
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ //
+ // CID string is NULL
+ //
+ *AsciiStr = '\0';
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI _ADR device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI _ADR device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiAdr (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *DisplayDeviceStr;
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+ UINTN Index;
+ UINTN Length;
+
+ AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_ADR_DP,
+ (UINT16) sizeof (ACPI_ADR_DEVICE_PATH)
+ );
+ ASSERT (AcpiAdr != NULL);
+
+ for (Index = 0; ; Index++) {
+ DisplayDeviceStr = GetNextParamStr (&TextDeviceNode);
+ if (IS_NULL (*DisplayDeviceStr)) {
+ break;
+ }
+ if (Index > 0) {
+ Length = DevicePathNodeLength (AcpiAdr);
+ AcpiAdr = ReallocatePool (
+ Length,
+ Length + sizeof (UINT32),
+ AcpiAdr
+ );
+ ASSERT (AcpiAdr != NULL);
+ SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32));
+ }
+
+ (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr;
+}
+
+/**
+ Converts a generic messaging text device path node to messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to messaging device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMsg (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+ CHAR16 *TextDeviceNode
+)
+{
+ CHAR16 *PrimarySecondaryStr;
+ CHAR16 *SlaveMasterStr;
+ CHAR16 *LunStr;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ (UINT16) sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ if (StrCmp (PrimarySecondaryStr, L"Primary") == 0) {
+ Atapi->PrimarySecondary = 0;
+ } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) {
+ Atapi->PrimarySecondary = 1;
+ } else {
+ Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);
+ }
+ if (StrCmp (SlaveMasterStr, L"Master") == 0) {
+ Atapi->SlaveMaster = 0;
+ } else if (StrCmp (SlaveMasterStr, L"Slave") == 0) {
+ Atapi->SlaveMaster = 1;
+ } else {
+ Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr);
+ }
+
+ Atapi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+/**
+ Converts a text device path node to SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ SCSI_DEVICE_PATH *Scsi;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SCSI_DP,
+ (UINT16) sizeof (SCSI_DEVICE_PATH)
+ );
+
+ Scsi->Pun = (UINT16) Strtoi (PunStr);
+ Scsi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+/**
+ Converts a text device path node to Fibre device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Fibre device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNEL_DP,
+ (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH)
+ );
+
+ Fibre->Reserved = 0;
+ Strtoi64 (WWNStr, &Fibre->WWN);
+ Strtoi64 (LunStr, &Fibre->Lun);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+/**
+ Converts a text device path node to FibreEx device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created FibreEx device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibreEx (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNELEX_DEVICE_PATH *FibreEx;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNELEX_DP,
+ (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH)
+ );
+
+ FibreEx->Reserved = 0;
+ Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN));
+ Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun));
+
+ *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN));
+ *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun));
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx;
+}
+
+/**
+ Converts a text device path node to 1394 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created 1394 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ F1394_DEVICE_PATH *F1394DevPath;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ (UINT16) sizeof (F1394_DEVICE_PATH)
+ );
+
+ F1394DevPath->Reserved = 0;
+ F1394DevPath->Guid = StrHexToUint64 (GuidStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
+}
+
+/**
+ Converts a text device path node to USB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PortStr;
+ CHAR16 *InterfaceStr;
+ USB_DEVICE_PATH *Usb;
+
+ PortStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceStr = GetNextParamStr (&TextDeviceNode);
+ Usb = (USB_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_DP,
+ (UINT16) sizeof (USB_DEVICE_PATH)
+ );
+
+ Usb->ParentPortNumber = (UINT8) Strtoi (PortStr);
+ Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+/**
+ Converts a text device path node to I20 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created I20 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TIDStr;
+ I2O_DEVICE_PATH *I2ODevPath;
+
+ TIDStr = GetNextParamStr (&TextDeviceNode);
+ I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ (UINT16) sizeof (I2O_DEVICE_PATH)
+ );
+
+ I2ODevPath->Tid = (UINT32) Strtoi (TIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath;
+}
+
+/**
+ Converts a text device path node to Infini Band device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Infini Band device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FlagsStr;
+ CHAR16 *GuidStr;
+ CHAR16 *SidStr;
+ CHAR16 *TidStr;
+ CHAR16 *DidStr;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ SidStr = GetNextParamStr (&TextDeviceNode);
+ TidStr = GetNextParamStr (&TextDeviceNode);
+ DidStr = GetNextParamStr (&TextDeviceNode);
+ InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_INFINIBAND_DP,
+ (UINT16) sizeof (INFINIBAND_DEVICE_PATH)
+ );
+
+ InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
+ StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid);
+ Strtoi64 (SidStr, &InfiniBand->ServiceId);
+ Strtoi64 (TidStr, &InfiniBand->TargetPortId);
+ Strtoi64 (DidStr, &InfiniBand->DeviceId);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+/**
+ Converts a text device path node to Vendor-Defined Messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-Defined Messaging device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Vendor defined PC-ANSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined PC-ANSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 Plus device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 Plus device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined UTF8 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined UTF8 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to UART Flow Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART Flow Control device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ValueStr;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+ ValueStr = GetNextParamStr (&TextDeviceNode);
+ UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+ );
+
+ CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid);
+ if (StrCmp (ValueStr, L"XonXoff") == 0) {
+ UartFlowControl->FlowControlMap = 2;
+ } else if (StrCmp (ValueStr, L"Hardware") == 0) {
+ UartFlowControl->FlowControlMap = 1;
+ } else {
+ UartFlowControl->FlowControlMap = 0;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ CHAR16 *ReservedStr;
+ UINT16 Info;
+ UINT16 Uint16;
+ SAS_DEVICE_PATH *Sas;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ ReservedStr = GetNextParamStr (&TextDeviceNode);
+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (SAS_DEVICE_PATH)
+ );
+
+ CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid);
+ Strtoi64 (AddressStr, &Sas->SasAddress);
+ Strtoi64 (LunStr, &Sas->Lun);
+ Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+ if (StrCmp (SASSATAStr, L"NoTopology") == 0) {
+ Info = 0x0;
+
+ } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) {
+
+ Uint16 = (UINT16) Strtoi (DriveBayStr);
+ if (Uint16 == 0) {
+ Info = 0x1;
+ } else {
+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= BIT4;
+ }
+
+ //
+ // Location is an integer between 0 and 1 or else
+ // the keyword Internal (0) or External (1).
+ //
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (LocationStr, L"Internal") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+ }
+ Info |= (Uint16 << 5);
+
+ //
+ // Connect is an integer between 0 and 3 or else
+ // the keyword Direct (0) or Expanded (1).
+ //
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (ConnectStr, L"Direct") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+ }
+ Info |= (Uint16 << 6);
+
+ } else {
+ Info = (UINT16) Strtoi (SASSATAStr);
+ }
+
+ Sas->DeviceTopology = Info;
+ Sas->Reserved = (UINT32) Strtoi (ReservedStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI Ex device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI Ex device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSasEx (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ UINT16 Info;
+ UINT16 Uint16;
+ UINT64 SasAddress;
+ UINT64 Lun;
+ SASEX_DEVICE_PATH *SasEx;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SASEX_DP,
+ (UINT16) sizeof (SASEX_DEVICE_PATH)
+ );
+
+ Strtoi64 (AddressStr, &SasAddress);
+ Strtoi64 (LunStr, &Lun);
+ WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress));
+ WriteUnaligned64 ((UINT64 *) &SasEx->Lun, SwapBytes64 (Lun));
+ SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+ if (StrCmp (SASSATAStr, L"NoTopology") == 0) {
+ Info = 0x0;
+
+ } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) {
+
+ Uint16 = (UINT16) Strtoi (DriveBayStr);
+ if (Uint16 == 0) {
+ Info = 0x1;
+ } else {
+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= BIT4;
+ }
+
+ //
+ // Location is an integer between 0 and 1 or else
+ // the keyword Internal (0) or External (1).
+ //
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (LocationStr, L"Internal") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+ }
+ Info |= (Uint16 << 5);
+
+ //
+ // Connect is an integer between 0 and 3 or else
+ // the keyword Direct (0) or Expanded (1).
+ //
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (ConnectStr, L"Direct") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+ }
+ Info |= (Uint16 << 6);
+
+ } else {
+ Info = (UINT16) Strtoi (SASSATAStr);
+ }
+
+ SasEx->DeviceTopology = Info;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) SasEx;
+}
+
+/**
+ Converts a text device path node to NVM Express Namespace device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created NVM Express Namespace device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextNVMe (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *NamespaceIdStr;
+ CHAR16 *NamespaceUuidStr;
+ NVME_NAMESPACE_DEVICE_PATH *Nvme;
+ UINT8 *Uuid;
+ UINTN Index;
+
+ NamespaceIdStr = GetNextParamStr (&TextDeviceNode);
+ NamespaceUuidStr = GetNextParamStr (&TextDeviceNode);
+ Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_NVME_NAMESPACE_DP,
+ (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH)
+ );
+
+ Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr);
+ Uuid = (UINT8 *) &Nvme->NamespaceUuid;
+
+ Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8);
+ while (Index-- != 0) {
+ Uuid[Index] = (UINT8) StrHexToUint64 (SplitStr (&NamespaceUuidStr, L'-'));
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Nvme;
+}
+
+/**
+ Converts a text device path node to UFS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UFS device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUfs (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ UFS_DEVICE_PATH *Ufs;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Ufs = (UFS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UFS_DP,
+ (UINT16) sizeof (UFS_DEVICE_PATH)
+ );
+
+ Ufs->Pun = (UINT8) Strtoi (PunStr);
+ Ufs->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Ufs;
+}
+
+/**
+ Converts a text device path node to SD (Secure Digital) device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SD device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSd (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SlotNumberStr;
+ SD_DEVICE_PATH *Sd;
+
+ SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+ Sd = (SD_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SD_DP,
+ (UINT16) sizeof (SD_DEVICE_PATH)
+ );
+
+ Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sd;
+}
+
+/**
+ Converts a text device path node to EMMC (Embedded MMC) device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created EMMC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmmc (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SlotNumberStr;
+ EMMC_DEVICE_PATH *Emmc;
+
+ SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+ Emmc = (EMMC_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_EMMC_DP,
+ (UINT16) sizeof (EMMC_DEVICE_PATH)
+ );
+
+ Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Emmc;
+}
+
+/**
+ Converts a text device path node to Debug Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Debug Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+ CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vend;
+
+ Vend = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH)
+ );
+
+ CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+/**
+ Converts a text device path node to MAC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created MAC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *IfTypeStr;
+ UINTN Length;
+ MAC_ADDR_DEVICE_PATH *MACDevPath;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ IfTypeStr = GetNextParamStr (&TextDeviceNode);
+ MACDevPath = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ (UINT16) sizeof (MAC_ADDR_DEVICE_PATH)
+ );
+
+ MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr);
+
+ Length = sizeof (EFI_MAC_ADDRESS);
+ if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {
+ Length = 6;
+ }
+
+ StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
+}
+
+
+/**
+ Converts a text format to the network protocol ID.
+
+ @param Text String of protocol field.
+
+ @return Network protocol ID .
+
+**/
+UINTN
+NetworkProtocolFromText (
+ CHAR16 *Text
+ )
+{
+ if (StrCmp (Text, L"UDP") == 0) {
+ return RFC_1700_UDP_PROTOCOL;
+ }
+
+ if (StrCmp (Text, L"TCP") == 0) {
+ return RFC_1700_TCP_PROTOCOL;
+ }
+
+ return Strtoi (Text);
+}
+
+
+/**
+ Converts a text device path node to IPV4 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV4 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *SubnetMaskStr;
+ IPv4_DEVICE_PATH *IPv4;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ SubnetMaskStr = GetNextParamStr (&TextDeviceNode);
+ IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ (UINT16) sizeof (IPv4_DEVICE_PATH)
+ );
+
+ StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
+ IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv4->StaticIpAddress = TRUE;
+ } else {
+ IPv4->StaticIpAddress = FALSE;
+ }
+
+ StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
+ StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, NULL);
+ StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL);
+ } else {
+ ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
+ ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask));
+ }
+
+ IPv4->LocalPort = 0;
+ IPv4->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+/**
+ Converts a text device path node to IPV6 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV6 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *PrefixLengthStr;
+ IPv6_DEVICE_PATH *IPv6;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ PrefixLengthStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ (UINT16) sizeof (IPv6_DEVICE_PATH)
+ );
+
+ StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
+ IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv6->IpAddressOrigin = 0;
+ } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) {
+ IPv6->IpAddressOrigin = 1;
+ } else {
+ IPv6->IpAddressOrigin = 2;
+ }
+
+ StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
+ StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
+ IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
+ } else {
+ ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
+ IPv6->PrefixLength = 0;
+ }
+
+ IPv6->LocalPort = 0;
+ IPv6->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+/**
+ Converts a text device path node to UART device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BaudStr;
+ CHAR16 *DataBitsStr;
+ CHAR16 *ParityStr;
+ CHAR16 *StopBitsStr;
+ UART_DEVICE_PATH *Uart;
+
+ BaudStr = GetNextParamStr (&TextDeviceNode);
+ DataBitsStr = GetNextParamStr (&TextDeviceNode);
+ ParityStr = GetNextParamStr (&TextDeviceNode);
+ StopBitsStr = GetNextParamStr (&TextDeviceNode);
+ Uart = (UART_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ (UINT16) sizeof (UART_DEVICE_PATH)
+ );
+
+ if (StrCmp (BaudStr, L"DEFAULT") == 0) {
+ Uart->BaudRate = 115200;
+ } else {
+ Strtoi64 (BaudStr, &Uart->BaudRate);
+ }
+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
+ switch (*ParityStr) {
+ case L'D':
+ Uart->Parity = 0;
+ break;
+
+ case L'N':
+ Uart->Parity = 1;
+ break;
+
+ case L'E':
+ Uart->Parity = 2;
+ break;
+
+ case L'O':
+ Uart->Parity = 3;
+ break;
+
+ case L'M':
+ Uart->Parity = 4;
+ break;
+
+ case L'S':
+ Uart->Parity = 5;
+ break;
+
+ default:
+ Uart->Parity = (UINT8) Strtoi (ParityStr);
+ break;
+ }
+
+ if (StrCmp (StopBitsStr, L"D") == 0) {
+ Uart->StopBits = (UINT8) 0;
+ } else if (StrCmp (StopBitsStr, L"1") == 0) {
+ Uart->StopBits = (UINT8) 1;
+ } else if (StrCmp (StopBitsStr, L"1.5") == 0) {
+ Uart->StopBits = (UINT8) 2;
+ } else if (StrCmp (StopBitsStr, L"2") == 0) {
+ Uart->StopBits = (UINT8) 3;
+ } else {
+ Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+ CHAR16 *TextDeviceNode,
+ USB_CLASS_TEXT *UsbClassText
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *ClassStr;
+ CHAR16 *SubClassStr;
+ CHAR16 *ProtocolStr;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ (UINT16) sizeof (USB_CLASS_DEVICE_PATH)
+ );
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ if (UsbClassText->ClassExist) {
+ ClassStr = GetNextParamStr (&TextDeviceNode);
+ if (*ClassStr == L'\0') {
+ UsbClass->DeviceClass = 0xFF;
+ } else {
+ UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
+ }
+ } else {
+ UsbClass->DeviceClass = UsbClassText->Class;
+ }
+ if (UsbClassText->SubClassExist) {
+ SubClassStr = GetNextParamStr (&TextDeviceNode);
+ if (*SubClassStr == L'\0') {
+ UsbClass->DeviceSubClass = 0xFF;
+ } else {
+ UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
+ }
+ } else {
+ UsbClass->DeviceSubClass = UsbClassText->SubClass;
+ }
+
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+ if (*VIDStr == L'\0') {
+ UsbClass->VendorId = 0xFFFF;
+ } else {
+ UsbClass->VendorId = (UINT16) Strtoi (VIDStr);
+ }
+ if (*PIDStr == L'\0') {
+ UsbClass->ProductId = 0xFFFF;
+ } else {
+ UsbClass->ProductId = (UINT16) Strtoi (PIDStr);
+ }
+ if (*ProtocolStr == L'\0') {
+ UsbClass->DeviceProtocol = 0xFF;
+ } else {
+ UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = TRUE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB audio device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB audio device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_AUDIO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC Control device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCCONTROL;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HID;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Image device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Image device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_IMAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Print device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Print device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_PRINTER;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB mass storage device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB mass storage device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_MASS_STORAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HUB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HUB device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HUB;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC data device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC data device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCDATA;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB smart card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB smart card device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_SMART_CARD;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB video device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB video device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_VIDEO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB diagnostic device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB diagnostic device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_DIAGNOSTIC;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB wireless device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB wireless device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_WIRELESS;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB device firmware update device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device firmware update device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB IRDA bridge device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB IRDA bridge device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB text and measurement device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB text and measurement device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+ CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_TEST;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB WWID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB WWID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *InterfaceNumStr;
+ CHAR16 *SerialNumberStr;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+ UINTN SerialNumberStrLen;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStrLen = StrLen (SerialNumberStr);
+ if (SerialNumberStrLen >= 2 &&
+ SerialNumberStr[0] == L'\"' &&
+ SerialNumberStr[SerialNumberStrLen - 1] == L'\"'
+ ) {
+ SerialNumberStr[SerialNumberStrLen - 1] = L'\0';
+ SerialNumberStr++;
+ SerialNumberStrLen -= 2;
+ }
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_DP,
+ (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
+ );
+ UsbWwid->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
+
+ //
+ // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr.
+ // Therefore, the '\0' will not be copied.
+ //
+ memcpy (
+ (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH),
+ SerialNumberStr,
+ SerialNumberStrLen * sizeof (CHAR16)
+ );
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+/**
+ Converts a text device path node to Logic Unit device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Logic Unit device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *LunStr;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_DEVICE_LOGICAL_UNIT_DP,
+ (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+ );
+
+ LogicalUnit->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+/**
+ Converts a text device path node to iSCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created iSCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+ CHAR16 *TextDeviceNode
+ )
+{
+ UINT16 Options;
+ CHAR16 *NameStr;
+ CHAR16 *PortalGroupStr;
+ CHAR16 *LunStr;
+ CHAR16 *HeaderDigestStr;
+ CHAR16 *DataDigestStr;
+ CHAR16 *AuthenticationStr;
+ CHAR16 *ProtocolStr;
+ CHAR8 *AsciiStr;
+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+ UINT64 Lun;
+
+ NameStr = GetNextParamStr (&TextDeviceNode);
+ PortalGroupStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode);
+ DataDigestStr = GetNextParamStr (&TextDeviceNode);
+ AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
+ );
+
+ AsciiStr = ISCSIDevPath->TargetName;
+ StrToAscii (NameStr, &AsciiStr);
+
+ ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
+ Strtoi64 (LunStr, &Lun);
+ WriteUnaligned64 ((UINT64 *) &ISCSIDevPath->Lun, SwapBytes64 (Lun));
+
+ Options = 0x0000;
+ if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0002;
+ }
+
+ if (StrCmp (DataDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0008;
+ }
+
+ if (StrCmp (AuthenticationStr, L"None") == 0) {
+ Options |= 0x0800;
+ }
+
+ if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) {
+ Options |= 0x1000;
+ }
+
+ ISCSIDevPath->LoginOption = (UINT16) Options;
+
+ if (IS_NULL (*ProtocolStr) || (StrCmp (ProtocolStr, L"TCP") == 0)) {
+ ISCSIDevPath->NetworkProtocol = 0;
+ } else {
+ //
+ // Undefined and reserved.
+ //
+ ISCSIDevPath->NetworkProtocol = 1;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
+}
+
+/**
+ Converts a text device path node to VLAN device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created VLAN device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVlan (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VlanStr;
+ VLAN_DEVICE_PATH *Vlan;
+
+ VlanStr = GetNextParamStr (&TextDeviceNode);
+ Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VLAN_DP,
+ (UINT16) sizeof (VLAN_DEVICE_PATH)
+ );
+
+ Vlan->VlanId = (UINT16) Strtoi (VlanStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
+}
+
+/**
+ Converts a text device path node to Bluetooth device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Bluetooth device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBluetooth (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BluetoothStr;
+ BLUETOOTH_DEVICE_PATH *BluetoothDp;
+
+ BluetoothStr = GetNextParamStr (&TextDeviceNode);
+ BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_BLUETOOTH_DP,
+ (UINT16) sizeof (BLUETOOTH_DEVICE_PATH)
+ );
+ StrHexToBytes (
+ BluetoothStr,
+ sizeof (BLUETOOTH_ADDRESS) * 2,
+ BluetoothDp->BD_ADDR.Address,
+ sizeof (BLUETOOTH_ADDRESS)
+ );
+ return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp;
+}
+
+/**
+ Converts a text device path node to Wi-Fi device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Wi-Fi device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextWiFi (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SSIdStr;
+ CHAR8 AsciiStr[33];
+ UINTN DataLen;
+ WIFI_DEVICE_PATH *WiFiDp;
+
+ SSIdStr = GetNextParamStr (&TextDeviceNode);
+ WiFiDp = (WIFI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_WIFI_DP,
+ (UINT16) sizeof (WIFI_DEVICE_PATH)
+ );
+
+ if (NULL != SSIdStr) {
+ DataLen = StrLen (SSIdStr);
+ if (StrLen (SSIdStr) > 32) {
+ SSIdStr[32] = L'\0';
+ DataLen = 32;
+ }
+
+ UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr));
+ memcpy (WiFiDp->SSId, AsciiStr, DataLen);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp;
+}
+
+/**
+ Converts a text device path node to Bluetooth LE device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Bluetooth LE device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBluetoothLE (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BluetoothLeAddrStr;
+ CHAR16 *BluetoothLeAddrTypeStr;
+ BLUETOOTH_LE_DEVICE_PATH *BluetoothLeDp;
+
+ BluetoothLeAddrStr = GetNextParamStr (&TextDeviceNode);
+ BluetoothLeAddrTypeStr = GetNextParamStr (&TextDeviceNode);
+ BluetoothLeDp = (BLUETOOTH_LE_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_BLUETOOTH_LE_DP,
+ (UINT16) sizeof (BLUETOOTH_LE_DEVICE_PATH)
+ );
+
+ BluetoothLeDp->Address.Type = (UINT8) Strtoi (BluetoothLeAddrTypeStr);
+ StrHexToBytes (
+ BluetoothLeAddrStr, sizeof (BluetoothLeDp->Address.Address) * 2,
+ BluetoothLeDp->Address.Address, sizeof (BluetoothLeDp->Address.Address)
+ );
+ return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothLeDp;
+}
+
+/**
+ Converts a text device path node to DNS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created DNS device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDns (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *DeviceNodeStr;
+ CHAR16 *DeviceNodeStrPtr;
+ UINT32 DnsServerIpCount;
+ UINT16 DnsDeviceNodeLength;
+ DNS_DEVICE_PATH *DnsDeviceNode;
+ UINT32 DnsServerIpIndex;
+ CHAR16 *DnsServerIp;
+
+
+ //
+ // Count the DNS server address number.
+ //
+ DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
+ if (DeviceNodeStr == NULL) {
+ return NULL;
+ }
+
+ DeviceNodeStrPtr = DeviceNodeStr;
+
+ DnsServerIpCount = 0;
+ while (DeviceNodeStrPtr != NULL && *DeviceNodeStrPtr != L'\0') {
+ GetNextParamStr (&DeviceNodeStrPtr);
+ DnsServerIpCount ++;
+ }
+
+ free (DeviceNodeStr);
+ DeviceNodeStr = NULL;
+
+ //
+ // One or more instances of the DNS server address in EFI_IP_ADDRESS,
+ // otherwise, NULL will be returned.
+ //
+ if (DnsServerIpCount == 0) {
+ return NULL;
+ }
+
+ //
+ // Create the DNS DeviceNode.
+ //
+ DnsDeviceNodeLength = (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (UINT8) + DnsServerIpCount * sizeof (EFI_IP_ADDRESS));
+ DnsDeviceNode = (DNS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_DNS_DP,
+ DnsDeviceNodeLength
+ );
+ if (DnsDeviceNode == NULL) {
+ return NULL;
+ }
+
+ //
+ // Confirm the DNS server address is IPv4 or IPv6 type.
+ //
+ DeviceNodeStrPtr = TextDeviceNode;
+ while (!IS_NULL (*DeviceNodeStrPtr)) {
+ if (*DeviceNodeStrPtr == L'.') {
+ DnsDeviceNode->IsIPv6 = 0x00;
+ break;
+ }
+
+ if (*DeviceNodeStrPtr == L':') {
+ DnsDeviceNode->IsIPv6 = 0x01;
+ break;
+ }
+
+ DeviceNodeStrPtr++;
+ }
+
+ for (DnsServerIpIndex = 0; DnsServerIpIndex < DnsServerIpCount; DnsServerIpIndex++) {
+ DnsServerIp = GetNextParamStr (&TextDeviceNode);
+ if (DnsDeviceNode->IsIPv6 == 0x00) {
+ StrToIpv4Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v4), NULL);
+ } else {
+ StrToIpv6Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v6), NULL);
+ }
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) DnsDeviceNode;
+}
+
+/**
+ Converts a text device path node to URI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created URI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUri (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *UriStr;
+ UINTN UriLength;
+ URI_DEVICE_PATH *Uri;
+
+ UriStr = GetNextParamStr (&TextDeviceNode);
+ UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH));
+ Uri = (URI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_URI_DP,
+ (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength)
+ );
+
+ while (UriLength-- != 0) {
+ Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength];
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uri;
+}
+
+/**
+ Converts a media text device path node to media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to media device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMediaPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to HD device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created HD device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PartitionStr;
+ CHAR16 *TypeStr;
+ CHAR16 *SignatureStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ UINT32 Signature32;
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ PartitionStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ SignatureStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_HARDDRIVE_DP,
+ (UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
+ );
+
+ Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
+
+ ZeroMem (Hd->Signature, 16);
+ Hd->MBRType = (UINT8) 0;
+
+ if (StrCmp (TypeStr, L"MBR") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_MBR;
+ Hd->MBRType = 0x01;
+
+ Signature32 = (UINT32) Strtoi (SignatureStr);
+ memcpy (Hd->Signature, &Signature32, sizeof (UINT32));
+ } else if (StrCmp (TypeStr, L"GPT") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_GUID;
+ Hd->MBRType = 0x02;
+
+ StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
+ } else {
+ Hd->SignatureType = (UINT8) Strtoi (TypeStr);
+ }
+
+ Strtoi64 (StartStr, &Hd->PartitionStart);
+ Strtoi64 (SizeStr, &Hd->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+/**
+ Converts a text device path node to CDROM device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created CDROM device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *EntryStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ CDROM_DEVICE_PATH *CDROMDevPath;
+
+ EntryStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ (UINT16) sizeof (CDROM_DEVICE_PATH)
+ );
+
+ CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
+ Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
+ Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
+}
+
+/**
+ Converts a text device path node to Vendor-defined media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-defined media device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMedia (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to File device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created File device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ FILEPATH_DEVICE_PATH *File;
+
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
+ );
+
+ StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+/**
+ Converts a text device path node to Media protocol device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Media protocol device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_PROTOCOL_DEVICE_PATH *Media;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Media->Protocol);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+/**
+ Converts a text device path node to firmware volume device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware volume device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFv (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_DEVICE_PATH *Fv;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Fv = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_VOL_DP,
+ (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Fv->FvName);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
+}
+
+/**
+ Converts a text device path node to firmware file device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware file device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFvFile (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_FILE_DP,
+ (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &FvFile->FvFileName);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
+}
+
+/**
+ Converts a text device path node to text relative offset device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRelativeOffsetRange (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingOffsetStr;
+ CHAR16 *EndingOffsetStr;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ EndingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RELATIVE_OFFSET_RANGE_DP,
+ (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
+ Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
+}
+
+/**
+ Converts a text device path node to text ram disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRamDisk (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *TypeGuidStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+ TypeGuidStr = GetNextParamStr (&TextDeviceNode);
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text virtual disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualDisk (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text virtual cd device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualCd (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text persistent virtual disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualDisk (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text persistent virtual cd device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualCd (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a BBS text device path node to BBS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to BBS device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBbsPath (
+ CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to BIOS Boot Specification device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BIOS Boot Specification device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+ CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+ CHAR16 *IdStr;
+ CHAR16 *FlagsStr;
+ CHAR8 *AsciiStr;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ IdStr = GetNextParamStr (&TextDeviceNode);
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
+ );
+
+ if (StrCmp (TypeStr, L"Floppy") == 0) {
+ Bbs->DeviceType = BBS_TYPE_FLOPPY;
+ } else if (StrCmp (TypeStr, L"HD") == 0) {
+ Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+ } else if (StrCmp (TypeStr, L"CDROM") == 0) {
+ Bbs->DeviceType = BBS_TYPE_CDROM;
+ } else if (StrCmp (TypeStr, L"PCMCIA") == 0) {
+ Bbs->DeviceType = BBS_TYPE_PCMCIA;
+ } else if (StrCmp (TypeStr, L"USB") == 0) {
+ Bbs->DeviceType = BBS_TYPE_USB;
+ } else if (StrCmp (TypeStr, L"Network") == 0) {
+ Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+ } else {
+ Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
+ }
+
+ AsciiStr = Bbs->String;
+ StrToAscii (IdStr, &AsciiStr);
+
+ Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+/**
+ Converts a text device path node to SATA device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SATA device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSata (
+ CHAR16 *TextDeviceNode
+ )
+{
+ SATA_DEVICE_PATH *Sata;
+ CHAR16 *Param1;
+ CHAR16 *Param2;
+ CHAR16 *Param3;
+
+ Param1 = GetNextParamStr (&TextDeviceNode);
+ Param2 = GetNextParamStr (&TextDeviceNode);
+ Param3 = GetNextParamStr (&TextDeviceNode);
+
+ Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SATA_DP,
+ (UINT16) sizeof (SATA_DEVICE_PATH)
+ );
+ Sata->HBAPortNumber = (UINT16) Strtoi (Param1);
+
+ //
+ // According to UEFI spec, if PMPN is not provided, the default is 0xFFFF
+ //
+ if (*Param2 == L'\0' ) {
+ Sata->PortMultiplierPortNumber = 0xFFFF;
+ } else {
+ Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
+ }
+ Sata->Lun = (UINT16) Strtoi (Param3);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
+}
+
+DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
+ {L"Path", DevPathFromTextPath },
+
+ {L"HardwarePath", DevPathFromTextHardwarePath },
+ {L"Pci", DevPathFromTextPci },
+ {L"PcCard", DevPathFromTextPcCard },
+ {L"MemoryMapped", DevPathFromTextMemoryMapped },
+ {L"VenHw", DevPathFromTextVenHw },
+ {L"Ctrl", DevPathFromTextCtrl },
+ {L"BMC", DevPathFromTextBmc },
+
+ {L"AcpiPath", DevPathFromTextAcpiPath },
+ {L"Acpi", DevPathFromTextAcpi },
+ {L"PciRoot", DevPathFromTextPciRoot },
+ {L"PcieRoot", DevPathFromTextPcieRoot },
+ {L"Floppy", DevPathFromTextFloppy },
+ {L"Keyboard", DevPathFromTextKeyboard },
+ {L"Serial", DevPathFromTextSerial },
+ {L"ParallelPort", DevPathFromTextParallelPort },
+ {L"AcpiEx", DevPathFromTextAcpiEx },
+ {L"AcpiExp", DevPathFromTextAcpiExp },
+ {L"AcpiAdr", DevPathFromTextAcpiAdr },
+
+ {L"Msg", DevPathFromTextMsg },
+ {L"Ata", DevPathFromTextAta },
+ {L"Scsi", DevPathFromTextScsi },
+ {L"Fibre", DevPathFromTextFibre },
+ {L"FibreEx", DevPathFromTextFibreEx },
+ {L"I1394", DevPathFromText1394 },
+ {L"USB", DevPathFromTextUsb },
+ {L"I2O", DevPathFromTextI2O },
+ {L"Infiniband", DevPathFromTextInfiniband },
+ {L"VenMsg", DevPathFromTextVenMsg },
+ {L"VenPcAnsi", DevPathFromTextVenPcAnsi },
+ {L"VenVt100", DevPathFromTextVenVt100 },
+ {L"VenVt100Plus", DevPathFromTextVenVt100Plus },
+ {L"VenUtf8", DevPathFromTextVenUtf8 },
+ {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl },
+ {L"SAS", DevPathFromTextSAS },
+#ifndef VBOX
+ {L"SasEx", DevPathFromTextSasEx },
+#else
+ {L"NVMe", DevPathFromTextNVMe },
+#endif
+ {L"NVMe", DevPathFromTextNVMe },
+ {L"UFS", DevPathFromTextUfs },
+ {L"SD", DevPathFromTextSd },
+ {L"eMMC", DevPathFromTextEmmc },
+ {L"DebugPort", DevPathFromTextDebugPort },
+ {L"MAC", DevPathFromTextMAC },
+ {L"IPv4", DevPathFromTextIPv4 },
+ {L"IPv6", DevPathFromTextIPv6 },
+ {L"Uart", DevPathFromTextUart },
+ {L"UsbClass", DevPathFromTextUsbClass },
+ {L"UsbAudio", DevPathFromTextUsbAudio },
+ {L"UsbCDCControl", DevPathFromTextUsbCDCControl },
+ {L"UsbHID", DevPathFromTextUsbHID },
+ {L"UsbImage", DevPathFromTextUsbImage },
+ {L"UsbPrinter", DevPathFromTextUsbPrinter },
+ {L"UsbMassStorage", DevPathFromTextUsbMassStorage },
+ {L"UsbHub", DevPathFromTextUsbHub },
+ {L"UsbCDCData", DevPathFromTextUsbCDCData },
+ {L"UsbSmartCard", DevPathFromTextUsbSmartCard },
+ {L"UsbVideo", DevPathFromTextUsbVideo },
+ {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic },
+ {L"UsbWireless", DevPathFromTextUsbWireless },
+ {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
+ {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge },
+ {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement },
+ {L"UsbWwid", DevPathFromTextUsbWwid },
+ {L"Unit", DevPathFromTextUnit },
+ {L"iSCSI", DevPathFromTextiSCSI },
+ {L"Vlan", DevPathFromTextVlan },
+ {L"Dns", DevPathFromTextDns },
+ {L"Uri", DevPathFromTextUri },
+ {L"Bluetooth", DevPathFromTextBluetooth },
+ {L"Wi-Fi", DevPathFromTextWiFi },
+ {L"BluetoothLE", DevPathFromTextBluetoothLE },
+ {L"MediaPath", DevPathFromTextMediaPath },
+ {L"HD", DevPathFromTextHD },
+ {L"CDROM", DevPathFromTextCDROM },
+ {L"VenMedia", DevPathFromTextVenMedia },
+ {L"Media", DevPathFromTextMedia },
+ {L"Fv", DevPathFromTextFv },
+ {L"FvFile", DevPathFromTextFvFile },
+ {L"Offset", DevPathFromTextRelativeOffsetRange },
+ {L"RamDisk", DevPathFromTextRamDisk },
+ {L"VirtualDisk", DevPathFromTextVirtualDisk },
+ {L"VirtualCD", DevPathFromTextVirtualCd },
+ {L"PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk },
+ {L"PersistentVirtualCD", DevPathFromTextPersistentVirtualCd },
+
+ {L"BbsPath", DevPathFromTextBbsPath },
+ {L"BBS", DevPathFromTextBBS },
+ {L"Sata", DevPathFromTextSata },
+ {NULL, NULL}
+};
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ )
+{
+ DEVICE_PATH_FROM_TEXT FromText;
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ CHAR16 *DeviceNodeStr;
+ UINTN Index;
+
+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+ return NULL;
+ }
+
+ ParamStr = NULL;
+ FromText = NULL;
+ DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
+ ASSERT (DeviceNodeStr != NULL);
+
+ for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (FromText == NULL) {
+ //
+ // A file path
+ //
+ FromText = DevPathFromTextFilePath;
+ DeviceNode = FromText (DeviceNodeStr);
+ //
+ // According to above logic, if 'FromText' is NULL in the 'if' statement,
+ // then 'ParamStr' must be NULL as well. No memory allocation has been made
+ // in this case.
+ //
+ // The below check is for addressing a false positive potential memory leak
+ // issue raised from static analysis.
+ //
+ if (ParamStr != NULL) {
+ free (ParamStr);
+ }
+ } else {
+ DeviceNode = FromText (ParamStr);
+ free (ParamStr);
+ }
+
+ free (DeviceNodeStr);
+
+ return DeviceNode;
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ CHAR16 *DevicePathStr;
+ CHAR16 *Str;
+ CHAR16 *DeviceNodeStr;
+ BOOLEAN IsInstanceEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+ return NULL;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DevicePath != NULL);
+ SetDevicePathEndNode (DevicePath);
+
+ DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
+
+ Str = DevicePathStr;
+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+ DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
+
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+ free (DevicePath);
+ free (DeviceNode);
+ DevicePath = NewDevicePath;
+
+ if (IsInstanceEnd) {
+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DeviceNode != NULL);
+ SetDevicePathEndNode (DeviceNode);
+ DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+ free (DevicePath);
+ free (DeviceNode);
+ DevicePath = NewDevicePath;
+ }
+ }
+
+ free (DevicePathStr);
+ return DevicePath;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathUtilities.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
new file mode 100644
index 00000000..d4b63271
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/DevicePathUtilities.c
@@ -0,0 +1,868 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment variables. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiDevicePathLib.h"
+#include <Protocol/DevicePathUtilities.h>
+
+//
+// Template for an end-of-device path node.
+//
+CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+};
+
+/**
+ Determine whether a given device path is valid.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param MaxSize The maximum size of the device path data structure.
+
+ @retval TRUE DevicePath is valid.
+ @retval FALSE DevicePath is NULL.
+ @retval FALSE Maxsize is less than sizeof(EFI_DEVICE_PATH_PROTOCOL).
+ @retval FALSE The length of any node node in the DevicePath is less
+ than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+ @retval FALSE If MaxSize is not zero, the size of the DevicePath
+ exceeds MaxSize.
+ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node
+ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+IsDevicePathValid (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ UINTN MaxSize
+ )
+{
+ UINTN Count;
+ UINTN Size;
+ UINTN NodeLength;
+
+ //
+ // Validate the input whether exists and its size big enough to touch the first node
+ //
+ if (DevicePath == NULL || (MaxSize > 0 && MaxSize < END_DEVICE_PATH_LENGTH)) {
+ return FALSE;
+ }
+
+ if (MaxSize == 0) {
+ MaxSize = MAX_UINT32;
+ }
+
+ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
+ NodeLength = DevicePathNodeLength (DevicePath);
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ if (NodeLength > MAX_UINT32 - Size) {
+ return FALSE;
+ }
+ Size += NodeLength;
+
+ //
+ // Validate next node before touch it.
+ //
+ if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {
+ return FALSE;
+ }
+
+ Count++;
+ if (Count >= MAX_DEVICE_PATH_NODE_COUNT) {
+ return FALSE;
+ }
+
+ }
+
+ //
+ // Only return TRUE when the End Device Path node is valid.
+ //
+ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
+}
+
+
+/**
+ Returns the Type field of a device path node.
+
+ Returns the Type field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The Type field of the device path node specified by Node.
+
+**/
+UINT8
+DevicePathType (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
+}
+
+/**
+ Returns the SubType field of a device path node.
+
+ Returns the SubType field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The SubType field of the device path node specified by Node.
+
+**/
+UINT8
+DevicePathSubType (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
+}
+
+/**
+ Returns the 16-bit Length field of a device path node.
+
+ Returns the 16-bit Length field of the device path node specified by Node.
+ Node is not required to be aligned on a 16-bit boundary, so it is recommended
+ that a function such as ReadUnaligned16() be used to extract the contents of
+ the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The 16-bit Length field of the device path node specified by Node.
+
+**/
+UINTN
+DevicePathNodeLength (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
+}
+
+/**
+ Returns a pointer to the next node in a device path.
+
+ Returns a pointer to the device path node that follows the device path node
+ specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return a pointer to the device path node that follows the device path node
+ specified by Node.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+NextDevicePathNode (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node));
+}
+
+/**
+ Determines if a device path node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that
+ are the end of an entire device path.
+
+ Determines if the device path node specified by Node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that are the
+ end of an entire device path. If Node represents an end node of a device path,
+ then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is an end node of a
+ device path.
+ @retval FALSE The device path node specified by Node is not an end node of
+ a device path.
+
+**/
+BOOLEAN
+IsDevicePathEndType (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE);
+}
+
+/**
+ Determines if a device path node is an end node of an entire device path.
+
+ Determines if a device path node specified by Node is an end node of an entire
+ device path. If Node represents the end of an entire device path, then TRUE is
+ returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of an entire
+ device path.
+ @retval FALSE The device path node specified by Node is not the end of an
+ entire device path.
+
+**/
+BOOLEAN
+IsDevicePathEnd (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Determines if a device path node is an end node of a device path instance.
+
+ Determines if a device path node specified by Node is an end node of a device
+ path instance. If Node represents the end of a device path instance, then TRUE
+ is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of a device
+ path instance.
+ @retval FALSE The device path node specified by Node is not the end of a
+ device path instance.
+
+**/
+BOOLEAN
+IsDevicePathEndInstance (
+ CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Sets the length, in bytes, of a device path node.
+
+ Sets the length of the device path node specified by Node to the value specified
+ by NodeLength. NodeLength is returned. Node is not required to be aligned on
+ a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
+ be used to set the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+ If NodeLength >= SIZE_64KB, then ASSERT().
+ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+ @param Length The length, in bytes, of the device path node.
+
+ @return Length
+
+**/
+UINT16
+SetDevicePathNodeLength (
+ VOID *Node,
+ UINTN Length
+ )
+{
+ ASSERT (Node != NULL);
+ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
+ return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+}
+
+/**
+ Fills in all the fields of a device path node that is the end of an entire device path.
+
+ Fills in all the fields of a device path node specified by Node so Node represents
+ the end of an entire device path. The Type field of Node is set to
+ END_DEVICE_PATH_TYPE, the SubType field of Node is set to
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
+ END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,
+ so it is recommended that a function such as WriteUnaligned16() be used to set
+ the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+**/
+VOID
+SetDevicePathEndNode (
+ VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
+}
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!IsDevicePathEnd (DevicePath)) {
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ UINTN Size;
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+
+ return AllocateCopyPool (Size, DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
+ )
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath2;
+
+ //
+ // If there's only 1 path, just duplicate it.
+ //
+ if (FirstDevicePath == NULL) {
+ return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+
+ if (SecondDevicePath == NULL) {
+ return DuplicateDevicePath (FirstDevicePath);
+ }
+
+ if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL.
+ //
+ Size1 = GetDevicePathSize (FirstDevicePath);
+ Size2 = GetDevicePathSize (SecondDevicePath);
+ Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH;
+
+ NewDevicePath = AllocatePool (Size);
+
+ if (NewDevicePath != NULL) {
+ NewDevicePath = memcpy (NewDevicePath, FirstDevicePath, Size1);
+ //
+ // Over write FirstDevicePath EndNode and do the copy
+ //
+ DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +
+ (Size1 - END_DEVICE_PATH_LENGTH));
+ memcpy (DevicePath2, SecondDevicePath, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if (DevicePathNode == NULL) {
+ return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DevicePathNode);
+
+ TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH);
+ if (TempDevicePath == NULL) {
+ return NULL;
+ }
+ TempDevicePath = memcpy (TempDevicePath, DevicePathNode, NodeLength);
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (TempDevicePath);
+ SetDevicePathEndNode (NextNode);
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);
+
+ free (TempDevicePath);
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (DevicePath == NULL) {
+ return DuplicateDevicePath (DevicePathInstance);
+ }
+
+ if (DevicePathInstance == NULL) {
+ return NULL;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) {
+ return NULL;
+ }
+
+ SrcSize = GetDevicePathSize (DevicePath);
+ InstanceSize = GetDevicePathSize (DevicePathInstance);
+
+ NewDevicePath = AllocatePool (SrcSize + InstanceSize);
+ if (NewDevicePath != NULL) {
+
+ TempDevicePath = memcpy (NewDevicePath, DevicePath, SrcSize);;
+
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ memcpy (TempDevicePath, DevicePathInstance, InstanceSize);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
+ UINT8 Temp;
+
+ ASSERT (Size != NULL);
+
+ if (DevicePath == NULL || *DevicePath == NULL) {
+ *Size = 0;
+ return NULL;
+ }
+
+ if (!IsDevicePathValid (*DevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Find the end of the device path instance
+ //
+ DevPath = *DevicePath;
+ while (!IsDevicePathEndType (DevPath)) {
+ DevPath = NextDevicePathNode (DevPath);
+ }
+
+ //
+ // Compute the size of the device path instance
+ //
+ *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ //
+ // Make a copy and return the device path instance
+ //
+ Temp = DevPath->SubType;
+ DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ ReturnValue = DuplicateDevicePath (*DevicePath);
+ DevPath->SubType = Temp;
+
+ //
+ // If DevPath is the end of an entire device path, then another instance
+ // does not follow, so *DevicePath is set to NULL.
+ //
+ if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+ *DevicePath = NULL;
+ } else {
+ *DevicePath = NextDevicePathNode (DevPath);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ //
+ // NodeLength is less than the size of the header.
+ //
+ return NULL;
+ }
+
+ DevicePath = AllocateZeroPool (NodeLength);
+ if (DevicePath != NULL) {
+ DevicePath->Type = NodeType;
+ DevicePath->SubType = NodeSubType;
+ SetDevicePathNodeLength (DevicePath, NodeLength);
+ }
+
+ return DevicePath;
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!IsDevicePathEnd (Node)) {
+ if (IsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+
+ Node = NextDevicePathNode (Node);
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Retrieves the device path protocol from a handle.
+
+ This function returns the device path protocol from the handle specified by Handle.
+ If Handle is NULL or Handle does not contain a device path protocol, then NULL
+ is returned.
+
+ @param Handle The handle from which to retrieve the device
+ path protocol.
+
+ @return The device path protocol from the handle specified by Handle.
+
+**/
+/*
+EFI_DEVICE_PATH_PROTOCOL *
+DevicePathFromHandle (
+ EFI_HANDLE Handle
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ DevicePath = NULL;
+ }
+ return DevicePath;
+}
+*/
+/**
+ Allocates a device path for a file and appends it to an existing device path.
+
+ If Device is a valid device handle that contains a device path protocol, then a device path for
+ the file specified by FileName is allocated and appended to the device path associated with the
+ handle Device. The allocated device path is returned. If Device is NULL or Device is a handle
+ that does not support the device path protocol, then a device path containing a single device
+ path node for the file specified by FileName is allocated and returned.
+ The memory for the new device path is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ If FileName is NULL, then ASSERT().
+ If FileName is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Device A pointer to a device handle. This parameter
+ is optional and may be NULL.
+ @param FileName A pointer to a Null-terminated Unicode string.
+
+ @return The allocated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+FileDevicePath (
+ EFI_HANDLE Device, OPTIONAL
+ CONST CHAR16 *FileName
+ )
+{
+ UINTN Size;
+ FILEPATH_DEVICE_PATH *FilePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
+
+ DevicePath = NULL;
+
+ Size = StrSize (FileName);
+ FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
+ if (FileDevicePath != NULL) {
+ FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
+ FilePath->Header.Type = MEDIA_DEVICE_PATH;
+ FilePath->Header.SubType = MEDIA_FILEPATH_DP;
+ memcpy (&FilePath->PathName, FileName, Size);
+ SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+ SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
+
+ //if (Device != NULL) {
+ // DevicePath = DevicePathFromHandle (Device);
+ //}
+
+ DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
+ free (FileDevicePath);
+ }
+
+ return DevicePath;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/GNUmakefile
new file mode 100644
index 00000000..693eed53
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/GNUmakefile
@@ -0,0 +1,24 @@
+## @file
+# GNU/Linux makefile for 'DevicePath' module build.
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+ARCH ?= IA32
+MAKEROOT ?= ..
+
+APPNAME = DevicePath
+
+OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtilities.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+ifeq ($(CYGWIN), CYGWIN)
+ LIBS += -L/lib/e2fsprogs -luuid
+endif
+
+ifeq ($(LINUX), Linux)
+ LIBS += -luuid
+endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/Makefile
new file mode 100644
index 00000000..47c99140
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/Makefile
@@ -0,0 +1,18 @@
+## @file
+# Windows makefile for 'DevicePath' module build.
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = DevicePath
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj DevicePathUtilities.obj
+
+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
new file mode 100644
index 00000000..3ee51bb3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c
@@ -0,0 +1,292 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment variables. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "UefiDevicePathLib.h"
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+GetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibGetDevicePathSize (DevicePath);
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibDuplicateDevicePath (DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ )
+{
+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ )
+{
+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ )
+{
+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+IsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
+}
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ )
+{
+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ )
+{
+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
new file mode 100644
index 00000000..4e855acc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h
@@ -0,0 +1,439 @@
+/** @file
+ Definition for Device Path library.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _UEFI_DEVICE_PATH_LIB_H_
+#define _UEFI_DEVICE_PATH_LIB_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#ifdef __GNUC__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include <Common/UefiBaseTypes.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DevicePathUtilities.h>
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+
+#define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL))
+#define MAX_DEVICE_PATH_NODE_COUNT 1024
+#define SIZE_64KB 0x00010000
+
+//
+// Private Data structure
+//
+typedef
+EFI_DEVICE_PATH_PROTOCOL *
+(*DEVICE_PATH_FROM_TEXT) (
+ IN CHAR16 *Str
+ );
+
+typedef struct {
+ CHAR16 *Str;
+ UINTN Count;
+ UINTN Capacity;
+} POOL_PRINT;
+
+
+typedef struct {
+ CHAR16 *DevicePathNodeText;
+ DEVICE_PATH_FROM_TEXT Function;
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+ BOOLEAN ClassExist;
+ UINT8 Class;
+ BOOLEAN SubClassExist;
+ UINT8 SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_CDCCONTROL 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDCDATA 10
+#define USB_CLASS_SMART_CARD 11
+#define USB_CLASS_VIDEO 14
+#define USB_CLASS_DIAGNOSTIC 220
+#define USB_CLASS_WIRELESS 224
+
+#define USB_CLASS_RESERVE 254
+#define USB_SUBCLASS_FW_UPDATE 1
+#define USB_SUBCLASS_IRDA_BRIDGE 2
+#define USB_SUBCLASS_TEST 3
+
+#define RFC_1700_UDP_PROTOCOL 17
+#define RFC_1700_TCP_PROTOCOL 6
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Hid;
+ UINT32 Uid;
+ UINT32 Cid;
+ CHAR8 HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT64 Lun;
+ UINT16 TargetPortalGroupTag;
+ CHAR8 TargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+#pragma pack()
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ );
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+UINTN
+GetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ BOOLEAN DisplayOnly,
+ BOOLEAN AllowShortcuts
+ );
+
+CHAR16 *
+ConvertDevicePathToText (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ BOOLEAN DisplayOnly,
+ BOOLEAN AllowShortcuts
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ CONST CHAR16 *TextDeviceNode
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ CONST CHAR16 *TextDevicePath
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.c
new file mode 100644
index 00000000..61e47a6a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.c
@@ -0,0 +1,1712 @@
+/** @file
+Utility program to create an EFI option ROM image from binary and EFI PE32 files.
+
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include "EfiRom.h"
+
+UINT64 DebugLevel = 0;
+
+int
+main (
+ int Argc,
+ char *Argv[]
+ )
+/*++
+
+Routine Description:
+
+ Given an EFI image filename, create a ROM-able image by creating an option
+ ROM header and PCI data structure, filling them in, and then writing the
+ option ROM header + PCI data structure + EFI image out to the output file.
+
+Arguments:
+
+ Argc - standard C main() argument count
+
+ Argv - standard C main() argument list
+
+Returns:
+
+ 0 success
+ non-zero otherwise
+
+--*/
+{
+ CHAR8 *Ext;
+ FILE *FptrOut;
+ UINT32 Status;
+ FILE_LIST *FList;
+ UINT32 TotalSize;
+ UINT32 Size;
+ CHAR8 *Ptr0;
+
+ SetUtilityName(UTILITY_NAME);
+
+ Status = STATUS_SUCCESS;
+ FptrOut = NULL;
+
+ //
+ // Parse the command line arguments
+ //
+ if (ParseCommandLine (Argc, Argv, &mOptions)) {
+ return STATUS_ERROR;
+ }
+
+ if (mOptions.Quiet) {
+ SetPrintLevel(40);
+ } else if (mOptions.Verbose) {
+ SetPrintLevel(15);
+ } else if (mOptions.Debug) {
+ SetPrintLevel(DebugLevel);
+ }
+
+ if (mOptions.Verbose) {
+ VerboseMsg("%s tool start.\n", UTILITY_NAME);
+ }
+
+ //
+ // If dumping an image, then do that and quit
+ //
+ if (mOptions.DumpOption == 1) {
+ if (mOptions.FileList != NULL) {
+ if ((Ptr0 = strstr ((CONST CHAR8 *) mOptions.FileList->FileName, DEFAULT_OUTPUT_EXTENSION)) != NULL) {
+ DumpImage (mOptions.FileList);
+ goto BailOut;
+ } else {
+ Error (NULL, 0, 1002, "No PciRom input file", "No *.rom input file");
+ goto BailOut;
+ }
+ }
+ }
+ //
+ // Determine the output filename. Either what they specified on
+ // the command line, or the first input filename with a different extension.
+ //
+ if (!mOptions.OutFileName[0]) {
+ if (mOptions.FileList != NULL) {
+ if (strlen (mOptions.FileList->FileName) >= MAX_PATH) {
+ Status = STATUS_ERROR;
+ Error (NULL, 0, 2000, "Invalid parameter", "Input file name is too long - %s.", mOptions.FileList->FileName);
+ goto BailOut;
+ }
+ strncpy (mOptions.OutFileName, mOptions.FileList->FileName, MAX_PATH - 1);
+ mOptions.OutFileName[MAX_PATH - 1] = 0;
+ //
+ // Find the last . on the line and replace the filename extension with
+ // the default
+ //
+ Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;
+ while (Ext >= mOptions.OutFileName) {
+ if ((*Ext == '.') || (*Ext == '\\')) {
+ break;
+ }
+ Ext--;
+ }
+ //
+ // If dot here, then insert extension here, otherwise append
+ //
+ if (*Ext != '.') {
+ Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);
+ }
+
+ strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);
+ }
+ }
+ //
+ // Make sure we don't have the same filename for input and output files
+ //
+ for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {
+ if (stricmp (mOptions.OutFileName, FList->FileName) == 0) {
+ Status = STATUS_ERROR;
+ Error (NULL, 0, 1002, "Invalid input parameter", "Input and output file names must be different - %s = %s.", FList->FileName, mOptions.OutFileName);
+ goto BailOut;
+ }
+ }
+ //
+ // Now open our output file
+ //
+ if ((FptrOut = fopen (LongFilePath (mOptions.OutFileName), "wb")) == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", "Error opening file %s", mOptions.OutFileName);
+ goto BailOut;
+ }
+ //
+ // Process all our files
+ //
+ TotalSize = 0;
+ for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {
+ Size = 0;
+ if ((FList->FileFlags & FILE_FLAG_EFI) != 0) {
+ if (mOptions.Verbose) {
+ VerboseMsg("Processing EFI file %s\n", FList->FileName);
+ }
+
+ Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevIdList[0], &Size);
+ } else if ((FList->FileFlags & FILE_FLAG_BINARY) !=0 ) {
+ if (mOptions.Verbose) {
+ VerboseMsg("Processing binary file %s\n", FList->FileName);
+ }
+
+ Status = ProcessBinFile (FptrOut, FList, &Size);
+ } else {
+ Error (NULL, 0, 2000, "Invalid parameter", "File type not specified, it must be either an EFI or binary file: %s.", FList->FileName);
+ Status = STATUS_ERROR;
+ }
+
+ if (mOptions.Verbose) {
+ VerboseMsg(" Output size = 0x%X\n", (unsigned) Size);
+ }
+
+ if (Status != STATUS_SUCCESS) {
+ break;
+ }
+
+ TotalSize += Size;
+ }
+ //
+ // Check total size
+ //
+ if (TotalSize > MAX_OPTION_ROM_SIZE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Option ROM image size exceeds limit of 0x%X bytes.", MAX_OPTION_ROM_SIZE);
+ Status = STATUS_ERROR;
+ }
+
+BailOut:
+ if (Status == STATUS_SUCCESS) {
+ //
+ // Clean up our file list
+ //
+ while (mOptions.FileList != NULL) {
+ FList = mOptions.FileList->Next;
+ free (mOptions.FileList);
+ mOptions.FileList = FList;
+ }
+
+ //
+ // Clean up device ID list
+ //
+ if (mOptions.DevIdList != NULL) {
+ free (mOptions.DevIdList);
+ }
+ }
+ if (FptrOut != NULL) {
+ fclose (FptrOut);
+ }
+
+ if (mOptions.Verbose) {
+ VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
+ }
+
+ return GetUtilityStatus ();
+}
+
+static
+int
+ProcessBinFile (
+ FILE *OutFptr,
+ FILE_LIST *InFile,
+ UINT32 *Size
+ )
+/*++
+
+Routine Description:
+
+ Process a binary input file.
+
+Arguments:
+
+ OutFptr - file pointer to output binary ROM image file we're creating
+ InFile - structure contains information on the binary file to process
+ Size - pointer to where to return the size added to the output file
+
+Returns:
+
+ 0 - successful
+
+--*/
+{
+ FILE *InFptr;
+ UINT32 TotalSize;
+ UINT32 FileSize;
+ UINT8 *Buffer;
+ UINT32 Status;
+ PCI_EXPANSION_ROM_HEADER *RomHdr;
+ PCI_DATA_STRUCTURE *PciDs23;
+ PCI_3_0_DATA_STRUCTURE *PciDs30;
+ UINT32 Index;
+ UINT8 ByteCheckSum;
+ UINT16 CodeType;
+
+ PciDs23 = NULL;
+ PciDs30 = NULL;
+ Status = STATUS_SUCCESS;
+
+ //
+ // Try to open the input file
+ //
+ if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", "%s", InFile->FileName);
+ return STATUS_ERROR;
+ }
+ //
+ // Seek to the end of the input file and get the file size. Then allocate
+ // a buffer to read it in to.
+ //
+ fseek (InFptr, 0, SEEK_END);
+ FileSize = ftell (InFptr);
+ if (mOptions.Verbose) {
+ VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize);
+ }
+
+ fseek (InFptr, 0, SEEK_SET);
+ Buffer = (UINT8 *) malloc (FileSize);
+ if (Buffer == NULL) {
+ Error (NULL, 0, 4003, "Resource", "memory cannot be allocated!");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ if (fread (Buffer, FileSize, 1, InFptr) != 1) {
+ Error (NULL, 0, 2000, "Invalid", "Failed to read all bytes from input file.");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Total size must be an even multiple of 512 bytes, and can't exceed
+ // the option ROM image size.
+ //
+ TotalSize = FileSize;
+ if (TotalSize & 0x1FF) {
+ TotalSize = (TotalSize + 0x200) &~0x1ff;
+ }
+
+ if (TotalSize > MAX_OPTION_ROM_SIZE) {
+ Error (NULL, 0, 3001, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Return the size to the caller so they can keep track of the running total.
+ //
+ *Size = TotalSize;
+
+ //
+ // Crude check to make sure it's a legitimate ROM image
+ //
+ RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;
+ if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "ROM image file has an invalid ROM signature.");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Make sure the pointer to the PCI data structure is within the size of the image.
+ // Then check it for valid signature.
+ //
+ if ((RomHdr->PcirOffset > FileSize) || (RomHdr->PcirOffset == 0)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Invalid PCI data structure offset.");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ //
+ // Check the header is conform to PCI2.3 or PCI3.0
+ //
+ if (mOptions.Pci23 == 1) {
+ PciDs23 = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);
+ if (PciDs23->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature.");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ } else {
+ //
+ // Default setting is PCI3.0 header
+ //
+ PciDs30 = (PCI_3_0_DATA_STRUCTURE *)(Buffer + RomHdr->PcirOffset);
+ if (PciDs30->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature.");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ }
+
+ //
+ // ReSet Option Rom size
+ //
+ if (mOptions.Pci23 == 1) {
+ PciDs23->ImageLength = (UINT16) (TotalSize / 512);
+ CodeType = PciDs23->CodeType;
+ } else {
+ PciDs30->ImageLength = (UINT16) (TotalSize / 512);
+ CodeType = PciDs30->CodeType;
+ }
+
+ //
+ // If this is the last image, then set the LAST bit unless requested not
+ // to via the command-line -n argument. Otherwise, make sure you clear it.
+ //
+ if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {
+ if (mOptions.Pci23 == 1) {
+ PciDs23->Indicator = INDICATOR_LAST;
+ } else {
+ PciDs30->Indicator = INDICATOR_LAST;
+ }
+ } else {
+ if (mOptions.Pci23 == 1) {
+ PciDs23->Indicator = 0;
+ } else {
+ PciDs30->Indicator = 0;
+ }
+ }
+
+ if (CodeType != PCI_CODE_TYPE_EFI_IMAGE) {
+ ByteCheckSum = 0;
+ for (Index = 0; Index < FileSize - 1; Index++) {
+ ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]);
+ }
+
+ Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1);
+ if (mOptions.Verbose) {
+ VerboseMsg(" Checksum = %02x\n\n", Buffer[FileSize - 1]);
+ }
+ }
+
+ //
+ // Now copy the input file contents out to the output file
+ //
+ if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {
+ Error (NULL, 0, 0005, "Failed to write all file bytes to output file.", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ TotalSize -= FileSize;
+ //
+ // Pad the rest of the image to make it a multiple of 512 bytes
+ //
+ while (TotalSize > 0) {
+ putc (~0, OutFptr);
+ TotalSize--;
+ }
+
+BailOut:
+ if (InFptr != NULL) {
+ fclose (InFptr);
+ }
+
+ if (Buffer != NULL) {
+ free (Buffer);
+ }
+ //
+ // Print the file name if errors occurred
+ //
+ if (Status != STATUS_SUCCESS) {
+ Error (NULL, 0, 0003, "Error", "Error parsing file: %s", InFile->FileName);
+ }
+
+ return Status;
+}
+
+static
+int
+ProcessEfiFile (
+ FILE *OutFptr,
+ FILE_LIST *InFile,
+ UINT16 VendId,
+ UINT16 DevId,
+ UINT32 *Size
+ )
+/*++
+
+Routine Description:
+
+ Process a PE32 EFI file.
+
+Arguments:
+
+ OutFptr - file pointer to output binary ROM image file we're creating
+ InFile - structure contains information on the PE32 file to process
+ VendId - vendor ID as required in the option ROM header
+ DevId - device ID as required in the option ROM header
+ Size - pointer to where to return the size added to the output file
+
+Returns:
+
+ 0 - successful
+
+--*/
+{
+ UINT32 Status;
+ FILE *InFptr;
+ EFI_PCI_EXPANSION_ROM_HEADER RomHdr;
+ PCI_DATA_STRUCTURE PciDs23;
+ PCI_3_0_DATA_STRUCTURE PciDs30;
+ UINT32 FileSize;
+ UINT32 CompressedFileSize;
+ UINT8 *Buffer;
+ UINT8 *CompressedBuffer;
+ UINT8 *TempBufferPtr;
+ UINT32 TotalSize;
+ UINT32 HeaderSize;
+ UINT16 MachineType;
+ UINT16 SubSystem;
+ UINT32 HeaderPadBytes;
+ UINT32 PadBytesBeforeImage;
+ UINT32 PadBytesAfterImage;
+ UINT32 DevIdListSize;
+
+ //
+ // Try to open the input file
+ //
+ if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
+ Error (NULL, 0, 0001, "Open file error", "Error opening file: %s", InFile->FileName);
+ return STATUS_ERROR;
+ }
+ //
+ // Initialize our buffer pointers to null.
+ //
+ Buffer = NULL;
+ CompressedBuffer = NULL;
+
+ //
+ // Double-check the file to make sure it's what we expect it to be
+ //
+ Status = CheckPE32File (InFptr, &MachineType, &SubSystem);
+ if (Status != STATUS_SUCCESS) {
+ goto BailOut;
+ }
+ //
+ // Seek to the end of the input file and get the file size
+ //
+ fseek (InFptr, 0, SEEK_END);
+ FileSize = ftell (InFptr);
+
+ //
+ // Get the size of the headers we're going to put in front of the image. The
+ // EFI header must be aligned on a 4-byte boundary, so pad accordingly.
+ //
+ if (sizeof (RomHdr) & 0x03) {
+ HeaderPadBytes = 4 - (sizeof (RomHdr) & 0x03);
+ } else {
+ HeaderPadBytes = 0;
+ }
+
+ //
+ // For Pci3.0 to use the different data structure.
+ //
+ if (mOptions.Pci23 == 1) {
+ HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
+ } else {
+ if (mOptions.DevIdCount > 1) {
+ //
+ // Write device ID list when more than one device ID is specified.
+ // Leave space for list plus terminator.
+ //
+ DevIdListSize = (mOptions.DevIdCount + 1) * sizeof (UINT16);
+ } else {
+ DevIdListSize = 0;
+ }
+ HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + DevIdListSize + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
+ }
+
+ if (mOptions.Verbose) {
+ VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize);
+ }
+ //
+ // Allocate memory for the entire file (in case we have to compress), then
+ // seek back to the beginning of the file and read it into our buffer.
+ //
+ Buffer = (UINT8 *) malloc (FileSize);
+ if (Buffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ fseek (InFptr, 0, SEEK_SET);
+ if (fread (Buffer, FileSize, 1, InFptr) != 1) {
+ Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Now determine the size of the final output file. It's either the header size
+ // plus the file's size, or the header size plus the compressed file size.
+ //
+ if ((InFile->FileFlags & FILE_FLAG_COMPRESS) != 0) {
+ //
+ // Allocate a buffer into which we can compress the image, compress it,
+ // and use that size as the new size.
+ //
+ CompressedBuffer = (UINT8 *) malloc (FileSize);
+ if (CompressedBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ CompressedFileSize = FileSize;
+ Status = EfiCompress (Buffer, FileSize, CompressedBuffer, &CompressedFileSize);
+ if (Status != STATUS_SUCCESS) {
+ Error (NULL, 0, 0007, "Error compressing file!", NULL);
+ goto BailOut;
+ }
+ //
+ // Now compute the size, then swap buffer pointers.
+ //
+ if (mOptions.Verbose) {
+ VerboseMsg(" Comp size = 0x%X\n", (unsigned) CompressedFileSize);
+ }
+
+ TotalSize = CompressedFileSize + HeaderSize;
+ FileSize = CompressedFileSize;
+ TempBufferPtr = Buffer;
+ Buffer = CompressedBuffer;
+ CompressedBuffer = TempBufferPtr;
+ } else {
+ TotalSize = FileSize + HeaderSize;
+ }
+ //
+ // Total size must be an even multiple of 512 bytes
+ //
+ if (TotalSize & 0x1FF) {
+ TotalSize = (TotalSize + 0x200) &~0x1ff;
+ }
+ //
+ // Workaround:
+ // If compressed, put the pad bytes after the image,
+ // else put the pad bytes before the image.
+ //
+ if ((InFile->FileFlags & FILE_FLAG_COMPRESS) != 0) {
+ PadBytesBeforeImage = 0;
+ PadBytesAfterImage = TotalSize - (FileSize + HeaderSize);
+ } else {
+ PadBytesBeforeImage = TotalSize - (FileSize + HeaderSize);
+ PadBytesAfterImage = 0;
+ }
+ //
+ // Check size
+ //
+ if (TotalSize > MAX_OPTION_ROM_SIZE) {
+ Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Return the size to the caller so they can keep track of the running total.
+ //
+ *Size = TotalSize;
+
+ //
+ // Now fill in the ROM header. These values come from chapter 18 of the
+ // EFI 1.02 specification.
+ //
+ memset (&RomHdr, 0, sizeof (RomHdr));
+ RomHdr.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE;
+ RomHdr.InitializationSize = (UINT16) (TotalSize / 512);
+ RomHdr.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;
+ RomHdr.EfiSubsystem = SubSystem;
+ RomHdr.EfiMachineType = MachineType;
+ RomHdr.EfiImageHeaderOffset = (UINT16) (HeaderSize + PadBytesBeforeImage);
+ RomHdr.PcirOffset = (UINT16) (sizeof (RomHdr) + HeaderPadBytes);
+ //
+ // Set image as compressed or not
+ //
+ if (InFile->FileFlags & FILE_FLAG_COMPRESS) {
+ RomHdr.CompressionType = EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED;
+ }
+ //
+ // Fill in the PCI data structure
+ //
+ if (mOptions.Pci23 == 1) {
+ memset (&PciDs23, 0, sizeof (PCI_DATA_STRUCTURE));
+ } else {
+ memset (&PciDs30, 0, sizeof (PCI_3_0_DATA_STRUCTURE));
+ }
+
+ if (mOptions.Pci23 == 1) {
+ PciDs23.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
+ PciDs23.VendorId = VendId;
+ PciDs23.DeviceId = DevId;
+ PciDs23.Length = (UINT16) sizeof (PCI_DATA_STRUCTURE);
+ PciDs23.Revision = 0;
+ //
+ // Class code and code revision from the command line (optional)
+ //
+ PciDs23.ClassCode[0] = (UINT8) InFile->ClassCode;
+ PciDs23.ClassCode[1] = (UINT8) (InFile->ClassCode >> 8);
+ PciDs23.ClassCode[2] = (UINT8) (InFile->ClassCode >> 16);
+ PciDs23.ImageLength = RomHdr.InitializationSize;
+ PciDs23.CodeRevision = InFile->CodeRevision;
+ PciDs23.CodeType = PCI_CODE_TYPE_EFI_IMAGE;
+ } else {
+ PciDs30.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
+ PciDs30.VendorId = VendId;
+ PciDs30.DeviceId = DevId;
+ if (mOptions.DevIdCount > 1) {
+ //
+ // Place device list immediately after PCI structure
+ //
+ PciDs30.DeviceListOffset = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);
+ } else {
+ PciDs30.DeviceListOffset = 0;
+ }
+ PciDs30.Length = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);
+ PciDs30.Revision = 0x3;
+ //
+ // Class code and code revision from the command line (optional)
+ //
+ PciDs30.ClassCode[0] = (UINT8) InFile->ClassCode;
+ PciDs30.ClassCode[1] = (UINT8) (InFile->ClassCode >> 8);
+ PciDs30.ClassCode[2] = (UINT8) (InFile->ClassCode >> 16);
+ PciDs30.ImageLength = RomHdr.InitializationSize;
+ PciDs30.CodeRevision = InFile->CodeRevision;
+ PciDs30.CodeType = PCI_CODE_TYPE_EFI_IMAGE;
+ PciDs30.MaxRuntimeImageLength = 0; // to be fixed
+ PciDs30.ConfigUtilityCodeHeaderOffset = 0; // to be fixed
+ PciDs30.DMTFCLPEntryPointOffset = 0; // to be fixed
+ }
+ //
+ // If this is the last image, then set the LAST bit unless requested not
+ // to via the command-line -n argument.
+ //
+ if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {
+ if (mOptions.Pci23 == 1) {
+ PciDs23.Indicator = INDICATOR_LAST;
+ } else {
+ PciDs30.Indicator = INDICATOR_LAST;}
+ } else {
+ if (mOptions.Pci23 == 1) {
+ PciDs23.Indicator = 0;
+ } else {
+ PciDs30.Indicator = 0;
+ }
+ }
+ //
+ // Write the ROM header to the output file
+ //
+ if (fwrite (&RomHdr, sizeof (RomHdr), 1, OutFptr) != 1) {
+ Error (NULL, 0, 0002, "Failed to write ROM header to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ //
+ // Write pad bytes to align the PciDs
+ //
+ while (HeaderPadBytes > 0) {
+ if (putc (0, OutFptr) == EOF) {
+ Error (NULL, 0, 0002, "Failed to write ROM header pad bytes to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ HeaderPadBytes--;
+ }
+ //
+ // Write the PCI data structure header to the output file
+ //
+ if (mOptions.Pci23 == 1) {
+ if (fwrite (&PciDs23, sizeof (PciDs23), 1, OutFptr) != 1) {
+ Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ } else {
+ if (fwrite (&PciDs30, sizeof (PciDs30), 1, OutFptr) != 1) {
+ Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ }
+
+ //
+ // Write the Device ID list to the output file
+ //
+ if (mOptions.DevIdCount > 1) {
+ if (fwrite (mOptions.DevIdList, sizeof (UINT16), mOptions.DevIdCount, OutFptr) != mOptions.DevIdCount) {
+ Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Write two-byte terminating 0 at the end of the device list
+ //
+ if (putc (0, OutFptr) == EOF || putc (0, OutFptr) == EOF) {
+ Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ }
+
+
+ //
+ // Pad head to make it a multiple of 512 bytes
+ //
+ while (PadBytesBeforeImage > 0) {
+ if (putc (~0, OutFptr) == EOF) {
+ Error (NULL, 0, 2000, "Failed to write trailing pad bytes output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ PadBytesBeforeImage--;
+ }
+ //
+ // Now dump the input file's contents to the output file
+ //
+ if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {
+ Error (NULL, 0, 0002, "Failed to write all file bytes to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ //
+ // Pad the rest of the image to make it a multiple of 512 bytes
+ //
+ while (PadBytesAfterImage > 0) {
+ if (putc (~0, OutFptr) == EOF) {
+ Error (NULL, 0, 2000, "Failed to write trailing pad bytes output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+
+ PadBytesAfterImage--;
+ }
+
+BailOut:
+ if (InFptr != NULL) {
+ fclose (InFptr);
+ }
+ //
+ // Free up our buffers
+ //
+ if (Buffer != NULL) {
+ free (Buffer);
+ }
+
+ if (CompressedBuffer != NULL) {
+ free (CompressedBuffer);
+ }
+ //
+ // Print the file name if errors occurred
+ //
+ if (Status != STATUS_SUCCESS) {
+ Error (NULL, 0, 0003, "Error parsing", "Error parsing file: %s", InFile->FileName);
+ }
+
+ return Status;
+}
+
+static
+int
+CheckPE32File (
+ FILE *Fptr,
+ UINT16 *MachineType,
+ UINT16 *SubSystem
+ )
+/*++
+
+Routine Description:
+
+ Given a file pointer to a supposed PE32 image file, verify that it is indeed a
+ PE32 image file, and then return the machine type in the supplied pointer.
+
+Arguments:
+
+ Fptr File pointer to the already-opened PE32 file
+ MachineType Location to stuff the machine type of the PE32 file. This is needed
+ because the image may be Itanium-based, IA32, or EBC.
+
+Returns:
+
+ 0 success
+ non-zero otherwise
+
+--*/
+{
+ EFI_IMAGE_DOS_HEADER DosHeader;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
+
+ //
+ // Position to the start of the file
+ //
+ fseek (Fptr, 0, SEEK_SET);
+
+ //
+ // Read the DOS header
+ //
+ if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
+ Error (NULL, 0, 0004, "Failed to read the DOS stub from the input file!", NULL);
+ return STATUS_ERROR;
+ }
+ //
+ // Check the magic number (0x5A4D)
+ //
+ if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!");
+ return STATUS_ERROR;
+ }
+ //
+ // Position into the file and check the PE signature
+ //
+ fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
+
+ //
+ // Read PE headers
+ //
+ if (fread (&PeHdr, sizeof (PeHdr), 1, Fptr) != 1) {
+ Error (NULL, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL);
+ return STATUS_ERROR;
+ }
+
+
+ //
+ // Check the PE signature in the header "PE\0\0"
+ //
+ if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!");
+ return STATUS_ERROR;
+ }
+
+ memcpy ((char *) MachineType, &PeHdr.Pe32.FileHeader.Machine, 2);
+
+ if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ *SubSystem = PeHdr.Pe32.OptionalHeader.Subsystem;
+ } else if (PeHdr.Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ *SubSystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem;
+ } else {
+ Error (NULL, 0, 2000, "Invalid parameter", "Unable to find subsystem type!");
+ return STATUS_ERROR;
+ }
+
+ if (mOptions.Verbose) {
+ VerboseMsg(" Got subsystem = 0x%X from image\n", *SubSystem);
+ }
+
+ //
+ // File was successfully identified as a PE32
+ //
+ return STATUS_SUCCESS;
+}
+
+static
+int
+ParseCommandLine (
+ int Argc,
+ char *Argv[],
+ OPTIONS *Options
+ )
+/*++
+
+Routine Description:
+
+ Given the Argc/Argv program arguments, and a pointer to an options structure,
+ parse the command-line options and check their validity.
+
+
+Arguments:
+
+ Argc - standard C main() argument count
+ Argv[] - standard C main() argument list
+ Options - pointer to a structure to store the options in
+
+Returns:
+
+ STATUS_SUCCESS success
+ non-zero otherwise
+
+--*/
+{
+ FILE_LIST *FileList;
+ FILE_LIST *PrevFileList;
+ UINT32 FileFlags;
+ UINT32 ClassCode;
+ UINT32 CodeRevision;
+ EFI_STATUS Status;
+ INTN ReturnStatus;
+ BOOLEAN EfiRomFlag;
+ UINT64 TempValue;
+ char *OptionName;
+ UINT16 *DevIdList;
+
+ ReturnStatus = 0;
+ FileFlags = 0;
+ EfiRomFlag = FALSE;
+
+ //
+ // Clear out the options
+ //
+ memset ((char *) Options, 0, sizeof (OPTIONS));
+
+ //
+ // To avoid compile warnings
+ //
+ FileList = PrevFileList = NULL;
+
+ Options->DevIdList = NULL;
+ Options->DevIdCount = 0;
+
+ ClassCode = 0;
+ CodeRevision = 0;
+ //
+ // Skip over the program name
+ //
+ Argc--;
+ Argv++;
+
+ //
+ // If no arguments, assume they want usage info
+ //
+ if (Argc == 0) {
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ if ((stricmp(Argv[0], "-h") == 0) || (stricmp(Argv[0], "--help") == 0)) {
+ Usage();
+ return STATUS_ERROR;
+ }
+
+ if ((stricmp(Argv[0], "--version") == 0)) {
+ Version();
+ return STATUS_ERROR;
+ }
+
+ //
+ // Process until no more arguments
+ //
+ while (Argc > 0) {
+ if (Argv[0][0] == '-') {
+ //
+ // Vendor ID specified with -f
+ //
+ if (stricmp (Argv[0], "-f") == 0) {
+ //
+ // Make sure there's another parameter
+ //
+ Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ if (TempValue >= 0x10000) {
+ Error (NULL, 0, 2000, "Invalid option value", "Vendor Id %s out of range!", Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ Options->VendId = (UINT16) TempValue;
+ Options->VendIdValid = 1;
+
+ Argv++;
+ Argc--;
+ } else if (stricmp (Argv[0], "-i") == 0) {
+
+ OptionName = Argv[0];
+
+ //
+ // Device IDs specified with -i
+ // Make sure there's at least one more parameter
+ //
+ if (Argc == 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Missing Device Id with %s option!", OptionName);
+ ReturnStatus = 1;
+ goto Done;
+ }
+
+ //
+ // Process until another dash-argument parameter or the end of the list
+ //
+ while (Argc > 1 && Argv[1][0] != '-') {
+ Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", OptionName, Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ //
+ // Don't allow device IDs greater than 16 bits
+ // Don't allow 0, since it is used as a list terminator
+ //
+ if (TempValue >= 0x10000 || TempValue == 0) {
+ Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+
+ DevIdList = (UINT16*) realloc (Options->DevIdList, (Options->DevIdCount + 1) * sizeof (UINT16));
+ if (DevIdList == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ Options->DevIdList = DevIdList;
+
+ Options->DevIdList[Options->DevIdCount++] = (UINT16) TempValue;
+
+ Argv++;
+ Argc--;
+ }
+
+ } else if ((stricmp (Argv[0], "-o") == 0) || (stricmp (Argv[0], "--output") == 0)) {
+ //
+ // Output filename specified with -o
+ // Make sure there's another parameter
+ //
+ if (Argv[1] == NULL || Argv[1][0] == '-') {
+ Error (NULL, 0, 2000, "Invalid parameter", "Missing output file name with %s option!", Argv[0]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ if (strlen (Argv[1]) > MAX_PATH - 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Output file name %s is too long!", Argv[1]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ strncpy (Options->OutFileName, Argv[1], MAX_PATH - 1);
+ Options->OutFileName[MAX_PATH - 1] = 0;
+
+ Argv++;
+ Argc--;
+ } else if ((stricmp (Argv[0], "-h") == 0) || (stricmp (Argv[0], "--help") == 0)) {
+ //
+ // Help option
+ //
+ Usage ();
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ } else if (stricmp (Argv[0], "-b") == 0) {
+ //
+ // Specify binary files with -b
+ //
+ FileFlags = FILE_FLAG_BINARY;
+ } else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) {
+ //
+ // Specify EFI files with -e. Specify EFI-compressed with -c.
+ //
+ FileFlags = FILE_FLAG_EFI;
+ if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) {
+ FileFlags |= FILE_FLAG_COMPRESS;
+ }
+ //
+ // Specify not to set the LAST bit in the last file with -n
+ //
+ } else if (stricmp (Argv[0], "-n") == 0) {
+ Options->NoLast = 1;
+ } else if (((stricmp (Argv[0], "-v") == 0)) || ((stricmp (Argv[0], "--verbose") == 0))) {
+ //
+ // -v for verbose
+ //
+ Options->Verbose = 1;
+ } else if (stricmp (Argv[0], "--debug") == 0) {
+ Status = AsciiStringToUint64(Argv[1], FALSE, &DebugLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ if (DebugLevel > 9) {
+ Error (NULL, 0, 2000, "Invalid option value", "Debug Level range is 0-9, current input level is %d", Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ if (DebugLevel>=5 && DebugLevel<=9) {
+ Options->Debug = TRUE;
+ } else {
+ Options->Debug = FALSE;
+ }
+ Argv++;
+ Argc--;
+ } else if ((stricmp (Argv[0], "--quiet") == 0) || (stricmp (Argv[0], "-q") == 0)) {
+ Options->Quiet = TRUE;
+ } else if ((stricmp (Argv[0], "--dump") == 0) || (stricmp (Argv[0], "-d") == 0)) {
+ //
+ // -dump for dumping a ROM image. In this case, say that the device id
+ // and vendor id are valid so we don't have to specify bogus ones on the
+ // command line.
+ //
+ Options->DumpOption = 1;
+
+ Options->VendIdValid = 1;
+ Options->DevIdCount = 1;
+ FileFlags = FILE_FLAG_BINARY;
+ } else if ((stricmp (Argv[0], "-l") == 0) || (stricmp (Argv[0], "--class-code") == 0)) {
+ //
+ // Class code value for the next file in the list.
+ // Make sure there's another parameter
+ //
+ Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ ClassCode = (UINT32) TempValue;
+ if (ClassCode & 0xFF000000) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Class code %s out of range!", Argv[1]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ if (FileList != NULL && FileList->ClassCode == 0) {
+ FileList->ClassCode = ClassCode;
+ }
+ Argv++;
+ Argc--;
+ } else if ((stricmp (Argv[0], "-r") == 0) || (stricmp (Argv[0], "--Revision") == 0)) {
+ //
+ // Code revision in the PCI data structure. The value is for the next
+ // file in the list.
+ // Make sure there's another parameter
+ //
+ Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ CodeRevision = (UINT32) TempValue;
+ if (CodeRevision & 0xFFFF0000) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Code revision %s out of range!", Argv[1]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ if (FileList != NULL && FileList->CodeRevision == 0) {
+ FileList->CodeRevision = (UINT16) CodeRevision;
+ }
+ Argv++;
+ Argc--;
+ } else if ((stricmp (Argv[0], "-p") == 0) || (stricmp (Argv[0], "--pci23") == 0)) {
+ //
+ // Default layout meets PCI 3.0 specifications, specifying this flag will for a PCI 2.3 layout.
+ //
+ mOptions.Pci23 = 1;
+ } else {
+ Error (NULL, 0, 2000, "Invalid parameter", "Invalid option specified: %s", Argv[0]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ } else {
+ //
+ // Not a slash-option argument. Must be a file name. Make sure they've specified
+ // -e or -b already.
+ //
+ if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Missing -e or -b with input file %s!", Argv[0]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ //
+ // Check Efi Option RomImage
+ //
+ if ((FileFlags & FILE_FLAG_EFI) == FILE_FLAG_EFI) {
+ EfiRomFlag = TRUE;
+ }
+ //
+ // Create a new file structure
+ //
+ FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST));
+ if (FileList == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+
+ //
+ // set flag and class code for this image.
+ //
+ memset ((char *) FileList, 0, sizeof (FILE_LIST));
+ FileList->FileName = Argv[0];
+ FileList->FileFlags = FileFlags;
+ FileList->ClassCode = ClassCode;
+ FileList->CodeRevision = (UINT16) CodeRevision;
+ ClassCode = 0;
+ CodeRevision = 0;
+
+ if (Options->FileList == NULL) {
+ Options->FileList = FileList;
+ } else {
+ if (PrevFileList == NULL) {
+ PrevFileList = FileList;
+ } else {
+ PrevFileList->Next = FileList;
+ }
+ }
+
+ PrevFileList = FileList;
+ }
+ //
+ // Next argument
+ //
+ Argv++;
+ Argc--;
+ }
+
+ //
+ // Must have specified some files
+ //
+ if (Options->FileList == NULL) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Missing input file name!");
+ //
+ // No memory allocation, return directly.
+ //
+ return STATUS_ERROR;
+ }
+
+ //
+ // For EFI OptionRom image, Make sure a device ID and vendor ID are both specified.
+ //
+ if (EfiRomFlag) {
+ if (!Options->VendIdValid) {
+ Error (NULL, 0, 2000, "Missing Vendor ID in command line", NULL);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+
+ if (!Options->DevIdCount) {
+ Error (NULL, 0, 2000, "Missing Device ID in command line", NULL);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ }
+
+ if (Options->DevIdCount > 1 && Options->Pci23) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PCI 3.0 is required when specifying multiple Device IDs");
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+
+Done:
+ if (ReturnStatus != 0) {
+ while (Options->FileList != NULL) {
+ FileList = Options->FileList->Next;
+ free (Options->FileList);
+ Options->FileList = FileList;
+ }
+ }
+
+ return ReturnStatus;
+}
+
+static
+void
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print version information for this utility.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ Nothing.
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+static
+void
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print usage information for this utility.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ Nothing.
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "Usage: %s -f VendorId -i DeviceId [options] [file name<s>] \n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " -o FileName, --output FileName\n\
+ File will be created to store the output content.\n");
+ fprintf (stdout, " -e EfiFileName\n\
+ EFI PE32 image files.\n");
+ fprintf (stdout, " -ec EfiFileName\n\
+ EFI PE32 image files and will be compressed.\n");
+ fprintf (stdout, " -b BinFileName\n\
+ Legacy binary files.\n");
+ fprintf (stdout, " -l ClassCode\n\
+ Hex ClassCode in the PCI data structure header.\n");
+ fprintf (stdout, " -r Rev Hex Revision in the PCI data structure header.\n");
+ fprintf (stdout, " -n Not to automatically set the LAST bit in the last file.\n");
+ fprintf (stdout, " -f VendorId\n\
+ Hex PCI Vendor ID for the device OpROM, must be specified\n");
+ fprintf (stdout, " -i DeviceId\n\
+ One or more hex PCI Device IDs for the device OpROM, must be specified\n");
+ fprintf (stdout, " -p, --pci23\n\
+ Default layout meets PCI 3.0 specifications\n\
+ specifying this flag will for a PCI 2.3 layout.\n");
+ fprintf (stdout, " -d, --dump\n\
+ Dump the headers of an existing option ROM image.\n");
+ fprintf (stdout, " -v, --verbose\n\
+ Turn on verbose output with informational messages.\n");
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help\n\
+ Show this help message and exit.\n");
+ fprintf (stdout, " -q, --quiet\n\
+ Disable all messages except FATAL ERRORS.\n");
+ fprintf (stdout, " --debug [#,0-9]\n\
+ Enable debug messages at level #.\n");
+}
+
+static
+void
+DumpImage (
+ FILE_LIST *InFile
+ )
+/*++
+
+Routine Description:
+
+ Dump the headers of an existing option ROM image
+
+Arguments:
+
+ InFile - the file name of an existing option ROM image
+
+Returns:
+
+ none
+
+--*/
+{
+ PCI_EXPANSION_ROM_HEADER PciRomHdr;
+ FILE *InFptr;
+ UINT32 ImageStart;
+ UINT32 ImageCount;
+ EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr;
+ PCI_DATA_STRUCTURE PciDs23;
+ PCI_3_0_DATA_STRUCTURE PciDs30;
+ UINT16 DevId;
+
+ //
+ // Open the input file
+ //
+ if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InFile->FileName);
+ return ;
+ }
+ //
+ // Go through the image and dump the header stuff for each
+ //
+ ImageCount = 0;
+ for (;;) {
+ //
+ // Save our position in the file, since offsets in the headers
+ // are relative to the particular image.
+ //
+ ImageStart = ftell (InFptr);
+ ImageCount++;
+
+ //
+ // Read the option ROM header. Have to assume a raw binary image for now.
+ //
+ if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to read PCI ROM header from file!");
+ goto BailOut;
+ }
+
+ //
+ // Dump the contents of the header
+ //
+ fprintf (stdout, "Image %u -- Offset 0x%X\n", (unsigned) ImageCount, (unsigned) ImageStart);
+ fprintf (stdout, " ROM header contents\n");
+ fprintf (stdout, " Signature 0x%04X\n", PciRomHdr.Signature);
+ fprintf (stdout, " PCIR offset 0x%04X\n", PciRomHdr.PcirOffset);
+ //
+ // Find PCI data structure
+ //
+ if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI data structure!");
+ goto BailOut;
+ }
+ //
+ // Read and dump the PCI data structure
+ //
+ memset (&PciDs23, 0, sizeof (PciDs23));
+ memset (&PciDs30, 0, sizeof (PciDs30));
+ if (mOptions.Pci23 == 1) {
+ if (fread (&PciDs23, sizeof (PciDs23), 1, InFptr) != 1) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile->FileName);
+ goto BailOut;
+ }
+ } else {
+ if (fread (&PciDs30, sizeof (PciDs30), 1, InFptr) != 1) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile->FileName);
+ goto BailOut;
+ }
+ }
+ if (mOptions.Verbose) {
+ VerboseMsg("Read PCI data structure from file %s", InFile->FileName);
+ }
+
+ //fprintf (stdout, " PCI Data Structure\n");
+ if (mOptions.Pci23 == 1) {
+ fprintf (
+ stdout,
+ " Signature %c%c%c%c\n",
+ (char) PciDs23.Signature,
+ (char) (PciDs23.Signature >> 8),
+ (char) (PciDs23.Signature >> 16),
+ (char) (PciDs23.Signature >> 24)
+ );
+ fprintf (stdout, " Vendor ID 0x%04X\n", PciDs23.VendorId);
+ fprintf (stdout, " Device ID 0x%04X\n", PciDs23.DeviceId);
+ fprintf (stdout, " Length 0x%04X\n", PciDs23.Length);
+ fprintf (stdout, " Revision 0x%04X\n", PciDs23.Revision);
+ fprintf (
+ stdout,
+ " Class Code 0x%06X\n",
+ (unsigned) (PciDs23.ClassCode[0] | (PciDs23.ClassCode[1] << 8) | (PciDs23.ClassCode[2] << 16))
+ );
+ fprintf (stdout, " Image size 0x%X\n", (unsigned) PciDs23.ImageLength * 512);
+ fprintf (stdout, " Code revision: 0x%04X\n", PciDs23.CodeRevision);
+ fprintf (stdout, " Indicator 0x%02X", PciDs23.Indicator);
+ } else {
+ fprintf (
+ stdout,
+ " Signature %c%c%c%c\n",
+ (char) PciDs30.Signature,
+ (char) (PciDs30.Signature >> 8),
+ (char) (PciDs30.Signature >> 16),
+ (char) (PciDs30.Signature >> 24)
+ );
+ fprintf (stdout, " Vendor ID 0x%04X\n", PciDs30.VendorId);
+ fprintf (stdout, " Device ID 0x%04X\n", PciDs30.DeviceId);
+ fprintf (stdout, " Length 0x%04X\n", PciDs30.Length);
+ fprintf (stdout, " Revision 0x%04X\n", PciDs30.Revision);
+ fprintf (stdout, " DeviceListOffset 0x%02X\n", PciDs30.DeviceListOffset);
+ if (PciDs30.DeviceListOffset) {
+ //
+ // Print device ID list
+ //
+ fprintf (stdout, " Device list contents\n");
+ if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs30.DeviceListOffset, SEEK_SET)) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI device ID list!");
+ goto BailOut;
+ }
+
+ //
+ // Loop until terminating 0
+ //
+ do {
+ if (fread (&DevId, sizeof (DevId), 1, InFptr) != 1) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to read PCI device ID list from file %s!", InFile->FileName);
+ goto BailOut;
+ }
+ if (DevId) {
+ fprintf (stdout, " 0x%04X\n", DevId);
+ }
+ } while (DevId);
+
+ }
+ fprintf (
+ stdout,
+ " Class Code 0x%06X\n",
+ (unsigned) (PciDs30.ClassCode[0] | (PciDs30.ClassCode[1] << 8) | (PciDs30.ClassCode[2] << 16))
+ );
+ fprintf (stdout, " Image size 0x%X\n", (unsigned) PciDs30.ImageLength * 512);
+ fprintf (stdout, " Code revision: 0x%04X\n", PciDs30.CodeRevision);
+ fprintf (stdout, " MaxRuntimeImageLength 0x%02X\n", PciDs30.MaxRuntimeImageLength);
+ fprintf (stdout, " ConfigUtilityCodeHeaderOffset 0x%02X\n", PciDs30.ConfigUtilityCodeHeaderOffset);
+ fprintf (stdout, " DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset);
+ fprintf (stdout, " Indicator 0x%02X", PciDs30.Indicator);
+ }
+ //
+ // Print the indicator, used to flag the last image
+ //
+ if (PciDs23.Indicator == INDICATOR_LAST || PciDs30.Indicator == INDICATOR_LAST) {
+ fprintf (stdout, " (last image)\n");
+ } else {
+ fprintf (stdout, "\n");
+ }
+ //
+ // Print the code type. If EFI code, then we can provide more info.
+ //
+ if (mOptions.Pci23 == 1) {
+ fprintf (stdout, " Code type 0x%02X", PciDs23.CodeType);
+ } else {
+ fprintf (stdout, " Code type 0x%02X", PciDs30.CodeType);
+ }
+ if (PciDs23.CodeType == PCI_CODE_TYPE_EFI_IMAGE || PciDs30.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
+ fprintf (stdout, " (EFI image)\n");
+ //
+ // Re-read the header as an EFI ROM header, then dump more info
+ //
+ fprintf (stdout, " EFI ROM header contents\n");
+ if (fseek (InFptr, ImageStart, SEEK_SET)) {
+ Error (NULL, 0, 5001, "Failed to re-seek to ROM header structure!", NULL);
+ goto BailOut;
+ }
+
+ if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) {
+ Error (NULL, 0, 5001, "Failed to read EFI PCI ROM header from file!", NULL);
+ goto BailOut;
+ }
+ //
+ // Now dump more info
+ //
+ fprintf (stdout, " EFI Signature 0x%04X\n", (unsigned) EfiRomHdr.EfiSignature);
+ fprintf (
+ stdout,
+ " Compression Type 0x%04X ",
+ EfiRomHdr.CompressionType
+ );
+ if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
+ fprintf (stdout, "(compressed)\n");
+ } else {
+ fprintf (stdout, "(not compressed)\n");
+ }
+
+ fprintf (
+ stdout,
+ " Machine type 0x%04X (%s)\n",
+ EfiRomHdr.EfiMachineType,
+ GetMachineTypeStr (EfiRomHdr.EfiMachineType)
+ );
+ fprintf (
+ stdout,
+ " Subsystem 0x%04X (%s)\n",
+ EfiRomHdr.EfiSubsystem,
+ GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem)
+ );
+ fprintf (
+ stdout,
+ " EFI image offset 0x%04X (@0x%X)\n",
+ EfiRomHdr.EfiImageHeaderOffset,
+ EfiRomHdr.EfiImageHeaderOffset + (unsigned) ImageStart
+ );
+
+ } else {
+ //
+ // Not an EFI image
+ //
+ fprintf (stdout, "\n");
+ }
+ //
+ // If code type is EFI image, then dump it as well?
+ //
+ // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
+ // }
+ //
+ // If last image, then we're done
+ //
+ if (PciDs23.Indicator == INDICATOR_LAST || PciDs30.Indicator == INDICATOR_LAST) {
+ goto BailOut;
+ }
+ //
+ // Seek to the start of the next image
+ //
+ if (mOptions.Pci23 == 1) {
+ if (fseek (InFptr, ImageStart + (PciDs23.ImageLength * 512), SEEK_SET)) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to seek to next image!");
+ goto BailOut;
+ }
+ } else {
+ if (fseek (InFptr, ImageStart + (PciDs30.ImageLength * 512), SEEK_SET)) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to seek to next image!");
+ goto BailOut;
+ }
+ }
+ }
+
+BailOut:
+ fclose (InFptr);
+}
+
+char *
+GetMachineTypeStr (
+ UINT16 MachineType
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ MachineType - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ int Index;
+
+ for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {
+ if (mMachineTypes[Index].Value == MachineType) {
+ return mMachineTypes[Index].Name;
+ }
+ }
+
+ return "unknown";
+}
+
+static
+char *
+GetSubsystemTypeStr (
+ UINT16 SubsystemType
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ SubsystemType - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ int Index;
+
+ for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {
+ if (mSubsystemTypes[Index].Value == SubsystemType) {
+ return mSubsystemTypes[Index].Name;
+ }
+ }
+
+ return "unknown";
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.h
new file mode 100644
index 00000000..0a04e605
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/EfiRom.h
@@ -0,0 +1,353 @@
+/** @file
+This file contains the relevant declarations required to generate Option Rom File
+
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_ROM_H__
+#define __EFI_ROM_H__
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h> // for PE32 structure definitions
+
+#include <IndustryStandard/pci22.h> // for option ROM header structures
+#include <IndustryStandard/pci30.h>
+
+#include "Compress.h"
+#include "CommonLib.h"
+
+//
+// Version of this utility
+//
+#define UTILITY_NAME "EfiRom"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+//
+// Define the max length of a filename
+//
+#define MAX_PATH 200
+
+//
+// Define the default file extension name
+//
+#define DEFAULT_OUTPUT_EXTENSION ".rom"
+
+//
+// Max size for an option ROM image
+//
+#define MAX_OPTION_ROM_SIZE (1024 * 1024 * 16) // 16MB
+
+//
+// Values for the indicator field in the PCI data structure
+//
+#define INDICATOR_LAST 0x80 // last file in series of files
+
+//
+// Masks for the FILE_LIST.FileFlags field
+//
+#define FILE_FLAG_BINARY 0x01
+#define FILE_FLAG_EFI 0x02
+#define FILE_FLAG_COMPRESS 0x04
+
+//
+// Use this linked list structure to keep track of all the filenames
+// specified on the command line.
+//
+typedef struct _FILE_LIST {
+ struct _FILE_LIST *Next;
+ CHAR8 *FileName;
+ UINT32 FileFlags;
+ UINT32 ClassCode;
+ UINT16 CodeRevision;
+} FILE_LIST;
+
+//
+// Use this to track our command-line options
+//
+typedef struct {
+ CHAR8 OutFileName[MAX_PATH];
+ INT8 NoLast;
+ UINT16 ClassCode;
+ UINT16 PciRevision;
+ UINT16 VendId;
+ UINT16 *DevIdList;
+ UINT32 DevIdCount;
+ UINT8 VendIdValid;
+ INT8 Verbose;
+ INT8 Quiet;
+ INT8 Debug;
+ INT8 Pci23;
+ INT8 Pci30;
+ INT8 DumpOption;
+// INT8 Help;
+// INT8 Version;
+ FILE_LIST *FileList;
+} OPTIONS;
+
+//
+// Make a global structure to keep track of command-line options
+//
+static OPTIONS mOptions;
+
+//
+// Use these to convert from machine type value to a named type
+//
+typedef struct {
+ UINT16 Value;
+ CHAR8 *Name;
+} STRING_LOOKUP;
+
+//
+// Machine Types
+//
+static STRING_LOOKUP mMachineTypes[] = {
+ { EFI_IMAGE_MACHINE_IA32, "IA32" },
+ { EFI_IMAGE_MACHINE_X64, "X64" },
+ { EFI_IMAGE_MACHINE_EBC, "EBC" },
+ { EFI_IMAGE_MACHINE_ARMT, "ARM" },
+ { EFI_IMAGE_MACHINE_AARCH64, "AA64" },
+ { 0, NULL }
+};
+
+//
+// Subsystem Types
+//
+static STRING_LOOKUP mSubsystemTypes[] = {
+ { EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, "EFI application" },
+ { EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, "EFI boot service driver" },
+ { EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, "EFI runtime driver" },
+ { 0, NULL }
+};
+
+//
+// Function prototypes
+//
+static
+void
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility version to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+static
+void
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+static
+int
+ParseCommandLine (
+ int Argc,
+ char *Argv[],
+ OPTIONS *Options
+ )
+/*++
+
+Routine Description:
+
+ Given the Argc/Argv program arguments, and a pointer to an options structure,
+ parse the command-line options and check their validity.
+
+Arguments:
+
+ Argc - standard C main() argument count
+ Argv[] - standard C main() argument list
+ Options - pointer to a structure to store the options in
+
+Returns:
+
+ STATUS_SUCCESS success
+ non-zero otherwise
+
+--*/
+;
+
+static
+int
+CheckPE32File (
+ FILE *Fptr,
+ UINT16 *MachineType,
+ UINT16 *SubSystem
+ )
+/*++
+
+Routine Description:
+
+ Given the Argc/Argv program arguments, and a pointer to an options structure,
+ parse the command-line options and check their validity.
+
+Arguments:
+
+ Argc - standard C main() argument count
+ Argv[] - standard C main() argument list
+ Options - pointer to a structure to store the options in
+
+Returns:
+
+ STATUS_SUCCESS success
+ non-zero otherwise
+
+--*/
+;
+
+static
+int
+ProcessEfiFile (
+ FILE *OutFptr,
+ FILE_LIST *InFile,
+ UINT16 VendId,
+ UINT16 DevId,
+ UINT32 *Size
+ )
+/*++
+
+Routine Description:
+
+ Process a PE32 EFI file.
+
+Arguments:
+
+ OutFptr - file pointer to output binary ROM image file we're creating
+ InFile - structure contains information on the PE32 file to process
+ VendId - vendor ID as required in the option ROM header
+ DevId - device ID as required in the option ROM header
+ Size - pointer to where to return the size added to the output file
+
+Returns:
+
+ 0 - successful
+
+--*/
+;
+
+static
+int
+ProcessBinFile (
+ FILE *OutFptr,
+ FILE_LIST *InFile,
+ UINT32 *Size
+ )
+/*++
+
+Routine Description:
+
+ Process a binary input file.
+
+Arguments:
+
+ OutFptr - file pointer to output binary ROM image file we're creating
+ InFile - structure contains information on the binary file to process
+ Size - pointer to where to return the size added to the output file
+
+Returns:
+
+ 0 - successful
+
+--*/
+;
+
+static
+void
+DumpImage (
+ FILE_LIST *InFile
+ )
+/*++
+
+Routine Description:
+
+ Dump the headers of an existing option ROM image
+
+Arguments:
+
+ InFile - the file name of an existing option ROM image
+
+Returns:
+
+ none
+
+--*/
+;
+
+char *
+GetMachineTypeStr (
+ UINT16 MachineType
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ MachineType - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+static
+char *
+GetSubsystemTypeStr (
+ UINT16 SubsystemType
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ SubsystemType - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/GNUmakefile
new file mode 100644
index 00000000..8b0e2c27
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/GNUmakefile
@@ -0,0 +1,15 @@
+## @file
+# GNU/Linux makefile for 'EfiRom' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = EfiRom
+
+LIBS = -lCommon
+
+OBJECTS = EfiRom.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile
new file mode 100644
index 00000000..ab64084c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile
@@ -0,0 +1,16 @@
+## @file
+# Windows makefile for 'EfiRom' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = EfiRom
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = EfiRom.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile.kmk
new file mode 100644
index 00000000..29dd6c16
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/EfiRom/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI EfiRom build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += EfiRom
+EfiRom_TEMPLATE = VBoxEfiBldProg
+EfiRom_SOURCES = EfiRom.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GNUmakefile
new file mode 100644
index 00000000..34031a4b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GNUmakefile
@@ -0,0 +1,93 @@
+## @file
+# GNU/Linux makefile for C tools build.
+#
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+ifndef HOST_ARCH
+ #
+ # If HOST_ARCH is not defined, then we use 'uname -m' to attempt
+ # try to figure out the appropriate HOST_ARCH.
+ #
+ uname_m = $(shell uname -m)
+ $(info Attempting to detect HOST_ARCH from 'uname -m': $(uname_m))
+ ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))
+ HOST_ARCH=X64
+ endif
+ ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
+ HOST_ARCH=IA32
+ endif
+ ifneq (,$(findstring aarch64,$(uname_m)))
+ HOST_ARCH=AARCH64
+ else ifneq (,$(findstring arm64,$(uname_m)))
+ HOST_ARCH=AARCH64
+ else ifneq (,$(findstring arm,$(uname_m)))
+ HOST_ARCH=ARM
+ endif
+ ifneq (,$(findstring riscv64,$(uname_m)))
+ HOST_ARCH=RISCV64
+ endif
+ ifndef HOST_ARCH
+ $(info Could not detected HOST_ARCH from uname results)
+ $(error HOST_ARCH is not defined!)
+ endif
+ $(info Detected HOST_ARCH of $(HOST_ARCH) using uname.)
+endif
+
+export HOST_ARCH
+
+MAKEROOT = .
+
+include Makefiles/header.makefile
+
+all: makerootdir subdirs
+ @echo Finished building BaseTools C Tools with HOST_ARCH=$(HOST_ARCH)
+
+LIBRARIES = Common
+VFRAUTOGEN = VfrCompile/VfrLexer.h
+APPLICATIONS = \
+ BrotliCompress \
+ VfrCompile \
+ EfiRom \
+ GenFfs \
+ GenFv \
+ GenFw \
+ GenSec \
+ GenCrc32 \
+ LzmaCompress \
+ TianoCompress \
+ VolInfo \
+ DevicePath
+
+SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
+
+$(LIBRARIES): $(MAKEROOT)/libs
+$(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN)
+
+.PHONY: outputdirs
+makerootdir:
+ -mkdir -p $(MAKEROOT)
+
+.PHONY: subdirs $(SUBDIRS)
+subdirs: $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) -C $@
+
+.PHONY: $(patsubst %,%-clean,$(sort $(SUBDIRS)))
+$(patsubst %,%-clean,$(sort $(SUBDIRS))):
+ -$(MAKE) -C $(@:-clean=) clean
+
+$(VFRAUTOGEN): VfrCompile/VfrSyntax.g
+ $(MAKE) -C VfrCompile VfrLexer.h
+
+clean: $(patsubst %,%-clean,$(sort $(SUBDIRS)))
+
+clean: localClean
+
+localClean:
+ rm -f $(MAKEROOT)/bin/*
+ -rmdir $(MAKEROOT)/libs $(MAKEROOT)/bin
+
+include Makefiles/footer.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GNUmakefile
new file mode 100644
index 00000000..5c007d85
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GNUmakefile
@@ -0,0 +1,15 @@
+## @file
+# GNU/Linux makefile for 'GenCrc32' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = GenCrc32
+
+LIBS = -lCommon
+
+OBJECTS = GenCrc32.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GenCrc32.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GenCrc32.c
new file mode 100644
index 00000000..a33bd3d8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/GenCrc32.c
@@ -0,0 +1,361 @@
+/** @file
+Calculate Crc32 value and Verify Crc32 value for input data.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ParseInf.h"
+#include "EfiUtilityMsgs.h"
+#include "CommonLib.h"
+#include "Crc32.h"
+
+#define UTILITY_NAME "GenCrc32"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 2
+
+#define CRC32_NULL 0
+#define CRC32_ENCODE 1
+#define CRC32_DECODE 2
+
+VOID
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the standard utility information to SDTOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "Usage: GenCrc32 -e|-d [options] <input_file>\n\n");
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "optional arguments:\n");
+ fprintf (stdout, " -h, --help Show this help message and exit\n");
+ fprintf (stdout, " --version Show program's version number and exit\n");
+ fprintf (stdout, " --debug [DEBUG] Output DEBUG statements, where DEBUG_LEVEL is 0 (min)\n\
+ - 9 (max)\n");
+ fprintf (stdout, " -v, --verbose Print informational statements\n");
+ fprintf (stdout, " -q, --quiet Returns the exit code, error messages will be\n\
+ displayed\n");
+ fprintf (stdout, " -s, --silent Returns only the exit code; informational and error\n\
+ messages are not displayed\n");
+ fprintf (stdout, " -e, --encode Calculate CRC32 value for the input file\n");
+ fprintf (stdout, " -d, --decode Verify CRC32 value for the input file\n");
+ fprintf (stdout, " -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
+ Output file name\n");
+ fprintf (stdout, " --sfo Reserved for future use\n");
+
+}
+
+int
+main (
+ int argc,
+ CHAR8 *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main function.
+
+Arguments:
+
+ argc - Number of command line parameters.
+ argv - Array of pointers to parameter strings.
+
+Returns:
+ STATUS_SUCCESS - Utility exits successfully.
+ STATUS_ERROR - Some error occurred during execution.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *OutputFileName;
+ CHAR8 *InputFileName;
+ UINT8 *FileBuffer;
+ UINT32 FileSize;
+ UINT64 LogLevel;
+ UINT8 FileAction;
+ UINT32 Crc32Value;
+ FILE *InFile;
+ FILE *OutFile;
+
+ //
+ // Init local variables
+ //
+ LogLevel = 0;
+ Status = EFI_SUCCESS;
+ InputFileName = NULL;
+ OutputFileName = NULL;
+ FileAction = CRC32_NULL;
+ InFile = NULL;
+ OutFile = NULL;
+ Crc32Value = 0;
+ FileBuffer = NULL;
+
+ SetUtilityName (UTILITY_NAME);
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "no options input");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ //
+ // Parse command line
+ //
+ argc --;
+ argv ++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[0], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
+ goto Finish;
+ }
+ OutputFileName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-e") == 0) || (stricmp (argv[0], "--encode") == 0)) {
+ FileAction = CRC32_ENCODE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--decode") == 0)) {
+ FileAction = CRC32_DECODE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
+ SetPrintLevel (VERBOSE_LOG_LEVEL);
+ VerboseMsg ("Verbose output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ SetPrintLevel (KEY_LOG_LEVEL);
+ KeyMsg ("Quiet output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--debug") == 0) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ if (LogLevel > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
+ goto Finish;
+ }
+ SetPrintLevel (LogLevel);
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (argv[0][0] == '-') {
+ Error (NULL, 0, 1000, "Unknown option", argv[0]);
+ goto Finish;
+ }
+
+ //
+ // Get Input file file name.
+ //
+ InputFileName = argv[0];
+ argc --;
+ argv ++;
+ }
+
+ VerboseMsg ("%s tool start.", UTILITY_NAME);
+
+ //
+ // Check Input parameters
+ //
+ if (FileAction == CRC32_NULL) {
+ Error (NULL, 0, 1001, "Missing option", "either the encode or the decode option must be specified!");
+ return STATUS_ERROR;
+ } else if (FileAction == CRC32_ENCODE) {
+ VerboseMsg ("File will be encoded by Crc32");
+ } else if (FileAction == CRC32_DECODE) {
+ VerboseMsg ("File will be decoded by Crc32");
+ }
+
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 1001, "Missing option", "Input files are not specified");
+ goto Finish;
+ } else {
+ VerboseMsg ("Input file name is %s", InputFileName);
+ }
+
+ if (OutputFileName == NULL) {
+ Error (NULL, 0, 1001, "Missing option", "Output file are not specified");
+ goto Finish;
+ } else {
+ VerboseMsg ("Output file name is %s", OutputFileName);
+ }
+
+ //
+ // Open Input file and read file data.
+ //
+ InFile = fopen (LongFilePath (InputFileName), "rb");
+ if (InFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName);
+ return STATUS_ERROR;
+ }
+
+ fseek (InFile, 0, SEEK_END);
+ FileSize = ftell (InFile);
+ fseek (InFile, 0, SEEK_SET);
+
+ FileBuffer = (UINT8 *) malloc (FileSize);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ fclose (InFile);
+ goto Finish;
+ }
+
+ fread (FileBuffer, 1, FileSize, InFile);
+ fclose (InFile);
+ VerboseMsg ("the size of the input file is %u bytes", (unsigned) FileSize);
+
+ //
+ // Open output file
+ //
+ OutFile = fopen (LongFilePath (OutputFileName), "wb");
+ if (OutFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", OutputFileName);
+ goto Finish;
+ }
+
+ //
+ // Calculate Crc32 value
+ //
+ if (FileAction == CRC32_ENCODE) {
+ Status = CalculateCrc32 (FileBuffer, FileSize, &Crc32Value);
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!");
+ goto Finish;
+ }
+ //
+ // Done, write output file.
+ //
+ fwrite (&Crc32Value, 1, sizeof (Crc32Value), OutFile);
+ VerboseMsg ("The calculated CRC32 value is 0x%08x", (unsigned) Crc32Value);
+ fwrite (FileBuffer, 1, FileSize, OutFile);
+ VerboseMsg ("the size of the encoded file is %u bytes", (unsigned) FileSize + sizeof (UINT32));
+ } else {
+ //
+ // Verify Crc32 Value
+ //
+ if (FileSize < sizeof (UINT32)) {
+ Error (NULL, 0, 3000, "Invalid", "Input file is invalid!");
+ goto Finish;
+ }
+ Status = CalculateCrc32 (FileBuffer + sizeof (UINT32), FileSize - sizeof (UINT32), &Crc32Value);
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!");
+ goto Finish;
+ }
+ VerboseMsg ("The calculated CRC32 value is 0x%08x and File Crc32 value is 0x%08x", (unsigned) Crc32Value, (unsigned) (*(UINT32 *)FileBuffer));
+ if (Crc32Value != *(UINT32 *)FileBuffer) {
+ Error (NULL, 0, 3000, "Invalid", "CRC32 value of input file is not correct!");
+ Status = STATUS_ERROR;
+ goto Finish;
+ }
+ //
+ // Done, write output file.
+ //
+ fwrite (FileBuffer + sizeof (UINT32), 1, FileSize - sizeof (UINT32), OutFile);
+ VerboseMsg ("the size of the decoded file is %u bytes", (unsigned) FileSize - sizeof (UINT32));
+ }
+
+Finish:
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+
+ if (OutFile != NULL) {
+ fclose (OutFile);
+ }
+
+ VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
+
+ return GetUtilityStatus ();
+}
+
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile
new file mode 100644
index 00000000..e3b6bcd7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile
@@ -0,0 +1,16 @@
+## @file
+# Windows makefile for 'GenCrc32' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenCrc32
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = GenCrc32.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile.kmk
new file mode 100644
index 00000000..51243288
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenCrc32/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI GenCrc32 build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += GenCrc32
+GenCrc32_TEMPLATE = VBoxEfiBldProg
+GenCrc32_SOURCES = GenCrc32.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GNUmakefile
new file mode 100644
index 00000000..804d8540
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GNUmakefile
@@ -0,0 +1,16 @@
+## @file
+# GNU/Linux makefile for 'GenFfs' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = GenFfs
+
+OBJECTS = GenFfs.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GenFfs.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GenFfs.c
new file mode 100644
index 00000000..28066c2b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/GenFfs.c
@@ -0,0 +1,1120 @@
+/** @file
+This file contains functions required to generate a Firmware File System file.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __GNUC__
+# ifdef VBOX
+// RUNTIME_FUNCTION typedef conflicts; just use EFI headers
+# else
+#include <windows.h>
+# endif
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#ifdef __GNUC__
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/PiFirmwareFile.h>
+#include <IndustryStandard/PeImage.h>
+#include <Guid/FfsSectionAlignmentPadding.h>
+
+#include "CommonLib.h"
+#include "ParseInf.h"
+#include "EfiUtilityMsgs.h"
+#include "FvLib.h"
+#include "PeCoffLib.h"
+
+#define UTILITY_NAME "GenFfs"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+STATIC CHAR8 *mFfsFileType[] = {
+ NULL, // 0x00
+ "EFI_FV_FILETYPE_RAW", // 0x01
+ "EFI_FV_FILETYPE_FREEFORM", // 0x02
+ "EFI_FV_FILETYPE_SECURITY_CORE", // 0x03
+ "EFI_FV_FILETYPE_PEI_CORE", // 0x04
+ "EFI_FV_FILETYPE_DXE_CORE", // 0x05
+ "EFI_FV_FILETYPE_PEIM", // 0x06
+ "EFI_FV_FILETYPE_DRIVER", // 0x07
+ "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER", // 0x08
+ "EFI_FV_FILETYPE_APPLICATION", // 0x09
+ "EFI_FV_FILETYPE_SMM", // 0x0A
+ "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE",// 0x0B
+ "EFI_FV_FILETYPE_COMBINED_SMM_DXE", // 0x0C
+ "EFI_FV_FILETYPE_SMM_CORE", // 0x0D
+ "EFI_FV_FILETYPE_MM_STANDALONE", // 0x0E
+ "EFI_FV_FILETYPE_MM_CORE_STANDALONE" // 0x0F
+};
+
+STATIC CHAR8 *mAlignName[] = {
+ "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
+ "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",
+ "512K", "1M", "2M", "4M", "8M", "16M"
+ };
+
+STATIC CHAR8 *mFfsValidAlignName[] = {
+ "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K","256K",
+ "512K", "1M", "2M", "4M", "8M", "16M"
+ };
+
+STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536, 131072, 262144,
+ 524288, 1048576, 2097152, 4194304, 8388608, 16777216};
+
+STATIC EFI_GUID mZeroGuid = {0};
+
+STATIC EFI_GUID mEfiFfsSectionAlignmentPaddingGuid = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;
+
+STATIC
+VOID
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print out version information for this utility.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print Error / Help message.
+
+Arguments:
+
+ VOID
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " -o FileName, --outputfile FileName\n\
+ File is FFS file to be created.\n");
+ fprintf (stdout, " -t Type, --filetype Type\n\
+ Type is one FV file type defined in PI spec, which is\n\
+ EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FREEFORM,\n\
+ EFI_FV_FILETYPE_SECURITY_CORE, EFI_FV_FILETYPE_PEIM,\n\
+ EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,\n\
+ EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION,\n\
+ EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\n\
+ EFI_FV_FILETYPE_SMM, EFI_FV_FILETYPE_SMM_CORE,\n\
+ EFI_FV_FILETYPE_MM_STANDALONE,\n\
+ EFI_FV_FILETYPE_MM_CORE_STANDALONE,\n\
+ EFI_FV_FILETYPE_COMBINED_SMM_DXE, \n\
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE.\n");
+ fprintf (stdout, " -g FileGuid, --fileguid FileGuid\n\
+ FileGuid is one module guid.\n\
+ Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
+ fprintf (stdout, " -x, --fixed Indicates that the file may not be moved\n\
+ from its present location.\n");
+ fprintf (stdout, " -s, --checksum Indicates to calculate file checksum.\n");
+ fprintf (stdout, " -a FileAlign, --align FileAlign\n\
+ FileAlign points to file alignment, which only support\n\
+ the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n\
+ 128K,256K,512K,1M,2M,4M,8M,16M\n");
+ fprintf (stdout, " -i SectionFile, --sectionfile SectionFile\n\
+ Section file will be contained in this FFS file.\n");
+ fprintf (stdout, " -oi SectionFile, --optionalsectionfile SectionFile\n\
+ If the Section file exists, it will be contained in this FFS file, otherwise, it will be ignored.\n");
+ fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\
+ SectionAlign points to section alignment, which support\n\
+ the alignment scope 0~16M. If SectionAlign is specified\n\
+ as 0, tool get alignment value from SectionFile. It is\n\
+ specified together with sectionfile to point its\n\
+ alignment in FFS file.\n");
+ fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
+ fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
+ fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
+}
+
+STATIC
+EFI_STATUS
+StringtoAlignment (
+ IN CHAR8 *AlignBuffer,
+ OUT UINT32 *AlignNumber
+ )
+/*++
+
+Routine Description:
+
+ Converts Align String to align value (1~16M).
+
+Arguments:
+
+ AlignBuffer - Pointer to Align string.
+ AlignNumber - Pointer to Align value.
+
+Returns:
+
+ EFI_SUCCESS Successfully convert align string to align value.
+ EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.
+
+--*/
+{
+ UINT32 Index = 0;
+ //
+ // Check AlignBuffer
+ //
+ if (AlignBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {
+ if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {
+ *AlignNumber = 1 << Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+STATIC
+UINT8
+StringToType (
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+
+ Converts File Type String to value. EFI_FV_FILETYPE_ALL indicates that an
+ unrecognized file type was specified.
+
+Arguments:
+
+ String - File type string
+
+Returns:
+
+ File Type Value
+
+--*/
+{
+ UINT8 Index = 0;
+
+ if (String == NULL) {
+ return EFI_FV_FILETYPE_ALL;
+ }
+
+ for (Index = 0; Index < sizeof (mFfsFileType) / sizeof (CHAR8 *); Index ++) {
+ if (mFfsFileType [Index] != NULL && (stricmp (String, mFfsFileType [Index]) == 0)) {
+ return Index;
+ }
+ }
+ return EFI_FV_FILETYPE_ALL;
+}
+
+STATIC
+EFI_STATUS
+GetSectionContents (
+ IN CHAR8 **InputFileName,
+ IN UINT32 *InputFileAlign,
+ IN UINT32 InputFileNum,
+ IN EFI_FFS_FILE_ATTRIBUTES FfsAttrib,
+ OUT UINT8 *FileBuffer,
+ OUT UINT32 *BufferLength,
+ OUT UINT32 *MaxAlignment,
+ OUT UINT8 *PESectionNum
+ )
+/*++
+
+Routine Description:
+
+ Get the contents of all section files specified in InputFileName
+ into FileBuffer.
+
+Arguments:
+
+ InputFileName - Name of the input file.
+
+ InputFileAlign - Alignment required by the input file data.
+
+ InputFileNum - Number of input files. Should be at least 1.
+
+ FileBuffer - Output buffer to contain data
+
+ BufferLength - On input, this is size of the FileBuffer.
+ On output, this is the actual length of the data.
+
+ MaxAlignment - The max alignment required by all the input file datas.
+
+ PeSectionNum - Calculate the number of Pe/Te Section in this FFS file.
+
+Returns:
+
+ EFI_SUCCESS on successful return
+ EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
+ EFI_ABORTED if unable to open input file.
+ EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
+--*/
+{
+ UINT32 Size;
+ UINT32 Offset;
+ UINT32 FileSize;
+ UINT32 Index;
+ FILE *InFile;
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION *SectHeader;
+ EFI_COMMON_SECTION_HEADER2 TempSectHeader;
+ EFI_TE_IMAGE_HEADER TeHeader;
+ UINT32 TeOffset;
+ EFI_GUID_DEFINED_SECTION GuidSectHeader;
+ EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
+ UINT32 HeaderSize;
+ UINT32 MaxEncounteredAlignment;
+
+ Size = 0;
+ Offset = 0;
+ TeOffset = 0;
+ MaxEncounteredAlignment = 1;
+
+ //
+ // Go through our array of file names and copy their contents
+ // to the output buffer.
+ //
+ for (Index = 0; Index < InputFileNum; Index++) {
+ //
+ // make sure section ends on a DWORD boundary
+ //
+ while ((Size & 0x03) != 0) {
+ Size++;
+ }
+
+ //
+ // Open file and read contents
+ //
+ InFile = fopen (LongFilePath (InputFileName[Index]), "rb");
+ if (InFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);
+ return EFI_ABORTED;
+ }
+
+ fseek (InFile, 0, SEEK_END);
+ FileSize = ftell (InFile);
+ fseek (InFile, 0, SEEK_SET);
+ DebugMsg (NULL, 0, 9, "Input section files",
+ "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize);
+
+ //
+ // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
+ //
+ TeOffset = 0;
+ if (FileSize >= MAX_FFS_SIZE) {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+ fread (&TempSectHeader, 1, HeaderSize, InFile);
+ if (TempSectHeader.Type == EFI_SECTION_TE) {
+ (*PESectionNum) ++;
+ fread (&TeHeader, 1, sizeof (TeHeader), InFile);
+ if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);
+ }
+ } else if (TempSectHeader.Type == EFI_SECTION_PE32) {
+ (*PESectionNum) ++;
+ } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {
+ fseek (InFile, 0, SEEK_SET);
+ if (FileSize >= MAX_SECTION_SIZE) {
+ fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);
+ if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader2.DataOffset;
+ }
+ } else {
+ fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
+ if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader.DataOffset;
+ }
+ }
+ (*PESectionNum) ++;
+ } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION ||
+ TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
+ //
+ // for the encapsulated section, assume it contains Pe/Te section
+ //
+ (*PESectionNum) ++;
+ }
+
+ fseek (InFile, 0, SEEK_SET);
+
+ //
+ // Revert TeOffset to the converse value relative to Alignment
+ // This is to assure the original PeImage Header at Alignment.
+ //
+ if ((TeOffset != 0) && (InputFileAlign [Index] != 0)) {
+ TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);
+ TeOffset = TeOffset % InputFileAlign [Index];
+ }
+
+ //
+ // make sure section data meet its alignment requirement by adding one pad section.
+ // But the different sections have the different section header. Necessary or not?
+ // Based on section type to adjust offset? Todo
+ //
+ if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {
+ Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);
+ Offset = Offset - Size - HeaderSize - TeOffset;
+
+ if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {
+ //
+ // The maximal alignment is 64K, the raw section size must be less than 0xffffff
+ //
+ memset (FileBuffer + Size, 0, Offset);
+ SectHeader = (EFI_FREEFORM_SUBTYPE_GUID_SECTION *) (FileBuffer + Size);
+ SectHeader->CommonHeader.Size[0] = (UINT8) (Offset & 0xff);
+ SectHeader->CommonHeader.Size[1] = (UINT8) ((Offset & 0xff00) >> 8);
+ SectHeader->CommonHeader.Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);
+
+ //
+ // Only add a special reducible padding section if
+ // - this FFS has the FFS_ATTRIB_FIXED attribute,
+ // - none of the preceding sections have alignment requirements,
+ // - the size of the padding is sufficient for the
+ // EFI_SECTION_FREEFORM_SUBTYPE_GUID header.
+ //
+ if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0 &&
+ MaxEncounteredAlignment <= 1 &&
+ Offset >= sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION)) {
+ SectHeader->CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID;
+ SectHeader->SubTypeGuid = mEfiFfsSectionAlignmentPaddingGuid;
+ } else {
+ SectHeader->CommonHeader.Type = EFI_SECTION_RAW;
+ }
+ }
+ DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment",
+ "Pad Raw section size is %u", (unsigned) Offset);
+
+ Size = Size + Offset;
+ }
+
+ //
+ // Get the Max alignment of all input file datas
+ //
+ if (MaxEncounteredAlignment < InputFileAlign [Index]) {
+ MaxEncounteredAlignment = InputFileAlign [Index];
+ }
+
+ //
+ // Now read the contents of the file into the buffer
+ // Buffer must be enough to contain the file content.
+ //
+ if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {
+ if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {
+ Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);
+ fclose (InFile);
+ return EFI_ABORTED;
+ }
+ }
+
+ fclose (InFile);
+ Size += FileSize;
+ }
+
+ *MaxAlignment = MaxEncounteredAlignment;
+
+ //
+ // Set the actual length of the data.
+ //
+ if (Size > *BufferLength) {
+ *BufferLength = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ *BufferLength = Size;
+ return EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+FfsRebaseImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINT32 *ReadSize,
+ OUT VOID *Buffer
+ )
+ /*++
+
+ Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+ Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+
+ FileOffset - The offset, in bytes, into the file to read
+
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+
+ Buffer - A pointer to the buffer to read the data into.
+
+ Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+ --*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINT32 Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
+ /*++
+ InFile is input file for getting alignment
+ return the alignment
+ --*/
+{
+ FILE *InFileHandle;
+ UINT8 *PeFileBuffer;
+ UINTN PeFileSize;
+ UINT32 CurSecHdrSize;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_COMMON_SECTION_HEADER *CommonHeader;
+ EFI_STATUS Status;
+
+ InFileHandle = NULL;
+ PeFileBuffer = NULL;
+ *Alignment = 0;
+
+ memset (&ImageContext, 0, sizeof (ImageContext));
+
+ InFileHandle = fopen(LongFilePath(InFile), "rb");
+ if (InFileHandle == NULL){
+ Error (NULL, 0, 0001, "Error opening file", InFile);
+ return EFI_ABORTED;
+ }
+ PeFileSize = _filelength (fileno(InFileHandle));
+ PeFileBuffer = (UINT8 *) malloc (PeFileSize);
+ if (PeFileBuffer == NULL) {
+ fclose (InFileHandle);
+ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
+ fclose (InFileHandle);
+ CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;
+ CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
+ ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo(&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);
+ return Status;
+ }
+ *Alignment = ImageContext.SectionAlignment;
+ // Free the allocated memory resource
+ if (PeFileBuffer != NULL) {
+ free (PeFileBuffer);
+ PeFileBuffer = NULL;
+ }
+ return EFI_SUCCESS;
+}
+
+int
+main (
+ int argc,
+ CHAR8 *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main function.
+
+Arguments:
+
+ argc - Number of command line parameters.
+ argv - Array of pointers to parameter strings.
+
+Returns:
+ STATUS_SUCCESS - Utility exits successfully.
+ STATUS_ERROR - Some error occurred during execution.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_ATTRIBUTES FfsAttrib;
+ UINT32 FfsAlign;
+ EFI_FV_FILETYPE FfsFiletype;
+ CHAR8 *OutputFileName;
+ EFI_GUID FileGuid = {0};
+ UINT32 InputFileNum;
+ UINT32 *InputFileAlign;
+ CHAR8 **InputFileName;
+ UINT8 *FileBuffer;
+ UINT32 FileSize;
+ UINT32 MaxAlignment;
+ EFI_FFS_FILE_HEADER2 FfsFileHeader;
+ FILE *FfsFile;
+ UINT32 Index;
+ UINT64 LogLevel;
+ UINT8 PeSectionNum;
+ UINT32 HeaderSize;
+ UINT32 Alignment;
+ //
+ // Workaround for static code checkers.
+ // Ensures the size of 'AlignmentBuffer' can hold all the digits of an
+ // unsigned 32-bit integer plus the size unit character.
+ //
+ CHAR8 AlignmentBuffer[16];
+
+ //
+ // Init local variables
+ //
+ LogLevel = 0;
+ Index = 0;
+ FfsAttrib = 0;
+ FfsAlign = 0;
+ FfsFiletype = EFI_FV_FILETYPE_ALL;
+ OutputFileName = NULL;
+ InputFileNum = 0;
+ InputFileName = NULL;
+ InputFileAlign = NULL;
+ FileBuffer = NULL;
+ FileSize = 0;
+ MaxAlignment = 1;
+ FfsFile = NULL;
+ Status = EFI_SUCCESS;
+ PeSectionNum = 0;
+
+ SetUtilityName (UTILITY_NAME);
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "no options input");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ //
+ // Parse command line
+ //
+ argc --;
+ argv ++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[0], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--filetype") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "file type is missing for -t option");
+ goto Finish;
+ }
+ FfsFiletype = StringToType (argv[1]);
+ if (FfsFiletype == EFI_FV_FILETYPE_ALL) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s is not a valid file type", argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Output file is missing for -o option");
+ goto Finish;
+ }
+ OutputFileName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--fileguid") == 0)) {
+ Status = StringToGuid (argv[1], &FileGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-x") == 0) || (stricmp (argv[0], "--fixed") == 0)) {
+ FfsAttrib |= FFS_ATTRIB_FIXED;
+ argc -= 1;
+ argv += 1;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--checksum") == 0)) {
+ FfsAttrib |= FFS_ATTRIB_CHECKSUM;
+ argc -= 1;
+ argv += 1;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Align value is missing for -a option");
+ goto Finish;
+ }
+ for (Index = 0; Index < sizeof (mFfsValidAlignName) / sizeof (CHAR8 *); Index ++) {
+ if (stricmp (argv[1], mFfsValidAlignName[Index]) == 0) {
+ break;
+ }
+ }
+ if (Index == sizeof (mFfsValidAlignName) / sizeof (CHAR8 *)) {
+ if ((stricmp (argv[1], "1") == 0) || (stricmp (argv[1], "2") == 0) || (stricmp (argv[1], "4") == 0)) {
+ //
+ // 1, 2, 4 byte alignment same to 8 byte alignment
+ //
+ Index = 0;
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ }
+ FfsAlign = Index;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-oi") == 0) || (stricmp (argv[0], "--optionalsectionfile") == 0) || (stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--sectionfile") == 0)) {
+ //
+ // Get Input file name and its alignment
+ //
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "input section file is missing for -i option");
+ goto Finish;
+ }
+ if ((stricmp (argv[0], "-oi") == 0) || (stricmp (argv[0], "--optionalsectionfile") == 0) ){
+ if (-1 == access(argv[1] , 0)){
+ Warning(NULL, 0, 0001, "File is not found.", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ }
+ //
+ // Allocate Input file name buffer and its alignment buffer.
+ //
+ if ((InputFileNum == 0) && (InputFileName == NULL)) {
+ InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return STATUS_ERROR;
+ }
+ memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
+
+ InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
+ if (InputFileAlign == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ free (InputFileName);
+ return STATUS_ERROR;
+ }
+ memset (InputFileAlign, 0, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
+ } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
+ //
+ // InputFileName and alignment buffer too small, need to realloc
+ //
+ InputFileName = (CHAR8 **) realloc (
+ InputFileName,
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
+ );
+
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ free (InputFileAlign);
+ return STATUS_ERROR;
+ }
+ memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
+
+ InputFileAlign = (UINT32 *) realloc (
+ InputFileAlign,
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)
+ );
+
+ if (InputFileAlign == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ free (InputFileName);
+ return STATUS_ERROR;
+ }
+ memset (&(InputFileAlign[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));
+ }
+
+ InputFileName[InputFileNum] = argv[1];
+ argc -= 2;
+ argv += 2;
+
+ if (argc <= 0) {
+ InputFileNum ++;
+ break;
+ }
+
+ //
+ // Section File alignment requirement
+ //
+ if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
+ if ((argv[1] != NULL) && (stricmp("0", argv[1]) == 0)) {
+ Status = GetAlignmentFromFile(InputFileName[InputFileNum], &Alignment);
+ if (EFI_ERROR(Status)) {
+ Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);
+ goto Finish;
+ }
+ if (Alignment < 0x400){
+ sprintf (AlignmentBuffer, "%d", Alignment);
+ }
+ else if (Alignment >= 0x100000) {
+ sprintf (AlignmentBuffer, "%dM", Alignment/0x100000);
+ }
+ else {
+ sprintf (AlignmentBuffer, "%dK", Alignment/0x400);
+ }
+ Status = StringtoAlignment (AlignmentBuffer, &(InputFileAlign[InputFileNum]));
+ }
+ else {
+ Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));
+ }
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ }
+ InputFileNum ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
+ Error (NULL, 0, 1000, "Unknown option", "SectionAlign option must be specified with section file.");
+ goto Finish;
+ }
+
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
+ SetPrintLevel (VERBOSE_LOG_LEVEL);
+ VerboseMsg ("Verbose output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ SetPrintLevel (KEY_LOG_LEVEL);
+ KeyMsg ("Quiet output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ if (LogLevel > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
+ goto Finish;
+ }
+ SetPrintLevel (LogLevel);
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);
+ goto Finish;
+ }
+
+ VerboseMsg ("%s tool start.", UTILITY_NAME);
+
+ //
+ // Check the complete input parameters.
+ //
+ if (FfsFiletype == EFI_FV_FILETYPE_ALL) {
+ Error (NULL, 0, 1001, "Missing option", "filetype");
+ goto Finish;
+ }
+
+ if (CompareGuid (&FileGuid, &mZeroGuid) == 0) {
+ Error (NULL, 0, 1001, "Missing option", "fileguid");
+ goto Finish;
+ }
+
+ if (InputFileNum == 0) {
+ Error (NULL, 0, 1001, "Missing option", "Input files");
+ goto Finish;
+ }
+
+ //
+ // Output input parameter information
+ //
+ VerboseMsg ("Fv File type is %s", mFfsFileType [FfsFiletype]);
+ VerboseMsg ("Output file name is %s", OutputFileName);
+ VerboseMsg ("FFS File Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ (unsigned) FileGuid.Data1,
+ FileGuid.Data2,
+ FileGuid.Data3,
+ FileGuid.Data4[0],
+ FileGuid.Data4[1],
+ FileGuid.Data4[2],
+ FileGuid.Data4[3],
+ FileGuid.Data4[4],
+ FileGuid.Data4[5],
+ FileGuid.Data4[6],
+ FileGuid.Data4[7]);
+ if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0) {
+ VerboseMsg ("FFS File has the fixed file attribute");
+ }
+ if ((FfsAttrib & FFS_ATTRIB_CHECKSUM) != 0) {
+ VerboseMsg ("FFS File requires the checksum of the whole file");
+ }
+ VerboseMsg ("FFS file alignment is %s", mFfsValidAlignName[FfsAlign]);
+ for (Index = 0; Index < InputFileNum; Index ++) {
+ if (InputFileAlign[Index] == 0) {
+ //
+ // Minimum alignment is 1 byte.
+ //
+ InputFileAlign[Index] = 1;
+ }
+ VerboseMsg ("the %dth input section name is %s and section alignment is %u", Index, InputFileName[Index], (unsigned) InputFileAlign[Index]);
+ }
+
+ //
+ // Calculate the size of all input section files.
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ FfsAttrib,
+ FileBuffer,
+ &FileSize,
+ &MaxAlignment,
+ &PeSectionNum
+ );
+
+ if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE ||
+ FfsFiletype == EFI_FV_FILETYPE_PEI_CORE ||
+ FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %u Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);
+ goto Finish;
+ }
+
+ if ((FfsFiletype == EFI_FV_FILETYPE_PEIM ||
+ FfsFiletype == EFI_FV_FILETYPE_DRIVER ||
+ FfsFiletype == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER ||
+ FfsFiletype == EFI_FV_FILETYPE_APPLICATION) && (PeSectionNum < 1)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe or Te section, but no Pe/Te section is input", mFfsFileType [FfsFiletype]);
+ goto Finish;
+ }
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FileBuffer = (UINT8 *) malloc (FileSize);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+ memset (FileBuffer, 0, FileSize);
+
+ //
+ // read all input file contents into a buffer
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ FfsAttrib,
+ FileBuffer,
+ &FileSize,
+ &MaxAlignment,
+ &PeSectionNum
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto Finish;
+ }
+
+ if (FileBuffer == NULL && FileSize != 0) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+
+ //
+ // Create Ffs file header.
+ //
+ memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER2));
+ memcpy (&FfsFileHeader.Name, &FileGuid, sizeof (EFI_GUID));
+ FfsFileHeader.Type = FfsFiletype;
+ //
+ // Update FFS Alignment based on the max alignment required by input section files
+ //
+ VerboseMsg ("the max alignment of all input sections is %u", (unsigned) MaxAlignment);
+ for (Index = 0; Index < sizeof (mFfsValidAlign) / sizeof (UINT32) - 1; Index ++) {
+ if ((MaxAlignment > mFfsValidAlign [Index]) && (MaxAlignment <= mFfsValidAlign [Index + 1])) {
+ break;
+ }
+ }
+ if (FfsAlign < Index) {
+ FfsAlign = Index;
+ }
+ VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]);
+
+ //
+ // Now FileSize includes the EFI_FFS_FILE_HEADER
+ //
+ if (FileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
+ HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
+ FileSize += sizeof (EFI_FFS_FILE_HEADER2);
+ FfsFileHeader.ExtendedSize = FileSize;
+ memset(FfsFileHeader.Size, 0, sizeof (UINT8) * 3);
+ FfsAttrib |= FFS_ATTRIB_LARGE_FILE;
+ } else {
+ HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
+ FileSize += sizeof (EFI_FFS_FILE_HEADER);
+ FfsFileHeader.Size[0] = (UINT8) (FileSize & 0xFF);
+ FfsFileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8);
+ FfsFileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16);
+ }
+ VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);
+
+ //FfsAlign larger than 7, set FFS_ATTRIB_DATA_ALIGNMENT2
+ if (FfsAlign < 8) {
+ FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
+ } else {
+ FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | ((FfsAlign & 0x7) << 3) | FFS_ATTRIB_DATA_ALIGNMENT2);
+ }
+
+ //
+ // Fill in checksums and state, these must be zero for checksumming
+ //
+ // FileHeader.IntegrityCheck.Checksum.Header = 0;
+ // FileHeader.IntegrityCheck.Checksum.File = 0;
+ // FileHeader.State = 0;
+ //
+ FfsFileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (
+ (UINT8 *) &FfsFileHeader,
+ HeaderSize
+ );
+
+ if (FfsFileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {
+ //
+ // Ffs header checksum = zero, so only need to calculate ffs body.
+ //
+ FfsFileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (
+ FileBuffer,
+ FileSize - HeaderSize
+ );
+ } else {
+ FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
+ }
+
+ FfsFileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
+
+ //
+ // Open output file to write ffs data.
+ //
+ if (OutputFileName != NULL) {
+ remove(OutputFileName);
+ FfsFile = fopen (LongFilePath (OutputFileName), "wb");
+ if (FfsFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", OutputFileName);
+ goto Finish;
+ }
+ //
+ // write header
+ //
+ fwrite (&FfsFileHeader, 1, HeaderSize, FfsFile);
+ //
+ // write data
+ //
+ if (FileBuffer != NULL) {
+ fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);
+ }
+
+ fclose (FfsFile);
+ }
+
+Finish:
+ if (InputFileName != NULL) {
+ free (InputFileName);
+ }
+ if (InputFileAlign != NULL) {
+ free (InputFileAlign);
+ }
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+ //
+ // If any errors were reported via the standard error reporting
+ // routines, then the status has been saved. Get the value and
+ // return it to the caller.
+ //
+ VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
+
+ return GetUtilityStatus ();
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile
new file mode 100644
index 00000000..1f805241
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile
@@ -0,0 +1,16 @@
+## @file
+# Windows makefile for 'GenFfs' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenFfs
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = GenFfs.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile.kmk
new file mode 100644
index 00000000..8a200b35
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFfs/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI GenFfs build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += GenFfs
+GenFfs_TEMPLATE = VBoxEfiBldProg
+GenFfs_SOURCES = GenFfs.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GNUmakefile
new file mode 100644
index 00000000..608d9b48
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GNUmakefile
@@ -0,0 +1,23 @@
+## @file
+# GNU/Linux makefile for 'GenFv' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = GenFv
+
+OBJECTS = GenFv.o GenFvInternalLib.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+ifeq ($(CYGWIN), CYGWIN)
+ LIBS += -L/lib/e2fsprogs -luuid
+endif
+
+ifeq ($(LINUX), Linux)
+ LIBS += -luuid
+endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFv.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFv.c
new file mode 100644
index 00000000..21b0a392
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFv.c
@@ -0,0 +1,696 @@
+/** @file
+ This contains all code necessary to build the GenFvImage.exe utility.
+ This utility relies heavily on the GenFvImage Lib. Definitions for both
+ can be found in the Tiano Firmware Volume Generation Utility
+ Specification, review draft.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// File included in build
+//
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "GenFvInternalLib.h"
+
+//
+// Utility Name
+//
+#define UTILITY_NAME "GenFv"
+
+//
+// Utility version information
+//
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+EFI_GUID mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;
+EFI_GUID mEfiFirmwareFileSystem3Guid = EFI_FIRMWARE_FILE_SYSTEM3_GUID;
+
+STATIC
+VOID
+Version (
+ VOID
+)
+/*++
+
+Routine Description:
+
+ Displays the standard utility information to SDTOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " -o FileName, --outputfile FileName\n\
+ File is the FvImage or CapImage to be created.\n");
+ fprintf (stdout, " -i FileName, --inputfile FileName\n\
+ File is the input FV.inf or Cap.inf to specify\n\
+ how to construct FvImage or CapImage.\n");
+ fprintf (stdout, " -b BlockSize, --blocksize BlockSize\n\
+ BlockSize is one HEX or DEC format value\n\
+ BlockSize is required by Fv Image.\n");
+ fprintf (stdout, " -n NumberBlock, --numberblock NumberBlock\n\
+ NumberBlock is one HEX or DEC format value\n\
+ NumberBlock is one optional parameter.\n");
+ fprintf (stdout, " -f FfsFile, --ffsfile FfsFile\n\
+ FfsFile is placed into Fv Image\n\
+ multi files can input one by one\n");
+ fprintf (stdout, " -s FileTakenSize, --filetakensize FileTakenSize\n\
+ FileTakenSize specifies the size of the required\n\
+ space that the input file is placed in Fvimage.\n\
+ It is specified together with the input file.\n");
+ fprintf (stdout, " -r Address, --baseaddr Address\n\
+ Address is the rebase start address for drivers that\n\
+ run in Flash. It supports DEC or HEX digital format.\n\
+ If it is set to zero, no rebase action will be taken\n");
+ fprintf (stdout, " -F ForceRebase, --force-rebase ForceRebase\n\
+ If value is TRUE, will always take rebase action\n\
+ If value is FALSE, will always not take reabse action\n\
+ If not specified, will take rebase action if rebase address greater than zero, \n\
+ will not take rebase action if rebase address is zero.\n");
+ fprintf (stdout, " -a AddressFile, --addrfile AddressFile\n\
+ AddressFile is one file used to record the child\n\
+ FV base address when current FV base address is set.\n");
+ fprintf (stdout, " -m logfile, --map logfile\n\
+ Logfile is the output fv map file name. if it is not\n\
+ given, the FvName.map will be the default map file name\n");
+ fprintf (stdout, " -g Guid, --guid Guid\n\
+ GuidValue is one specific capsule guid value\n\
+ or fv file system guid value.\n\
+ Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
+ fprintf (stdout, " --FvNameGuid Guid Guid is used to specify Fv Name.\n\
+ Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
+ fprintf (stdout, " --capflag CapFlag Capsule Reset Flag can be PersistAcrossReset,\n\
+ or PopulateSystemTable or InitiateReset or not set\n");
+ fprintf (stdout, " --capoemflag CapOEMFlag\n\
+ Capsule OEM Flag is an integer between 0x0000 and 0xffff\n");
+ fprintf (stdout, " --capheadsize HeadSize\n\
+ HeadSize is one HEX or DEC format value\n\
+ HeadSize is required by Capsule Image.\n");
+ fprintf (stdout, " -c, --capsule Create Capsule Image.\n");
+ fprintf (stdout, " -p, --dump Dump Capsule Image header.\n");
+ fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
+ fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
+ fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
+}
+
+UINT32 mFvTotalSize;
+UINT32 mFvTakenSize;
+
+int
+main (
+ IN int argc,
+ IN char **argv
+ )
+/*++
+
+Routine Description:
+
+ This utility uses GenFvImage.Lib to build a firmware volume image.
+
+Arguments:
+
+ FvInfFileName The name of an FV image description file or Capsule Image.
+
+ Arguments come in pair in any order.
+ -I FvInfFileName
+
+Returns:
+
+ EFI_SUCCESS No error conditions detected.
+ EFI_INVALID_PARAMETER One or more of the input parameters is invalid.
+ EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable.
+ Most commonly this will be memory allocation
+ or file creation.
+ EFI_LOAD_ERROR GenFvImage.lib could not be loaded.
+ EFI_ABORTED Error executing the GenFvImage lib.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *InfFileName;
+ CHAR8 *AddrFileName;
+ CHAR8 *MapFileName;
+ CHAR8 *InfFileImage;
+ UINT32 InfFileSize;
+ CHAR8 *OutFileName;
+ BOOLEAN CapsuleFlag;
+ BOOLEAN DumpCapsule;
+ FILE *FpFile;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ UINT64 LogLevel, TempNumber;
+ UINT32 Index;
+
+ InfFileName = NULL;
+ AddrFileName = NULL;
+ InfFileImage = NULL;
+ OutFileName = NULL;
+ MapFileName = NULL;
+ InfFileSize = 0;
+ CapsuleFlag = FALSE;
+ DumpCapsule = FALSE;
+ FpFile = NULL;
+ CapsuleHeader = NULL;
+ LogLevel = 0;
+ TempNumber = 0;
+ Index = 0;
+ mFvTotalSize = 0;
+ mFvTakenSize = 0;
+ Status = EFI_SUCCESS;
+
+ SetUtilityName (UTILITY_NAME);
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No input options specified.");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ //
+ // Init global data to Zero
+ //
+ memset (&mFvDataInfo, 0, sizeof (FV_INFO));
+ memset (&mCapDataInfo, 0, sizeof (CAP_INFO));
+ //
+ // Set the default FvGuid
+ //
+ memcpy (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid, sizeof (EFI_GUID));
+ mFvDataInfo.ForceRebase = -1;
+
+ //
+ // Parse command line
+ //
+ argc --;
+ argv ++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[0], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {
+ InfFileName = argv[1];
+ if (InfFileName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");
+ return STATUS_ERROR;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {
+ AddrFileName = argv[1];
+ if (AddrFileName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");
+ return STATUS_ERROR;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
+ OutFileName = argv[1];
+ if (OutFileName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");
+ return STATUS_ERROR;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ mFvDataInfo.BaseAddress = TempNumber;
+ mFvDataInfo.BaseAddressSet = TRUE;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ if (TempNumber == 0) {
+ Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");
+ return STATUS_ERROR;
+ }
+ mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;
+ DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%llx", EFI_BLOCK_SIZE_STRING, (unsigned long long) TempNumber);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ if (TempNumber == 0) {
+ Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");
+ return STATUS_ERROR;
+ }
+ mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;
+ DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%llx", EFI_NUM_BLOCKS_STRING, (unsigned long long) TempNumber);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((strcmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");
+ return STATUS_ERROR;
+ }
+ if (strlen (argv[1]) > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile name %s is too long!", argv[1]);
+ return STATUS_ERROR;
+ }
+ strncpy (mFvDataInfo.FvFiles[Index], argv[1], MAX_LONG_FILE_PATH - 1);
+ mFvDataInfo.FvFiles[Index][MAX_LONG_FILE_PATH - 1] = 0;
+ DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index + 1, argv[1]);
+ argc -= 2;
+ argv += 2;
+
+ if (argc > 0) {
+ if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");
+ return STATUS_ERROR;
+ }
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ mFvDataInfo.SizeofFvFiles[Index] = (UINT32) TempNumber;
+ DebugMsg (NULL, 0, 9, "FV component file size", "the %uth size is %s", (unsigned) Index + 1, argv[1]);
+ argc -= 2;
+ argv += 2;
+ }
+ }
+ Index ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {
+ Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");
+ return STATUS_ERROR;
+ }
+
+ if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {
+ CapsuleFlag = TRUE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((strcmp (argv[0], "-F") == 0) || (stricmp (argv[0], "--force-rebase") == 0)) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Froce rebase flag can't be null");
+ return STATUS_ERROR;
+ }
+
+ if (stricmp (argv[1], "TRUE") == 0) {
+ mFvDataInfo.ForceRebase = 1;
+ } else if (stricmp (argv[1], "FALSE") == 0) {
+ mFvDataInfo.ForceRebase = 0;
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "froce rebase flag value must be \"TRUE\" or \"FALSE\"");
+ return STATUS_ERROR;
+ }
+
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--capheadsize") == 0) {
+ //
+ // Get Capsule Image Header Size
+ //
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ mCapDataInfo.HeaderSize = (UINT32) TempNumber;
+ DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%llx", EFI_CAPSULE_HEADER_SIZE_STRING, (unsigned long long) TempNumber);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--capflag") == 0) {
+ //
+ // Get Capsule Header
+ //
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ if (strcmp (argv[1], "PopulateSystemTable") == 0) {
+ mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
+ } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {
+ mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
+ } else if (strcmp (argv[1], "InitiateReset") == 0) {
+ mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET;
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--capoemflag") == 0) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag can't be null");
+ }
+ Status = AsciiStringToUint64(argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status) || TempNumber > 0xffff) {
+ Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag value must be integer value between 0x0000 and 0xffff");
+ return STATUS_ERROR;
+ }
+ mCapDataInfo.Flags |= TempNumber;
+ DebugMsg( NULL, 0, 9, "Capsule OEM Flags", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--capguid") == 0) {
+ //
+ // Get the Capsule Guid
+ //
+ Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
+ return STATUS_ERROR;
+ }
+ DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {
+ //
+ // Get the Capsule or Fv Guid
+ //
+ Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
+ return STATUS_ERROR;
+ }
+ memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));
+ mFvDataInfo.FvFileSystemGuidSet = TRUE;
+ DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);
+ DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--FvNameGuid") == 0) {
+ //
+ // Get Fv Name Guid
+ //
+ Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);
+ return STATUS_ERROR;
+ }
+ mFvDataInfo.FvNameGuidSet = TRUE;
+ DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {
+ DumpCapsule = TRUE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {
+ MapFileName = argv[1];
+ if (MapFileName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");
+ return STATUS_ERROR;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
+ SetPrintLevel (VERBOSE_LOG_LEVEL);
+ VerboseMsg ("Verbose output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ SetPrintLevel (KEY_LOG_LEVEL);
+ KeyMsg ("Quiet output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return STATUS_ERROR;
+ }
+ if (LogLevel > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
+ return STATUS_ERROR;
+ }
+ SetPrintLevel (LogLevel);
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ //
+ // Don't recognize the parameter.
+ //
+ Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);
+ return STATUS_ERROR;
+ }
+
+ VerboseMsg ("%s tool start.", UTILITY_NAME);
+
+ //
+ // check input parameter, InfFileName can be NULL
+ //
+ if (InfFileName == NULL && DumpCapsule) {
+ Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");
+ return STATUS_ERROR;
+ }
+ VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);
+
+ if (!DumpCapsule && OutFileName == NULL) {
+ Error (NULL, 0, 1001, "Missing option", "Output File");
+ return STATUS_ERROR;
+ }
+ if (OutFileName != NULL) {
+ VerboseMsg ("the output file name is %s", OutFileName);
+ }
+
+ //
+ // Read the INF file image
+ //
+ if (InfFileName != NULL) {
+ Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);
+ if (EFI_ERROR (Status)) {
+ return STATUS_ERROR;
+ }
+ }
+
+ if (DumpCapsule) {
+ VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);
+ //
+ // Dump Capsule Image Header Information
+ //
+ CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;
+ if (OutFileName == NULL) {
+ FpFile = stdout;
+ } else {
+ FpFile = fopen (LongFilePath (OutFileName), "w");
+ if (FpFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", OutFileName);
+ return STATUS_ERROR;
+ }
+ }
+ if (FpFile != NULL) {
+ fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);
+ fprintf (FpFile, " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
+ (unsigned) CapsuleHeader->CapsuleGuid.Data1,
+ (unsigned) CapsuleHeader->CapsuleGuid.Data2,
+ (unsigned) CapsuleHeader->CapsuleGuid.Data3,
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[0],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[1],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[2],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[3],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[4],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[5],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[6],
+ (unsigned) CapsuleHeader->CapsuleGuid.Data4[7]);
+ fprintf (FpFile, " Header size 0x%08X\n", (unsigned) CapsuleHeader->HeaderSize);
+ fprintf (FpFile, " Flags 0x%08X\n", (unsigned) CapsuleHeader->Flags);
+ fprintf (FpFile, " Capsule image size 0x%08X\n", (unsigned) CapsuleHeader->CapsuleImageSize);
+ fclose (FpFile);
+ }
+ } else if (CapsuleFlag) {
+ VerboseMsg ("Create capsule image");
+ //
+ // Call the GenerateCapImage to generate Capsule Image
+ //
+ for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {
+ strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);
+ }
+
+ Status = GenerateCapImage (
+ InfFileImage,
+ InfFileSize,
+ OutFileName
+ );
+ } else {
+ VerboseMsg ("Create Fv image and its map file");
+ //
+ // Will take rebase action at below situation:
+ // 1. ForceRebase Flag specified to TRUE;
+ // 2. ForceRebase Flag not specified, BaseAddress greater than zero.
+ //
+ if (((mFvDataInfo.BaseAddress > 0) && (mFvDataInfo.ForceRebase == -1)) || (mFvDataInfo.ForceRebase == 1)) {
+ VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);
+ }
+ //
+ // Call the GenerateFvImage to generate Fv Image
+ //
+ Status = GenerateFvImage (
+ InfFileImage,
+ InfFileSize,
+ OutFileName,
+ MapFileName
+ );
+ }
+
+ //
+ // free InfFileImage memory
+ //
+ if (InfFileImage != NULL) {
+ free (InfFileImage);
+ }
+
+ //
+ // update boot driver address and runtime driver address in address file
+ //
+ if (Status == EFI_SUCCESS && AddrFileName != NULL && mFvBaseAddressNumber > 0) {
+ FpFile = fopen (LongFilePath (AddrFileName), "w");
+ if (FpFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", AddrFileName);
+ return STATUS_ERROR;
+ }
+ fprintf (FpFile, FV_BASE_ADDRESS_STRING);
+ fprintf (FpFile, "\n");
+ for (Index = 0; Index < mFvBaseAddressNumber; Index ++) {
+ fprintf (
+ FpFile,
+ "0x%llx\n",
+ (unsigned long long)mFvBaseAddress[Index]
+ );
+ }
+ fflush (FpFile);
+ fclose (FpFile);
+ }
+
+ if (Status == EFI_SUCCESS) {
+ DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
+ DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);
+ DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));
+ }
+
+ VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
+
+ return GetUtilityStatus ();
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.c
new file mode 100644
index 00000000..85ea51eb
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -0,0 +1,4432 @@
+/** @file
+This file contains the internal functions required to generate a Firmware Volume.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Include files
+//
+
+#if defined(__FreeBSD__)
+#include <uuid.h>
+#elif defined(__GNUC__)
+#include <uuid/uuid.h>
+#endif
+#ifdef __GNUC__
+#include <sys/stat.h>
+#endif
+#include <string.h>
+#ifndef __GNUC__
+#include <io.h>
+#endif
+#include <assert.h>
+
+#include <Guid/FfsSectionAlignmentPadding.h>
+
+#include "WinNtInclude.h"
+#include "GenFvInternalLib.h"
+#include "FvLib.h"
+#include "PeCoffLib.h"
+
+#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION 0xEB000000
+#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000
+
+BOOLEAN mArm = FALSE;
+BOOLEAN mRiscV = FALSE;
+STATIC UINT32 MaxFfsAlignment = 0;
+BOOLEAN VtfFileFlag = FALSE;
+
+EFI_GUID mEfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
+EFI_GUID mFileGuidArray [MAX_NUMBER_OF_FILES_IN_FV];
+EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+EFI_GUID mDefaultCapsuleGuid = {0x3B6686BD, 0x0D76, 0x4030, { 0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0 }};
+EFI_GUID mEfiFfsSectionAlignmentPaddingGuid = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;
+
+CHAR8 *mFvbAttributeName[] = {
+ EFI_FVB2_READ_DISABLED_CAP_STRING,
+ EFI_FVB2_READ_ENABLED_CAP_STRING,
+ EFI_FVB2_READ_STATUS_STRING,
+ EFI_FVB2_WRITE_DISABLED_CAP_STRING,
+ EFI_FVB2_WRITE_ENABLED_CAP_STRING,
+ EFI_FVB2_WRITE_STATUS_STRING,
+ EFI_FVB2_LOCK_CAP_STRING,
+ EFI_FVB2_LOCK_STATUS_STRING,
+ NULL,
+ EFI_FVB2_STICKY_WRITE_STRING,
+ EFI_FVB2_MEMORY_MAPPED_STRING,
+ EFI_FVB2_ERASE_POLARITY_STRING,
+ EFI_FVB2_READ_LOCK_CAP_STRING,
+ EFI_FVB2_READ_LOCK_STATUS_STRING,
+ EFI_FVB2_WRITE_LOCK_CAP_STRING,
+ EFI_FVB2_WRITE_LOCK_STATUS_STRING
+};
+
+CHAR8 *mFvbAlignmentName[] = {
+ EFI_FVB2_ALIGNMENT_1_STRING,
+ EFI_FVB2_ALIGNMENT_2_STRING,
+ EFI_FVB2_ALIGNMENT_4_STRING,
+ EFI_FVB2_ALIGNMENT_8_STRING,
+ EFI_FVB2_ALIGNMENT_16_STRING,
+ EFI_FVB2_ALIGNMENT_32_STRING,
+ EFI_FVB2_ALIGNMENT_64_STRING,
+ EFI_FVB2_ALIGNMENT_128_STRING,
+ EFI_FVB2_ALIGNMENT_256_STRING,
+ EFI_FVB2_ALIGNMENT_512_STRING,
+ EFI_FVB2_ALIGNMENT_1K_STRING,
+ EFI_FVB2_ALIGNMENT_2K_STRING,
+ EFI_FVB2_ALIGNMENT_4K_STRING,
+ EFI_FVB2_ALIGNMENT_8K_STRING,
+ EFI_FVB2_ALIGNMENT_16K_STRING,
+ EFI_FVB2_ALIGNMENT_32K_STRING,
+ EFI_FVB2_ALIGNMENT_64K_STRING,
+ EFI_FVB2_ALIGNMENT_128K_STRING,
+ EFI_FVB2_ALIGNMENT_256K_STRING,
+ EFI_FVB2_ALIGNMENT_512K_STRING,
+ EFI_FVB2_ALIGNMENT_1M_STRING,
+ EFI_FVB2_ALIGNMENT_2M_STRING,
+ EFI_FVB2_ALIGNMENT_4M_STRING,
+ EFI_FVB2_ALIGNMENT_8M_STRING,
+ EFI_FVB2_ALIGNMENT_16M_STRING,
+ EFI_FVB2_ALIGNMENT_32M_STRING,
+ EFI_FVB2_ALIGNMENT_64M_STRING,
+ EFI_FVB2_ALIGNMENT_128M_STRING,
+ EFI_FVB2_ALIGNMENT_256M_STRING,
+ EFI_FVB2_ALIGNMENT_512M_STRING,
+ EFI_FVB2_ALIGNMENT_1G_STRING,
+ EFI_FVB2_ALIGNMENT_2G_STRING
+};
+
+//
+// This data array will be located at the base of the Firmware Volume Header (FVH)
+// in the boot block. It must not exceed 14 bytes of code. The last 2 bytes
+// will be used to keep the FVH checksum consistent.
+// This code will be run in response to a startup IPI for HT-enabled systems.
+//
+#define SIZEOF_STARTUP_DATA_ARRAY 0x10
+
+UINT8 m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {
+ //
+ // EA D0 FF 00 F0 ; far jmp F000:FFD0
+ // 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes
+ // 0, 0 ; Checksum Padding
+ //
+ 0xEA,
+ 0xD0,
+ 0xFF,
+ 0x0,
+ 0xF0,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+UINT8 m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {
+ //
+ // EB CE ; jmp short ($-0x30)
+ // ; (from offset 0x0 to offset 0xFFD0)
+ // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes
+ // 0, 0 ; Checksum Padding
+ //
+ 0xEB,
+ 0xCE,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+FV_INFO mFvDataInfo;
+CAP_INFO mCapDataInfo;
+BOOLEAN mIsLargeFfs = FALSE;
+
+EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];
+UINT32 mFvBaseAddressNumber = 0;
+
+EFI_STATUS
+ParseFvInf (
+ IN MEMORY_FILE *InfFile,
+ OUT FV_INFO *FvInfo
+ )
+/*++
+
+Routine Description:
+
+ This function parses a FV.INF file and copies info into a FV_INFO structure.
+
+Arguments:
+
+ InfFile Memory file image.
+ FvInfo Information read from INF file.
+
+Returns:
+
+ EFI_SUCCESS INF file information successfully retrieved.
+ EFI_ABORTED INF file has an invalid format.
+ EFI_NOT_FOUND A required string was not found in the INF file.
+--*/
+{
+ CHAR8 Value[MAX_LONG_FILE_PATH];
+ UINT64 Value64;
+ UINTN Index;
+ UINTN Number;
+ EFI_STATUS Status;
+ EFI_GUID GuidValue;
+
+ //
+ // Read the FV base address
+ //
+ if (!mFvDataInfo.BaseAddressSet) {
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ //
+ // Get the base address
+ //
+ Status = AsciiStringToUint64 (Value, FALSE, &Value64);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_BASE_ADDRESS_STRING, Value);
+ return EFI_ABORTED;
+ }
+ DebugMsg (NULL, 0, 9, "rebase address", "%s = %s", EFI_FV_BASE_ADDRESS_STRING, Value);
+
+ FvInfo->BaseAddress = Value64;
+ FvInfo->BaseAddressSet = TRUE;
+ }
+ }
+
+ //
+ // Read the FV File System Guid
+ //
+ if (!FvInfo->FvFileSystemGuidSet) {
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILESYSTEMGUID_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ //
+ // Get the guid value
+ //
+ Status = StringToGuid (Value, &GuidValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, Value);
+ return EFI_ABORTED;
+ }
+ memcpy (&FvInfo->FvFileSystemGuid, &GuidValue, sizeof (EFI_GUID));
+ FvInfo->FvFileSystemGuidSet = TRUE;
+ }
+ }
+
+ //
+ // Read the FV Extension Header File Name
+ //
+ Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_EXT_HEADER_FILE_NAME, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ strcpy (FvInfo->FvExtHeaderFile, Value);
+ }
+
+ //
+ // Read the FV file name
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ //
+ // copy the file name
+ //
+ strcpy (FvInfo->FvName, Value);
+ }
+
+ //
+ // Read Fv Attribute
+ //
+ for (Index = 0; Index < sizeof (mFvbAttributeName)/sizeof (CHAR8 *); Index ++) {
+ if ((mFvbAttributeName [Index] != NULL) && \
+ (FindToken (InfFile, ATTRIBUTES_SECTION_STRING, mFvbAttributeName [Index], 0, Value) == EFI_SUCCESS)) {
+ if ((strcmp (Value, TRUE_STRING) == 0) || (strcmp (Value, ONE_STRING) == 0)) {
+ FvInfo->FvAttributes |= 1 << Index;
+ } else if ((strcmp (Value, FALSE_STRING) != 0) && (strcmp (Value, ZERO_STRING) != 0)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s expected %s | %s", mFvbAttributeName [Index], TRUE_STRING, FALSE_STRING);
+ return EFI_ABORTED;
+ }
+ }
+ }
+
+ //
+ // Read Fv Alignment
+ //
+ for (Index = 0; Index < sizeof (mFvbAlignmentName)/sizeof (CHAR8 *); Index ++) {
+ if (FindToken (InfFile, ATTRIBUTES_SECTION_STRING, mFvbAlignmentName [Index], 0, Value) == EFI_SUCCESS) {
+ if (strcmp (Value, TRUE_STRING) == 0) {
+ FvInfo->FvAttributes |= Index << 16;
+ DebugMsg (NULL, 0, 9, "FV file alignment", "Align = %s", mFvbAlignmentName [Index]);
+ break;
+ }
+ }
+ }
+
+ //
+ // Read weak alignment flag
+ //
+ Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_WEAK_ALIGNMENT_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ if ((strcmp (Value, TRUE_STRING) == 0) || (strcmp (Value, ONE_STRING) == 0)) {
+ FvInfo->FvAttributes |= EFI_FVB2_WEAK_ALIGNMENT;
+ } else if ((strcmp (Value, FALSE_STRING) != 0) && (strcmp (Value, ZERO_STRING) != 0)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Weak alignment value expected one of TRUE, FALSE, 1 or 0.");
+ return EFI_ABORTED;
+ }
+ }
+
+ //
+ // Read block maps
+ //
+ for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) {
+ if (FvInfo->FvBlocks[Index].Length == 0) {
+ //
+ // Read block size
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Update the size of block
+ //
+ Status = AsciiStringToUint64 (Value, FALSE, &Value64);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_BLOCK_SIZE_STRING, Value);
+ return EFI_ABORTED;
+ }
+
+ FvInfo->FvBlocks[Index].Length = (UINT32) Value64;
+ DebugMsg (NULL, 0, 9, "FV Block Size", "%s = %s", EFI_BLOCK_SIZE_STRING, Value);
+ } else {
+ //
+ // If there is no blocks size, but there is the number of block, then we have a mismatched pair
+ // and should return an error.
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);
+ if (!EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "both %s and %s must be specified.", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING);
+ return EFI_ABORTED;
+ } else {
+ //
+ // We are done
+ //
+ break;
+ }
+ }
+
+ //
+ // Read blocks number
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Update the number of blocks
+ //
+ Status = AsciiStringToUint64 (Value, FALSE, &Value64);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_NUM_BLOCKS_STRING, Value);
+ return EFI_ABORTED;
+ }
+
+ FvInfo->FvBlocks[Index].NumBlocks = (UINT32) Value64;
+ DebugMsg (NULL, 0, 9, "FV Block Number", "%s = %s", EFI_NUM_BLOCKS_STRING, Value);
+ }
+ }
+ }
+
+ if (Index == 0) {
+ Error (NULL, 0, 2001, "Missing required argument", "block size.");
+ return EFI_ABORTED;
+ }
+
+ //
+ // Read files
+ //
+ Number = 0;
+ for (Number = 0; Number < MAX_NUMBER_OF_FILES_IN_FV; Number ++) {
+ if (FvInfo->FvFiles[Number][0] == '\0') {
+ break;
+ }
+ }
+
+ for (Index = 0; Number + Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {
+ //
+ // Read the FFS file list
+ //
+ Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Add the file
+ //
+ strcpy (FvInfo->FvFiles[Number + Index], Value);
+ DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index, Value);
+ } else {
+ break;
+ }
+ }
+
+ if ((Index + Number) == 0) {
+ Warning (NULL, 0, 0, "FV components are not specified.", NULL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+UpdateFfsFileState (
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+/*++
+
+Routine Description:
+
+ This function changes the FFS file attributes based on the erase polarity
+ of the FV. Update the reserved bits of State to EFI_FVB2_ERASE_POLARITY.
+
+Arguments:
+
+ FfsFile File header.
+ FvHeader FV header.
+
+Returns:
+
+ None
+
+--*/
+{
+ if (FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ FfsFile->State = (UINT8)~(FfsFile->State);
+ // FfsFile->State |= ~(UINT8) EFI_FILE_ALL_STATE_BITS;
+ }
+}
+
+EFI_STATUS
+ReadFfsAlignment (
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN OUT UINT32 *Alignment
+ )
+/*++
+
+Routine Description:
+
+ This function determines the alignment of the FFS input file from the file
+ attributes.
+
+Arguments:
+
+ FfsFile FFS file to parse
+ Alignment The minimum required alignment offset of the FFS file
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED An error occurred.
+
+--*/
+{
+ //
+ // Verify input parameters.
+ //
+ if (FfsFile == NULL || Alignment == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch ((FfsFile->Attributes >> 3) & 0x07) {
+
+ case 0:
+ //
+ // 1 byte alignment
+ //if bit 1 have set, 128K byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 17;
+ } else {
+ *Alignment = 0;
+ }
+ break;
+
+ case 1:
+ //
+ // 16 byte alignment
+ //if bit 1 have set, 256K byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 18;
+ } else {
+ *Alignment = 4;
+ }
+ break;
+
+ case 2:
+ //
+ // 128 byte alignment
+ //if bit 1 have set, 512K byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 19;
+ } else {
+ *Alignment = 7;
+ }
+ break;
+
+ case 3:
+ //
+ // 512 byte alignment
+ //if bit 1 have set, 1M byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 20;
+ } else {
+ *Alignment = 9;
+ }
+ break;
+
+ case 4:
+ //
+ // 1K byte alignment
+ //if bit 1 have set, 2M byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 21;
+ } else {
+ *Alignment = 10;
+ }
+ break;
+
+ case 5:
+ //
+ // 4K byte alignment
+ //if bit 1 have set, 4M byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 22;
+ } else {
+ *Alignment = 12;
+ }
+ break;
+
+ case 6:
+ //
+ // 32K byte alignment
+ //if bit 1 have set , 8M byte alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 23;
+ } else {
+ *Alignment = 15;
+ }
+ break;
+
+ case 7:
+ //
+ // 64K byte alignment
+ //if bit 1 have set, 16M alignment
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 24;
+ } else {
+ *Alignment = 16;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AddPadFile (
+ IN OUT MEMORY_FILE *FvImage,
+ IN UINT32 DataAlignment,
+ IN VOID *FvEnd,
+ IN EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHeader,
+ IN UINT32 NextFfsSize
+ )
+/*++
+
+Routine Description:
+
+ This function adds a pad file to the FV image if it required to align the
+ data of the next file.
+
+Arguments:
+
+ FvImage The memory image of the FV to add it to.
+ The current offset must be valid.
+ DataAlignment The data alignment of the next FFS file.
+ FvEnd End of the empty data in FvImage.
+ ExtHeader PI FvExtHeader Optional
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_OUT_OF_RESOURCES Insufficient resources exist in the FV to complete
+ the pad file add.
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *PadFile;
+ UINTN PadFileSize;
+ UINT32 NextFfsHeaderSize;
+ UINT32 CurFfsHeaderSize;
+ UINT32 Index;
+
+ Index = 0;
+ CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
+ //
+ // Verify input parameters.
+ //
+ if (FvImage == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate the pad file size
+ //
+
+ //
+ // Append extension header size
+ //
+ if (ExtHeader != NULL) {
+ PadFileSize = ExtHeader->ExtHeaderSize;
+ if (PadFileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
+ CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
+ }
+ PadFileSize += CurFfsHeaderSize;
+ } else {
+ NextFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
+ if (NextFfsSize >= MAX_FFS_SIZE) {
+ NextFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
+ }
+ //
+ // Check if a pad file is necessary
+ //
+ if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + NextFfsHeaderSize) % DataAlignment == 0) {
+ return EFI_SUCCESS;
+ }
+ PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER) + NextFfsHeaderSize;
+ //
+ // Add whatever it takes to get to the next aligned address
+ //
+ while ((PadFileSize % DataAlignment) != 0) {
+ PadFileSize++;
+ }
+ //
+ // Subtract the next file header size
+ //
+ PadFileSize -= NextFfsHeaderSize;
+ //
+ // Subtract the starting offset to get size
+ //
+ PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;
+ }
+
+ //
+ // Verify that we have enough space for the file header
+ //
+ if (((UINTN) FvImage->CurrentFilePointer + PadFileSize) > (UINTN) FvEnd) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Write pad file header
+ //
+ PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;
+
+ //
+ // Write PadFile FFS header with PadType, don't need to set PAD file guid in its header.
+ //
+ PadFile->Type = EFI_FV_FILETYPE_FFS_PAD;
+ PadFile->Attributes = 0;
+
+ //
+ // Write pad file size (calculated size minus next file header size)
+ //
+ if (PadFileSize >= MAX_FFS_SIZE) {
+ memset(PadFile->Size, 0, sizeof(UINT8) * 3);
+ ((EFI_FFS_FILE_HEADER2 *)PadFile)->ExtendedSize = PadFileSize;
+ PadFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
+ } else {
+ PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF);
+ PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF);
+ PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF);
+ }
+
+ //
+ // Fill in checksums and state, they must be 0 for checksumming.
+ //
+ PadFile->IntegrityCheck.Checksum.Header = 0;
+ PadFile->IntegrityCheck.Checksum.File = 0;
+ PadFile->State = 0;
+ PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, CurFfsHeaderSize);
+ PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
+
+ PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
+ UpdateFfsFileState (
+ (EFI_FFS_FILE_HEADER *) PadFile,
+ (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
+ );
+
+ //
+ // Update the current FV pointer
+ //
+ FvImage->CurrentFilePointer += PadFileSize;
+
+ if (ExtHeader != NULL) {
+ //
+ // Copy Fv Extension Header and Set Fv Extension header offset
+ //
+ if (ExtHeader->ExtHeaderSize > sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER)) {
+ for (Index = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER); Index < ExtHeader->ExtHeaderSize;) {
+ if (((EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtHeader + Index))-> ExtEntryType == EFI_FV_EXT_TYPE_USED_SIZE_TYPE) {
+ if (VtfFileFlag) {
+ ((EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)((UINT8 *)ExtHeader + Index))->UsedSize = mFvTotalSize;
+ } else {
+ ((EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)((UINT8 *)ExtHeader + Index))->UsedSize = mFvTakenSize;
+ }
+ break;
+ }
+ Index += ((EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtHeader + Index))-> ExtEntrySize;
+ }
+ }
+ memcpy ((UINT8 *)PadFile + CurFfsHeaderSize, ExtHeader, ExtHeader->ExtHeaderSize);
+ ((EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage)->ExtHeaderOffset = (UINT16) ((UINTN) ((UINT8 *)PadFile + CurFfsHeaderSize) - (UINTN) FvImage->FileImage);
+ //
+ // Make next file start at QWord Boundary
+ //
+ while (((UINTN) FvImage->CurrentFilePointer & (EFI_FFS_FILE_HEADER_ALIGNMENT - 1)) != 0) {
+ FvImage->CurrentFilePointer++;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsVtfFile (
+ IN EFI_FFS_FILE_HEADER *FileBuffer
+ )
+/*++
+
+Routine Description:
+
+ This function checks the header to validate if it is a VTF file
+
+Arguments:
+
+ FileBuffer Buffer in which content of a file has been read.
+
+Returns:
+
+ TRUE If this is a VTF file
+ FALSE If this is not a VTF file
+
+--*/
+{
+ if (!memcmp (&FileBuffer->Name, &mEfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID))) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+EFI_STATUS
+WriteMapFile (
+ IN OUT FILE *FvMapFile,
+ IN CHAR8 *FileName,
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext
+ )
+/*++
+
+Routine Description:
+
+ This function gets the basic debug information (entrypoint, baseaddress, .text, .data section base address)
+ from PE/COFF image and abstracts Pe Map file information and add them into FvMap file for Debug.
+
+Arguments:
+
+ FvMapFile A pointer to FvMap File
+ FileName Ffs File PathName
+ FfsFile A pointer to Ffs file image.
+ ImageBaseAddress PeImage Base Address.
+ pImageContext Image Context Information.
+
+Returns:
+
+ EFI_SUCCESS Added required map information.
+
+--*/
+{
+ CHAR8 PeMapFileName [MAX_LONG_FILE_PATH];
+ CHAR8 *Cptr, *Cptr2;
+ CHAR8 FileGuidName [MAX_LINE_LEN];
+ FILE *PeMapFile;
+ CHAR8 Line [MAX_LINE_LEN];
+ CHAR8 KeyWord [MAX_LINE_LEN];
+ CHAR8 KeyWord2 [MAX_LINE_LEN];
+ CHAR8 FunctionName [MAX_LINE_LEN];
+ EFI_PHYSICAL_ADDRESS FunctionAddress;
+ UINT32 FunctionType;
+ CHAR8 FunctionTypeName [MAX_LINE_LEN];
+ UINT32 Index;
+ UINT32 AddressOfEntryPoint;
+ UINT32 Offset;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_TE_IMAGE_HEADER *TEImageHeader;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ long long TempLongAddress;
+ UINT32 TextVirtualAddress;
+ UINT32 DataVirtualAddress;
+ EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress;
+ BOOLEAN IsUseClang;
+
+ //
+ // Init local variable
+ //
+ FunctionType = 0;
+ //
+ // Print FileGuid to string buffer.
+ //
+ PrintGuidToBuffer (&FfsFile->Name, (UINT8 *)FileGuidName, MAX_LINE_LEN, TRUE);
+
+ //
+ // Construct Map file Name
+ //
+ if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
+ return EFI_ABORTED;
+ }
+ strncpy (PeMapFileName, FileName, MAX_LONG_FILE_PATH - 1);
+ PeMapFileName[MAX_LONG_FILE_PATH - 1] = 0;
+
+ //
+ // Change '\\' to '/', unified path format.
+ //
+ Cptr = PeMapFileName;
+ while (*Cptr != '\0') {
+ if (*Cptr == '\\') {
+ *Cptr = FILE_SEP_CHAR;
+ }
+ Cptr ++;
+ }
+
+ //
+ // Get Map file
+ //
+ Cptr = PeMapFileName + strlen (PeMapFileName);
+ while ((*Cptr != '.') && (Cptr >= PeMapFileName)) {
+ Cptr --;
+ }
+ if (Cptr < PeMapFileName) {
+ return EFI_NOT_FOUND;
+ } else {
+ *(Cptr + 1) = 'm';
+ *(Cptr + 2) = 'a';
+ *(Cptr + 3) = 'p';
+ *(Cptr + 4) = '\0';
+ }
+
+ //
+ // Get module Name
+ //
+ Cptr2 = Cptr;
+ while ((*Cptr != FILE_SEP_CHAR) && (Cptr >= PeMapFileName)) {
+ Cptr --;
+ }
+ *Cptr2 = '\0';
+ if (strlen (Cptr + 1) >= MAX_LINE_LEN) {
+ return EFI_ABORTED;
+ }
+ strncpy (KeyWord, Cptr + 1, MAX_LINE_LEN - 1);
+ KeyWord[MAX_LINE_LEN - 1] = 0;
+ *Cptr2 = '.';
+
+ //
+ // AddressOfEntryPoint and Offset in Image
+ //
+ if (!pImageContext->IsTeImage) {
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset);
+ AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
+ Offset = 0;
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINT8 *) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+ Index = ImgHdr->Pe32.FileHeader.NumberOfSections;
+ } else {
+ TEImageHeader = (EFI_TE_IMAGE_HEADER *) pImageContext->Handle;
+ AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint;
+ Offset = TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
+ Index = TEImageHeader->NumberOfSections;
+ }
+
+ //
+ // module information output
+ //
+ if (ImageBaseAddress == 0) {
+ fprintf (FvMapFile, "%s (dummy) (", KeyWord);
+ fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress);
+ } else {
+ fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord);
+ fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset));
+ }
+
+ fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
+ if (!pImageContext->IsTeImage) {
+ fprintf (FvMapFile, "Type=PE");
+ } else {
+ fprintf (FvMapFile, "Type=TE");
+ }
+ fprintf (FvMapFile, ")\n");
+
+ fprintf (FvMapFile, "(GUID=%s", FileGuidName);
+ TextVirtualAddress = 0;
+ DataVirtualAddress = 0;
+ for (; Index > 0; Index --, SectionHeader ++) {
+ if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {
+ TextVirtualAddress = SectionHeader->VirtualAddress;
+ } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".data") == 0) {
+ DataVirtualAddress = SectionHeader->VirtualAddress;
+ } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".sdata") == 0) {
+ DataVirtualAddress = SectionHeader->VirtualAddress;
+ }
+ }
+ fprintf (FvMapFile, " .textbaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + TextVirtualAddress));
+ fprintf (FvMapFile, " .databaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + DataVirtualAddress));
+ fprintf (FvMapFile, ")\n\n");
+
+ //
+ // Open PeMapFile
+ //
+ PeMapFile = fopen (LongFilePath (PeMapFileName), "r");
+ if (PeMapFile == NULL) {
+ // fprintf (stdout, "can't open %s file to reading\n", PeMapFileName);
+ return EFI_ABORTED;
+ }
+ VerboseMsg ("The map file is %s", PeMapFileName);
+
+ //
+ // Output Functions information into Fv Map file
+ //
+ LinkTimeBaseAddress = 0;
+ IsUseClang = FALSE;
+ while (fgets (Line, MAX_LINE_LEN, PeMapFile) != NULL) {
+ //
+ // Skip blank line
+ //
+ if (Line[0] == 0x0a) {
+ FunctionType = 0;
+ continue;
+ }
+ //
+ // By Address and Static keyword
+ //
+ if (FunctionType == 0) {
+ sscanf (Line, "%s", KeyWord);
+ if (stricmp (KeyWord, "Address") == 0) {
+ sscanf (Line, "%s %s", KeyWord, KeyWord2);
+ if (stricmp (KeyWord2, "Size") == 0) {
+ IsUseClang = TRUE;
+ FunctionType = 1;
+ continue;
+ }
+ //
+ // function list
+ //
+ FunctionType = 1;
+ fgets (Line, MAX_LINE_LEN, PeMapFile);
+ } else if (stricmp (KeyWord, "Static") == 0) {
+ //
+ // static function list
+ //
+ FunctionType = 2;
+ fgets (Line, MAX_LINE_LEN, PeMapFile);
+ } else if (stricmp (KeyWord, "Preferred") ==0) {
+ sscanf (Line + strlen (" Preferred load address is"), "%llx", &TempLongAddress);
+ LinkTimeBaseAddress = (UINT64) TempLongAddress;
+ }
+ continue;
+ }
+ //
+ // Printf Function Information
+ //
+ if (FunctionType == 1) {
+ if (IsUseClang) {
+ sscanf (Line, "%llx %s %s %s", &TempLongAddress, KeyWord, KeyWord2, FunctionTypeName);
+ FunctionAddress = (UINT64) TempLongAddress;
+ if (FunctionTypeName [0] == '_' ) {
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
+ fprintf (FvMapFile, "%s\n", FunctionTypeName);
+ }
+ } else {
+ sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);
+ FunctionAddress = (UINT64) TempLongAddress;
+ if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
+ fprintf (FvMapFile, "%s\n", FunctionName);
+ }
+ }
+ } else if (FunctionType == 2) {
+ sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);
+ FunctionAddress = (UINT64) TempLongAddress;
+ if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
+ fprintf (FvMapFile, "%s\n", FunctionName);
+ }
+ }
+ }
+ //
+ // Close PeMap file
+ //
+ fprintf (FvMapFile, "\n\n");
+ fclose (PeMapFile);
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+BOOLEAN
+AdjustInternalFfsPadding (
+ IN OUT EFI_FFS_FILE_HEADER *FfsFile,
+ IN OUT MEMORY_FILE *FvImage,
+ IN UINTN Alignment,
+ IN OUT UINTN *FileSize
+ )
+/*++
+
+Routine Description:
+
+ This function looks for a dedicated alignment padding section in the FFS, and
+ shrinks it to the size required to line up subsequent sections correctly.
+
+Arguments:
+
+ FfsFile A pointer to Ffs file image.
+ FvImage The memory image of the FV to adjust it to.
+ Alignment Current file alignment
+ FileSize Reference to a variable holding the size of the FFS file
+
+Returns:
+
+ TRUE Padding section was found and updated successfully
+ FALSE Otherwise
+
+--*/
+{
+ EFI_FILE_SECTION_POINTER PadSection;
+ UINT8 *Remainder;
+ EFI_STATUS Status;
+ UINT32 FfsHeaderLength;
+ UINT32 FfsFileLength;
+ UINT32 PadSize;
+ UINTN Misalignment;
+ EFI_FFS_INTEGRITY_CHECK *IntegrityCheck;
+
+ //
+ // Figure out the misalignment: all FFS sections are aligned relative to the
+ // start of the FFS payload, so use that as the base of the misalignment
+ // computation.
+ //
+ FfsHeaderLength = GetFfsHeaderLength(FfsFile);
+ Misalignment = (UINTN) FvImage->CurrentFilePointer -
+ (UINTN) FvImage->FileImage + FfsHeaderLength;
+ Misalignment &= Alignment - 1;
+ if (Misalignment == 0) {
+ // Nothing to do, return success
+ return TRUE;
+ }
+
+ //
+ // We only apply this optimization to FFS files with the FIXED attribute set,
+ // since the FFS will not be loadable at arbitrary offsets anymore after
+ // we adjust the size of the padding section.
+ //
+ if ((FfsFile->Attributes & FFS_ATTRIB_FIXED) == 0) {
+ return FALSE;
+ }
+
+ //
+ // Look for a dedicated padding section that we can adjust to compensate
+ // for the misalignment. If such a padding section exists, it precedes all
+ // sections with alignment requirements, and so the adjustment will correct
+ // all of them.
+ //
+ Status = GetSectionByType (FfsFile, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 1,
+ &PadSection);
+ if (EFI_ERROR (Status) ||
+ CompareGuid (&PadSection.FreeformSubtypeSection->SubTypeGuid,
+ &mEfiFfsSectionAlignmentPaddingGuid) != 0) {
+ return FALSE;
+ }
+
+ //
+ // Find out if the size of the padding section is sufficient to compensate
+ // for the misalignment.
+ //
+ PadSize = GetSectionFileLength (PadSection.CommonHeader);
+ if (Misalignment > PadSize - sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION)) {
+ return FALSE;
+ }
+
+ //
+ // Move the remainder of the FFS file towards the front, and adjust the
+ // file size output parameter.
+ //
+ Remainder = (UINT8 *) PadSection.CommonHeader + PadSize;
+ memmove (Remainder - Misalignment, Remainder,
+ *FileSize - (UINTN) (Remainder - (UINTN) FfsFile));
+ *FileSize -= Misalignment;
+
+ //
+ // Update the padding section's length with the new values. Note that the
+ // padding is always < 64 KB, so we can ignore EFI_COMMON_SECTION_HEADER2
+ // ExtendedSize.
+ //
+ PadSize -= Misalignment;
+ PadSection.CommonHeader->Size[0] = (UINT8) (PadSize & 0xff);
+ PadSection.CommonHeader->Size[1] = (UINT8) ((PadSize & 0xff00) >> 8);
+ PadSection.CommonHeader->Size[2] = (UINT8) ((PadSize & 0xff0000) >> 16);
+
+ //
+ // Update the FFS header with the new overall length
+ //
+ FfsFileLength = GetFfsFileLength (FfsFile) - Misalignment;
+ if (FfsHeaderLength > sizeof(EFI_FFS_FILE_HEADER)) {
+ ((EFI_FFS_FILE_HEADER2 *)FfsFile)->ExtendedSize = FfsFileLength;
+ } else {
+ FfsFile->Size[0] = (UINT8) (FfsFileLength & 0x000000FF);
+ FfsFile->Size[1] = (UINT8) ((FfsFileLength & 0x0000FF00) >> 8);
+ FfsFile->Size[2] = (UINT8) ((FfsFileLength & 0x00FF0000) >> 16);
+ }
+
+ //
+ // Clear the alignment bits: these have become meaningless now that we have
+ // adjusted the padding section.
+ //
+ FfsFile->Attributes &= ~(FFS_ATTRIB_DATA_ALIGNMENT | FFS_ATTRIB_DATA_ALIGNMENT2);
+
+ //
+ // Recalculate the FFS header checksum. Instead of setting Header and State
+ // both to zero, set Header to (UINT8)(-State) so State preserves its original
+ // value
+ //
+ IntegrityCheck = &FfsFile->IntegrityCheck;
+ IntegrityCheck->Checksum.Header = (UINT8) (0x100 - FfsFile->State);
+ IntegrityCheck->Checksum.File = 0;
+
+ IntegrityCheck->Checksum.Header = CalculateChecksum8 (
+ (UINT8 *) FfsFile, FfsHeaderLength);
+
+ if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
+ //
+ // Ffs header checksum = zero, so only need to calculate ffs body.
+ //
+ IntegrityCheck->Checksum.File = CalculateChecksum8 (
+ (UINT8 *) FfsFile + FfsHeaderLength,
+ FfsFileLength - FfsHeaderLength);
+ } else {
+ IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM;
+ }
+
+ return TRUE;
+}
+
+EFI_STATUS
+AddFile (
+ IN OUT MEMORY_FILE *FvImage,
+ IN FV_INFO *FvInfo,
+ IN UINTN Index,
+ IN OUT EFI_FFS_FILE_HEADER **VtfFileImage,
+ IN FILE *FvMapFile,
+ IN FILE *FvReportFile
+ )
+/*++
+
+Routine Description:
+
+ This function adds a file to the FV image. The file will pad to the
+ appropriate alignment if required.
+
+Arguments:
+
+ FvImage The memory image of the FV to add it to. The current offset
+ must be valid.
+ FvInfo Pointer to information about the FV.
+ Index The file in the FvInfo file list to add.
+ VtfFileImage A pointer to the VTF file within the FvImage. If this is equal
+ to the end of the FvImage then no VTF previously found.
+ FvMapFile Pointer to FvMap File
+ FvReportFile Pointer to FvReport File
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED An error occurred.
+ EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add.
+
+--*/
+{
+ FILE *NewFile;
+ UINTN FileSize;
+ UINT8 *FileBuffer;
+ UINTN NumBytesRead;
+ UINT32 CurrentFileAlignment;
+ EFI_STATUS Status;
+ UINTN Index1;
+ UINT8 FileGuidString[PRINTED_GUID_BUFFER_SIZE];
+
+ Index1 = 0;
+ //
+ // Verify input parameters.
+ //
+ if (FvImage == NULL || FvInfo == NULL || FvInfo->FvFiles[Index][0] == 0 || VtfFileImage == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Read the file to add
+ //
+ NewFile = fopen (LongFilePath (FvInfo->FvFiles[Index]), "rb");
+
+ if (NewFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", FvInfo->FvFiles[Index]);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Get the file size
+ //
+ FileSize = _filelength (fileno (NewFile));
+
+ //
+ // Read the file into a buffer
+ //
+ FileBuffer = malloc (FileSize);
+ if (FileBuffer == NULL) {
+ fclose (NewFile);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NumBytesRead = fread (FileBuffer, sizeof (UINT8), FileSize, NewFile);
+
+ //
+ // Done with the file, from this point on we will just use the buffer read.
+ //
+ fclose (NewFile);
+
+ //
+ // Verify read successful
+ //
+ if (NumBytesRead != sizeof (UINT8) * FileSize) {
+ free (FileBuffer);
+ Error (NULL, 0, 0004, "Error reading file", FvInfo->FvFiles[Index]);
+ return EFI_ABORTED;
+ }
+
+ //
+ // For None PI Ffs file, directly add them into FvImage.
+ //
+ if (!FvInfo->IsPiFvImage) {
+ memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);
+ if (FvInfo->SizeofFvFiles[Index] > FileSize) {
+ FvImage->CurrentFilePointer += FvInfo->SizeofFvFiles[Index];
+ } else {
+ FvImage->CurrentFilePointer += FileSize;
+ }
+ goto Done;
+ }
+
+ //
+ // Verify Ffs file
+ //
+ Status = VerifyFfsFile ((EFI_FFS_FILE_HEADER *)FileBuffer);
+ if (EFI_ERROR (Status)) {
+ free (FileBuffer);
+ Error (NULL, 0, 3000, "Invalid", "%s is not a valid FFS file.", FvInfo->FvFiles[Index]);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify space exists to add the file
+ //
+ if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) {
+ free (FileBuffer);
+ Error (NULL, 0, 4002, "Resource", "FV space is full, not enough room to add file %s.", FvInfo->FvFiles[Index]);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Verify the input file is the duplicated file in this Fv image
+ //
+ for (Index1 = 0; Index1 < Index; Index1 ++) {
+ if (CompareGuid ((EFI_GUID *) FileBuffer, &mFileGuidArray [Index1]) == 0) {
+ Error (NULL, 0, 2000, "Invalid parameter", "the %dth file and %uth file have the same file GUID.", (unsigned) Index1 + 1, (unsigned) Index + 1);
+ PrintGuid ((EFI_GUID *) FileBuffer);
+ free (FileBuffer);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ CopyMem (&mFileGuidArray [Index], FileBuffer, sizeof (EFI_GUID));
+
+ //
+ // Update the file state based on polarity of the FV.
+ //
+ UpdateFfsFileState (
+ (EFI_FFS_FILE_HEADER *) FileBuffer,
+ (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
+ );
+
+ //
+ // Check if alignment is required
+ //
+ ReadFfsAlignment ((EFI_FFS_FILE_HEADER *) FileBuffer, &CurrentFileAlignment);
+
+ //
+ // Find the largest alignment of all the FFS files in the FV
+ //
+ if (CurrentFileAlignment > MaxFfsAlignment) {
+ MaxFfsAlignment = CurrentFileAlignment;
+ }
+ //
+ // If we have a VTF file, add it at the top.
+ //
+ if (IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer)) {
+ if ((UINTN) *VtfFileImage == (UINTN) FvImage->Eof) {
+ //
+ // No previous VTF, add this one.
+ //
+ *VtfFileImage = (EFI_FFS_FILE_HEADER *) (UINTN) ((UINTN) FvImage->FileImage + FvInfo->Size - FileSize);
+ //
+ // Sanity check. The file MUST align appropriately
+ //
+ if (((UINTN) *VtfFileImage + GetFfsHeaderLength((EFI_FFS_FILE_HEADER *)FileBuffer) - (UINTN) FvImage->FileImage) % (1 << CurrentFileAlignment)) {
+ Error (NULL, 0, 3000, "Invalid", "VTF file cannot be aligned on a %u-byte boundary.", (unsigned) (1 << CurrentFileAlignment));
+ free (FileBuffer);
+ return EFI_ABORTED;
+ }
+ //
+ // Rebase the PE or TE image in FileBuffer of FFS file for XIP
+ // Rebase for the debug genfvmap tool
+ //
+ Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
+ return Status;
+ }
+ //
+ // copy VTF File
+ //
+ memcpy (*VtfFileImage, FileBuffer, FileSize);
+
+ PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE);
+ fprintf (FvReportFile, "0x%08X %s\n", (unsigned)(UINTN) (((UINT8 *)*VtfFileImage) - (UINTN)FvImage->FileImage), FileGuidString);
+
+ free (FileBuffer);
+ DebugMsg (NULL, 0, 9, "Add VTF FFS file in FV image", NULL);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Already found a VTF file.
+ //
+ Error (NULL, 0, 3000, "Invalid", "multiple VTF files are not permitted within a single FV.");
+ free (FileBuffer);
+ return EFI_ABORTED;
+ }
+ }
+
+ //
+ // Add pad file if necessary
+ //
+ if (!AdjustInternalFfsPadding ((EFI_FFS_FILE_HEADER *) FileBuffer, FvImage,
+ 1 << CurrentFileAlignment, &FileSize)) {
+ Status = AddPadFile (FvImage, 1 << CurrentFileAlignment, *VtfFileImage, NULL, FileSize);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 4002, "Resource", "FV space is full, could not add pad file for data alignment property.");
+ free (FileBuffer);
+ return EFI_ABORTED;
+ }
+ }
+ //
+ // Add file
+ //
+ if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) {
+ //
+ // Rebase the PE or TE image in FileBuffer of FFS file for XIP.
+ // Rebase Bs and Rt drivers for the debug genfvmap tool.
+ //
+ Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
+ return Status;
+ }
+ //
+ // Copy the file
+ //
+ memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);
+ PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE);
+ fprintf (FvReportFile, "0x%08X %s\n", (unsigned) (FvImage->CurrentFilePointer - FvImage->FileImage), FileGuidString);
+ FvImage->CurrentFilePointer += FileSize;
+ } else {
+ Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add file %s.", FvInfo->FvFiles[Index]);
+ free (FileBuffer);
+ return EFI_ABORTED;
+ }
+ //
+ // Make next file start at QWord Boundary
+ //
+ while (((UINTN) FvImage->CurrentFilePointer & (EFI_FFS_FILE_HEADER_ALIGNMENT - 1)) != 0) {
+ FvImage->CurrentFilePointer++;
+ }
+
+Done:
+ //
+ // Free allocated memory.
+ //
+ free (FileBuffer);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PadFvImage (
+ IN MEMORY_FILE *FvImage,
+ IN EFI_FFS_FILE_HEADER *VtfFileImage
+ )
+/*++
+
+Routine Description:
+
+ This function places a pad file between the last file in the FV and the VTF
+ file if the VTF file exists.
+
+Arguments:
+
+ FvImage Memory file for the FV memory image
+ VtfFileImage The address of the VTF file. If this is the end of the FV
+ image, no VTF exists and no pad file is needed.
+
+Returns:
+
+ EFI_SUCCESS Completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was NULL.
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *PadFile;
+ UINTN FileSize;
+ UINT32 FfsHeaderSize;
+
+ //
+ // If there is no VTF or the VTF naturally follows the previous file without a
+ // pad file, then there's nothing to do
+ //
+ if ((UINTN) VtfFileImage == (UINTN) FvImage->Eof || \
+ ((UINTN) VtfFileImage == (UINTN) FvImage->CurrentFilePointer)) {
+ return EFI_SUCCESS;
+ }
+
+ if ((UINTN) VtfFileImage < (UINTN) FvImage->CurrentFilePointer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Pad file starts at beginning of free space
+ //
+ PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;
+
+ //
+ // write PadFile FFS header with PadType, don't need to set PAD file guid in its header.
+ //
+ PadFile->Type = EFI_FV_FILETYPE_FFS_PAD;
+ PadFile->Attributes = 0;
+
+ //
+ // FileSize includes the EFI_FFS_FILE_HEADER
+ //
+ FileSize = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer;
+ if (FileSize >= MAX_FFS_SIZE) {
+ PadFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
+ memset(PadFile->Size, 0, sizeof(UINT8) * 3);
+ ((EFI_FFS_FILE_HEADER2 *)PadFile)->ExtendedSize = FileSize;
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
+ mIsLargeFfs = TRUE;
+ } else {
+ PadFile->Size[0] = (UINT8) (FileSize & 0x000000FF);
+ PadFile->Size[1] = (UINT8) ((FileSize & 0x0000FF00) >> 8);
+ PadFile->Size[2] = (UINT8) ((FileSize & 0x00FF0000) >> 16);
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER);
+ }
+
+ //
+ // Fill in checksums and state, must be zero during checksum calculation.
+ //
+ PadFile->IntegrityCheck.Checksum.Header = 0;
+ PadFile->IntegrityCheck.Checksum.File = 0;
+ PadFile->State = 0;
+ PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, FfsHeaderSize);
+ PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
+
+ PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
+
+ UpdateFfsFileState (
+ (EFI_FFS_FILE_HEADER *) PadFile,
+ (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
+ );
+ //
+ // Update the current FV pointer
+ //
+ FvImage->CurrentFilePointer = FvImage->Eof;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdateResetVector (
+ IN MEMORY_FILE *FvImage,
+ IN FV_INFO *FvInfo,
+ IN EFI_FFS_FILE_HEADER *VtfFile
+ )
+/*++
+
+Routine Description:
+
+ This parses the FV looking for the PEI core and then plugs the address into
+ the SALE_ENTRY point of the BSF/VTF for IPF and does BUGBUG TBD action to
+ complete an IA32 Bootstrap FV.
+
+Arguments:
+
+ FvImage Memory file for the FV memory image
+ FvInfo Information read from INF file.
+ VtfFile Pointer to the VTF file in the FV image.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND PEI Core file not found.
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *PeiCoreFile;
+ EFI_FFS_FILE_HEADER *SecCoreFile;
+ EFI_STATUS Status;
+ EFI_FILE_SECTION_POINTER Pe32Section;
+ UINT32 EntryPoint;
+ UINT32 BaseOfCode;
+ UINT16 MachineType;
+ EFI_PHYSICAL_ADDRESS PeiCorePhysicalAddress;
+ EFI_PHYSICAL_ADDRESS SecCorePhysicalAddress;
+ INT32 Ia32SecEntryOffset;
+ UINT32 *Ia32ResetAddressPtr;
+ UINT8 *BytePointer;
+ UINT8 *BytePointer2;
+ UINT16 *WordPointer;
+ UINT16 CheckSum;
+ UINT32 IpiVector;
+ UINTN Index;
+ EFI_FFS_FILE_STATE SavedState;
+ BOOLEAN Vtf0Detected;
+ UINT32 FfsHeaderSize;
+ UINT32 SecHeaderSize;
+
+ //
+ // Verify input parameters
+ //
+ if (FvImage == NULL || FvInfo == NULL || VtfFile == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Initialize FV library
+ //
+ InitializeFvLib (FvImage->FileImage, FvInfo->Size);
+
+ //
+ // Verify VTF file
+ //
+ Status = VerifyFfsFile (VtfFile);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (
+ (((UINTN)FvImage->Eof - (UINTN)FvImage->FileImage) >=
+ IA32_X64_VTF_SIGNATURE_OFFSET) &&
+ (*(UINT32 *)(VOID*)((UINTN) FvImage->Eof -
+ IA32_X64_VTF_SIGNATURE_OFFSET) ==
+ IA32_X64_VTF0_SIGNATURE)
+ ) {
+ Vtf0Detected = TRUE;
+ } else {
+ Vtf0Detected = FALSE;
+ }
+
+ //
+ // Find the Sec Core
+ //
+ Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile);
+ if (EFI_ERROR (Status) || SecCoreFile == NULL) {
+ if (Vtf0Detected) {
+ //
+ // If the SEC core file is not found, but the VTF-0 signature
+ // is found, we'll treat it as a VTF-0 'Volume Top File'.
+ // This means no modifications are required to the VTF.
+ //
+ return EFI_SUCCESS;
+ }
+
+ Error (NULL, 0, 3000, "Invalid", "could not find the SEC core file in the FV.");
+ return EFI_ABORTED;
+ }
+ //
+ // Sec Core found, now find PE32 section
+ //
+ Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section);
+ if (Status == EFI_NOT_FOUND) {
+ Status = GetSectionByType (SecCoreFile, EFI_SECTION_TE, 1, &Pe32Section);
+ }
+
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "could not find a PE32 section in the SEC core file.");
+ return EFI_ABORTED;
+ }
+
+ SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
+ Status = GetPe32Info (
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
+ &EntryPoint,
+ &BaseOfCode,
+ &MachineType
+ );
+
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the SEC core.");
+ return EFI_ABORTED;
+ }
+
+ if (
+ Vtf0Detected &&
+ (MachineType == EFI_IMAGE_MACHINE_IA32 ||
+ MachineType == EFI_IMAGE_MACHINE_X64)
+ ) {
+ //
+ // If the SEC core code is IA32 or X64 and the VTF-0 signature
+ // is found, we'll treat it as a VTF-0 'Volume Top File'.
+ // This means no modifications are required to the VTF.
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Physical address is FV base + offset of PE32 + offset of the entry point
+ //
+ SecCorePhysicalAddress = FvInfo->BaseAddress;
+ SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
+ SecCorePhysicalAddress += EntryPoint;
+ DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%llX", (unsigned long long) SecCorePhysicalAddress);
+
+ //
+ // Find the PEI Core
+ //
+ PeiCorePhysicalAddress = 0;
+ Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile);
+ if (!EFI_ERROR (Status) && (PeiCoreFile != NULL)) {
+ //
+ // PEI Core found, now find PE32 or TE section
+ //
+ Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section);
+ if (Status == EFI_NOT_FOUND) {
+ Status = GetSectionByType (PeiCoreFile, EFI_SECTION_TE, 1, &Pe32Section);
+ }
+
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "could not find either a PE32 or a TE section in PEI core file.");
+ return EFI_ABORTED;
+ }
+
+ SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
+ Status = GetPe32Info (
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
+ &EntryPoint,
+ &BaseOfCode,
+ &MachineType
+ );
+
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the PEI core.");
+ return EFI_ABORTED;
+ }
+ //
+ // Physical address is FV base + offset of PE32 + offset of the entry point
+ //
+ PeiCorePhysicalAddress = FvInfo->BaseAddress;
+ PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
+ PeiCorePhysicalAddress += EntryPoint;
+ DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);
+ }
+
+if (MachineType == EFI_IMAGE_MACHINE_IA32 || MachineType == EFI_IMAGE_MACHINE_X64) {
+ if (PeiCorePhysicalAddress != 0) {
+ //
+ // Get the location to update
+ //
+ Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - IA32_PEI_CORE_ENTRY_OFFSET);
+
+ //
+ // Write lower 32 bits of physical address for Pei Core entry
+ //
+ *Ia32ResetAddressPtr = (UINT32) PeiCorePhysicalAddress;
+ }
+ //
+ // Write SecCore Entry point relative address into the jmp instruction in reset vector.
+ //
+ Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - IA32_SEC_CORE_ENTRY_OFFSET);
+
+ Ia32SecEntryOffset = (INT32) (SecCorePhysicalAddress - (FV_IMAGES_TOP_ADDRESS - IA32_SEC_CORE_ENTRY_OFFSET + 2));
+ if (Ia32SecEntryOffset <= -65536) {
+ Error (NULL, 0, 3000, "Invalid", "The SEC EXE file size is too large, it must be less than 64K.");
+ return STATUS_ERROR;
+ }
+
+ *(UINT16 *) Ia32ResetAddressPtr = (UINT16) Ia32SecEntryOffset;
+
+ //
+ // Update the BFV base address
+ //
+ Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - 4);
+ *Ia32ResetAddressPtr = (UINT32) (FvInfo->BaseAddress);
+ DebugMsg (NULL, 0, 9, "update BFV base address in the top FV image", "BFV base address = 0x%llX.", (unsigned long long) FvInfo->BaseAddress);
+
+ //
+ // Update the Startup AP in the FVH header block ZeroVector region.
+ //
+ BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage);
+ if (FvInfo->Size <= 0x10000) {
+ BytePointer2 = m64kRecoveryStartupApDataArray;
+ } else if (FvInfo->Size <= 0x20000) {
+ BytePointer2 = m128kRecoveryStartupApDataArray;
+ } else {
+ BytePointer2 = m128kRecoveryStartupApDataArray;
+ //
+ // Find the position to place Ap reset vector, the offset
+ // between the position and the end of Fvrecovery.fv file
+ // should not exceed 128kB to prevent Ap reset vector from
+ // outside legacy E and F segment
+ //
+ Status = FindApResetVectorPosition (FvImage, &BytePointer);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "FV image does not have enough space to place AP reset vector. The FV image needs to reserve at least 4KB of unused space.");
+ return EFI_ABORTED;
+ }
+ }
+
+ for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY; Index++) {
+ BytePointer[Index] = BytePointer2[Index];
+ }
+ //
+ // Calculate the checksum
+ //
+ CheckSum = 0x0000;
+ WordPointer = (UINT16 *) (BytePointer);
+ for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY / 2; Index++) {
+ CheckSum = (UINT16) (CheckSum + ((UINT16) *WordPointer));
+ WordPointer++;
+ }
+ //
+ // Update the checksum field
+ //
+ WordPointer = (UINT16 *) (BytePointer + SIZEOF_STARTUP_DATA_ARRAY - 2);
+ *WordPointer = (UINT16) (0x10000 - (UINT32) CheckSum);
+
+ //
+ // IpiVector at the 4k aligned address in the top 2 blocks in the PEI FV.
+ //
+ IpiVector = (UINT32) (FV_IMAGES_TOP_ADDRESS - ((UINTN) FvImage->Eof - (UINTN) BytePointer));
+ DebugMsg (NULL, 0, 9, "Startup AP Vector address", "IpiVector at 0x%X", (unsigned) IpiVector);
+ if ((IpiVector & 0xFFF) != 0) {
+ Error (NULL, 0, 3000, "Invalid", "Startup AP Vector address are not 4K aligned, because the FV size is not 4K aligned");
+ return EFI_ABORTED;
+ }
+ IpiVector = IpiVector >> 12;
+ IpiVector = IpiVector & 0xFF;
+
+ //
+ // Write IPI Vector at Offset FvrecoveryFileSize - 8
+ //
+ Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - 8);
+ *Ia32ResetAddressPtr = IpiVector;
+ } else if (MachineType == EFI_IMAGE_MACHINE_ARMT) {
+ //
+ // Since the ARM reset vector is in the FV Header you really don't need a
+ // Volume Top File, but if you have one for some reason don't crash...
+ //
+ } else if (MachineType == EFI_IMAGE_MACHINE_AARCH64) {
+ //
+ // Since the AArch64 reset vector is in the FV Header you really don't need a
+ // Volume Top File, but if you have one for some reason don't crash...
+ //
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "machine type=0x%X in PEI core.", MachineType);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Now update file checksum
+ //
+ SavedState = VtfFile->State;
+ VtfFile->IntegrityCheck.Checksum.File = 0;
+ VtfFile->State = 0;
+ if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) {
+ FfsHeaderSize = GetFfsHeaderLength(VtfFile);
+ VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
+ (UINT8 *) ((UINT8 *)VtfFile + FfsHeaderSize),
+ GetFfsFileLength (VtfFile) - FfsHeaderSize
+ );
+ } else {
+ VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
+ }
+
+ VtfFile->State = SavedState;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FindCorePeSection(
+ IN VOID *FvImageBuffer,
+ IN UINT64 FvSize,
+ IN EFI_FV_FILETYPE FileType,
+ OUT EFI_FILE_SECTION_POINTER *Pe32Section
+ )
+/*++
+
+Routine Description:
+
+ Recursively searches the FV for the FFS file of specified type (typically
+ SEC or PEI core) and extracts the PE32 section for further processing.
+
+Arguments:
+
+ FvImageBuffer Buffer containing FV data
+ FvSize Size of the FV
+ FileType Type of FFS file to search for
+ Pe32Section PE32 section pointer when FFS file is found.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND Core file not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER *OrigFvHeader;
+ UINT32 OrigFvLength;
+ EFI_FFS_FILE_HEADER *CoreFfsFile;
+ UINTN FvImageFileCount;
+ EFI_FFS_FILE_HEADER *FvImageFile;
+ UINTN EncapFvSectionCount;
+ EFI_FILE_SECTION_POINTER EncapFvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *EncapsulatedFvHeader;
+
+ if (Pe32Section == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize FV library, saving previous values
+ //
+ OrigFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NULL;
+ GetFvHeader (&OrigFvHeader, &OrigFvLength);
+ InitializeFvLib(FvImageBuffer, (UINT32)FvSize);
+
+ //
+ // First see if we can obtain the file directly in outer FV
+ //
+ Status = GetFileByType(FileType, 1, &CoreFfsFile);
+ if (!EFI_ERROR(Status) && (CoreFfsFile != NULL) ) {
+
+ //
+ // Core found, now find PE32 or TE section
+ //
+ Status = GetSectionByType(CoreFfsFile, EFI_SECTION_PE32, 1, Pe32Section);
+ if (EFI_ERROR(Status)) {
+ Status = GetSectionByType(CoreFfsFile, EFI_SECTION_TE, 1, Pe32Section);
+ }
+
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "could not find a PE32 section in the core file.");
+ return EFI_ABORTED;
+ }
+
+ //
+ // Core PE/TE section, found, return
+ //
+ Status = EFI_SUCCESS;
+ goto EarlyExit;
+ }
+
+ //
+ // File was not found, look for FV Image file
+ //
+
+ // iterate through all FV image files in outer FV
+ for (FvImageFileCount = 1;; FvImageFileCount++) {
+
+ Status = GetFileByType(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, FvImageFileCount, &FvImageFile);
+
+ if (EFI_ERROR(Status) || (FvImageFile == NULL) ) {
+ // exit FV image file loop, no more found
+ break;
+ }
+
+ // Found an fv image file, look for an FV image section. The PI spec does not
+ // preclude multiple FV image sections so we loop accordingly.
+ for (EncapFvSectionCount = 1;; EncapFvSectionCount++) {
+
+ // Look for the next FV image section. The section search code will
+ // iterate into encapsulation sections. For example, it will iterate
+ // into an EFI_SECTION_GUID_DEFINED encapsulation section to find the
+ // EFI_SECTION_FIRMWARE_VOLUME_IMAGE sections contained therein.
+ Status = GetSectionByType(FvImageFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EncapFvSectionCount, &EncapFvSection);
+
+ if (EFI_ERROR(Status)) {
+ // exit section inner loop, no more found
+ break;
+ }
+
+ EncapsulatedFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)EncapFvSection.FVImageSection + GetSectionHeaderLength(EncapFvSection.FVImageSection));
+
+ // recurse to search the encapsulated FV for this core file type
+ Status = FindCorePeSection(EncapsulatedFvHeader, EncapsulatedFvHeader->FvLength, FileType, Pe32Section);
+
+ if (!EFI_ERROR(Status)) {
+ // we found the core in the capsulated image, success
+ goto EarlyExit;
+ }
+
+ } // end encapsulated fv image section loop
+ } // end fv image file loop
+
+ // core was not found
+ Status = EFI_NOT_FOUND;
+
+EarlyExit:
+
+ // restore FV lib values
+ if(OrigFvHeader != NULL) {
+ InitializeFvLib(OrigFvHeader, OrigFvLength);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+GetCoreMachineType(
+ IN EFI_FILE_SECTION_POINTER Pe32Section,
+ OUT UINT16 *CoreMachineType
+ )
+/*++
+
+Routine Description:
+
+ Returns the machine type of a P32 image, typically SEC or PEI core.
+
+Arguments:
+
+ Pe32Section PE32 section data
+ CoreMachineType The extracted machine type
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 EntryPoint;
+ UINT32 BaseOfCode;
+
+ if (CoreMachineType == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetPe32Info(
+ (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
+ &EntryPoint,
+ &BaseOfCode,
+ CoreMachineType
+ );
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "could not get the PE32 machine type for the core.");
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetCoreEntryPointAddress(
+ IN VOID *FvImageBuffer,
+ IN FV_INFO *FvInfo,
+ IN EFI_FILE_SECTION_POINTER Pe32Section,
+ OUT EFI_PHYSICAL_ADDRESS *CoreEntryAddress
+)
+/*++
+
+Routine Description:
+
+ Returns the physical address of the core (SEC or PEI) entry point.
+
+Arguments:
+
+ FvImageBuffer Pointer to buffer containing FV data
+ FvInfo Info for the parent FV
+ Pe32Section PE32 section data
+ CoreEntryAddress The extracted core entry physical address
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 EntryPoint;
+ UINT32 BaseOfCode;
+ UINT16 MachineType;
+ EFI_PHYSICAL_ADDRESS EntryPhysicalAddress;
+
+ if (CoreEntryAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetPe32Info(
+ (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
+ &EntryPoint,
+ &BaseOfCode,
+ &MachineType
+ );
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the core.");
+ return EFI_ABORTED;
+ }
+
+ //
+ // Physical address is FV base + offset of PE32 + offset of the entry point
+ //
+ EntryPhysicalAddress = FvInfo->BaseAddress;
+ EntryPhysicalAddress += (UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN)FvImageBuffer;
+ EntryPhysicalAddress += EntryPoint;
+
+ *CoreEntryAddress = EntryPhysicalAddress;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdateArmResetVectorIfNeeded (
+ IN MEMORY_FILE *FvImage,
+ IN FV_INFO *FvInfo
+ )
+/*++
+
+Routine Description:
+ This parses the FV looking for SEC and patches that address into the
+ beginning of the FV header.
+
+ For ARM32 the reset vector is at 0x00000000 or 0xFFFF0000.
+ For AArch64 the reset vector is at 0x00000000.
+
+ This would commonly map to the first entry in the ROM.
+ ARM32 Exceptions:
+ Reset +0
+ Undefined +4
+ SWI +8
+ Prefetch Abort +12
+ Data Abort +16
+ IRQ +20
+ FIQ +24
+
+ We support two schemes on ARM.
+ 1) Beginning of the FV is the reset vector
+ 2) Reset vector is data bytes FDF file and that code branches to reset vector
+ in the beginning of the FV (fixed size offset).
+
+ Need to have the jump for the reset vector at location zero.
+ We also need to store the address or PEI (if it exists).
+ We stub out a return from interrupt in case the debugger
+ is using SWI (not done for AArch64, not enough space in struct).
+ The optional entry to the common exception handler is
+ to support full featured exception handling from ROM and is currently
+ not support by this tool.
+
+Arguments:
+ FvImage Memory file for the FV memory image
+ FvInfo Information read from INF file.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND PEI Core file not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FILE_SECTION_POINTER SecPe32;
+ EFI_FILE_SECTION_POINTER PeiPe32;
+ BOOLEAN UpdateVectorSec = FALSE;
+ BOOLEAN UpdateVectorPei = FALSE;
+ UINT16 MachineType = 0;
+ EFI_PHYSICAL_ADDRESS SecCoreEntryAddress = 0;
+ UINT16 PeiMachineType = 0;
+ EFI_PHYSICAL_ADDRESS PeiCoreEntryAddress = 0;
+
+ //
+ // Verify input parameters
+ //
+ if (FvImage == NULL || FvInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Locate an SEC Core instance and if found extract the machine type and entry point address
+ //
+ Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
+ if (!EFI_ERROR(Status)) {
+
+ Status = GetCoreMachineType(SecPe32, &MachineType);
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
+ return EFI_ABORTED;
+ }
+
+ Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+ return EFI_ABORTED;
+ }
+
+ VerboseMsg("UpdateArmResetVectorIfNeeded found SEC core entry at 0x%llx", (unsigned long long)SecCoreEntryAddress);
+ UpdateVectorSec = TRUE;
+ }
+
+ //
+ // Locate a PEI Core instance and if found extract the machine type and entry point address
+ //
+ Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_PEI_CORE, &PeiPe32);
+ if (!EFI_ERROR(Status)) {
+
+ Status = GetCoreMachineType(PeiPe32, &PeiMachineType);
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for PEI Core.");
+ return EFI_ABORTED;
+ }
+
+ Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, PeiPe32, &PeiCoreEntryAddress);
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for PEI Core.");
+ return EFI_ABORTED;
+ }
+
+ VerboseMsg("UpdateArmResetVectorIfNeeded found PEI core entry at 0x%llx", (unsigned long long)PeiCoreEntryAddress);
+
+ // if we previously found an SEC Core make sure machine types match
+ if (UpdateVectorSec && (MachineType != PeiMachineType)) {
+ Error(NULL, 0, 3000, "Invalid", "SEC and PEI machine types do not match, can't update reset vector");
+ return EFI_ABORTED;
+ }
+ else {
+ MachineType = PeiMachineType;
+ }
+
+ UpdateVectorPei = TRUE;
+ }
+
+ if (!UpdateVectorSec && !UpdateVectorPei) {
+ return EFI_SUCCESS;
+ }
+
+ if (MachineType == EFI_IMAGE_MACHINE_ARMT) {
+ // ARM: Array of 4 UINT32s:
+ // 0 - is branch relative to SEC entry point
+ // 1 - PEI Entry Point
+ // 2 - movs pc,lr for a SWI handler
+ // 3 - Place holder for Common Exception Handler
+ UINT32 ResetVector[4];
+
+ memset(ResetVector, 0, sizeof (ResetVector));
+
+ // if we found an SEC core entry point then generate a branch instruction
+ // to it and populate a debugger SWI entry as well
+ if (UpdateVectorSec) {
+
+ VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC vector");
+
+ // B SecEntryPoint - signed_immed_24 part +/-32MB offset
+ // on ARM, the PC is always 8 ahead, so we're not really jumping from the base address, but from base address + 8
+ ResetVector[0] = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress - 8) >> 2;
+
+ if (ResetVector[0] > 0x00FFFFFF) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 32MB of the start of the FV");
+ return EFI_ABORTED;
+ }
+
+ // Add opcode for an unconditional branch with no link. i.e.: " B SecEntryPoint"
+ ResetVector[0] |= ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+
+ // SWI handler movs pc,lr. Just in case a debugger uses SWI
+ ResetVector[2] = 0xE1B0F07E;
+
+ // Place holder to support a common interrupt handler from ROM.
+ // Currently not supported. For this to be used the reset vector would not be in this FV
+ // and the exception vectors would be hard coded in the ROM and just through this address
+ // to find a common handler in the a module in the FV.
+ ResetVector[3] = 0;
+ }
+
+ // if a PEI core entry was found place its address in the vector area
+ if (UpdateVectorPei) {
+
+ VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM PEI address");
+
+ // Address of PEI Core, if we have one
+ ResetVector[1] = (UINT32)PeiCoreEntryAddress;
+ }
+
+ //
+ // Copy to the beginning of the FV
+ //
+ memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));
+
+ } else if (MachineType == EFI_IMAGE_MACHINE_AARCH64) {
+ // AArch64: Used as UINT64 ResetVector[2]
+ // 0 - is branch relative to SEC entry point
+ // 1 - PEI Entry Point
+ UINT64 ResetVector[2];
+
+ memset(ResetVector, 0, sizeof (ResetVector));
+
+ /* NOTE:
+ ARMT above has an entry in ResetVector[2] for SWI. The way we are using the ResetVector
+ array at the moment, for AArch64, does not allow us space for this as the header only
+ allows for a fixed amount of bytes at the start. If we are sure that UEFI will live
+ within the first 4GB of addressable RAM we could potentially adopt the same ResetVector
+ layout as above. But for the moment we replace the four 32bit vectors with two 64bit
+ vectors in the same area of the Image heasder. This allows UEFI to start from a 64bit
+ base.
+ */
+
+ // if we found an SEC core entry point then generate a branch instruction to it
+ if (UpdateVectorSec) {
+
+ VerboseMsg("UpdateArmResetVectorIfNeeded updating AArch64 SEC vector");
+
+ ResetVector[0] = (UINT64)(SecCoreEntryAddress - FvInfo->BaseAddress) >> 2;
+
+ // B SecEntryPoint - signed_immed_26 part +/-128MB offset
+ if (ResetVector[0] > 0x03FFFFFF) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 128MB of the start of the FV");
+ return EFI_ABORTED;
+ }
+ // Add opcode for an unconditional branch with no link. i.e.: " B SecEntryPoint"
+ ResetVector[0] |= ARM64_UNCONDITIONAL_JUMP_INSTRUCTION;
+ }
+
+ // if a PEI core entry was found place its address in the vector area
+ if (UpdateVectorPei) {
+
+ VerboseMsg("UpdateArmResetVectorIfNeeded updating AArch64 PEI address");
+
+ // Address of PEI Core, if we have one
+ ResetVector[1] = (UINT64)PeiCoreEntryAddress;
+ }
+
+ //
+ // Copy to the beginning of the FV
+ //
+ memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));
+
+ } else {
+ Error(NULL, 0, 3000, "Invalid", "Unknown machine type");
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdateRiscvResetVectorIfNeeded (
+ MEMORY_FILE *FvImage,
+ FV_INFO *FvInfo
+ )
+/*++
+
+Routine Description:
+ This parses the FV looking for SEC and patches that address into the
+ beginning of the FV header.
+
+ For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h
+
+Arguments:
+ FvImage Memory file for the FV memory image/
+ FvInfo Information read from INF file.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND PEI Core file not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT16 MachineType;
+ EFI_FILE_SECTION_POINTER SecPe32;
+ EFI_PHYSICAL_ADDRESS SecCoreEntryAddress;
+
+ UINT32 bSecCore;
+ UINT32 tmp;
+
+
+ //
+ // Verify input parameters
+ //
+ if (FvImage == NULL || FvInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Initialize FV library
+ //
+ InitializeFvLib (FvImage->FileImage, FvInfo->Size);
+
+ //
+ // Find the Sec Core
+ //
+ Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
+ if(EFI_ERROR(Status)) {
+ printf("skip because Secutiry Core not found\n");
+ return EFI_SUCCESS;
+ }
+
+ DebugMsg (NULL, 0, 9, "Update SEC core in FV Header", NULL);
+
+ Status = GetCoreMachineType(SecPe32, &MachineType);
+ if(EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core.");
+ return EFI_ABORTED;
+ }
+
+ if (MachineType != EFI_IMAGE_MACHINE_RISCV64) {
+ Error(NULL, 0, 3000, "Invalid", "Could not update SEC core because Machine type is not RiscV.");
+ return EFI_ABORTED;
+ }
+
+ Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
+ if(EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+ return EFI_ABORTED;
+ }
+
+ VerboseMsg("SecCore entry point Address = 0x%llX", (unsigned long long) SecCoreEntryAddress);
+ VerboseMsg("BaseAddress = 0x%llX", (unsigned long long) FvInfo->BaseAddress);
+ bSecCore = (UINT32)(SecCoreEntryAddress - FvInfo->BaseAddress);
+ VerboseMsg("offset = 0x%llX", bSecCore);
+
+ if(bSecCore > 0x0fffff) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 1MB of start of the FV");
+ return EFI_ABORTED;
+ }
+
+ tmp = bSecCore;
+ bSecCore = 0;
+ //J-type
+ bSecCore = (tmp&0x100000)<<11; //imm[20] at bit[31]
+ bSecCore |= (tmp&0x0007FE)<<20; //imm[10:1] at bit[30:21]
+ bSecCore |= (tmp&0x000800)<<9; //imm[11] at bit[20]
+ bSecCore |= (tmp&0x0FF000); //imm[19:12] at bit[19:12]
+ bSecCore |= 0x6F; //JAL opcode
+
+ memcpy(FvImage->FileImage, &bSecCore, sizeof(bSecCore));
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetPe32Info (
+ IN UINT8 *Pe32,
+ OUT UINT32 *EntryPoint,
+ OUT UINT32 *BaseOfCode,
+ OUT UINT16 *MachineType
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the PE32 entry point offset and machine type from PE image or TeImage.
+ See EfiImage.h for machine types. The entry point offset is from the beginning
+ of the PE32 buffer passed in.
+
+Arguments:
+
+ Pe32 Beginning of the PE32.
+ EntryPoint Offset from the beginning of the PE32 to the image entry point.
+ BaseOfCode Base address of code.
+ MachineType Magic number for the machine type.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_UNSUPPORTED The operation is unsupported.
+
+--*/
+{
+ EFI_IMAGE_DOS_HEADER *DosHeader;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_TE_IMAGE_HEADER *TeHeader;
+
+ //
+ // Verify input parameters
+ //
+ if (Pe32 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // First check whether it is one TE Image.
+ //
+ TeHeader = (EFI_TE_IMAGE_HEADER *) Pe32;
+ if (TeHeader->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ //
+ // By TeImage Header to get output
+ //
+ *EntryPoint = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize;
+ *BaseOfCode = TeHeader->BaseOfCode + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize;
+ *MachineType = TeHeader->Machine;
+ } else {
+
+ //
+ // Then check whether
+ // First is the DOS header
+ //
+ DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32;
+
+ //
+ // Verify DOS header is expected
+ //
+ if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic);
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Immediately following is the NT header.
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew);
+
+ //
+ // Verify NT header is expected
+ //
+ if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature);
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get output
+ //
+ *EntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
+ *BaseOfCode = ImgHdr->Pe32.OptionalHeader.BaseOfCode;
+ *MachineType = ImgHdr->Pe32.FileHeader.Machine;
+ }
+
+ //
+ // Verify machine type is supported
+ //
+ if ((*MachineType != EFI_IMAGE_MACHINE_IA32) && (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) &&
+ (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&
+ (*MachineType != EFI_IMAGE_MACHINE_RISCV64)) {
+ Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GenerateFvImage (
+ IN CHAR8 *InfFileImage,
+ IN UINTN InfFileSize,
+ IN CHAR8 *FvFileName,
+ IN CHAR8 *MapFileName
+ )
+/*++
+
+Routine Description:
+
+ This is the main function which will be called from application.
+
+Arguments:
+
+ InfFileImage Buffer containing the INF file contents.
+ InfFileSize Size of the contents of the InfFileImage buffer.
+ FvFileName Requested name for the FV file.
+ MapFileName Fv map file to log fv driver information.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_OUT_OF_RESOURCES Could not allocate required resources.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ MEMORY_FILE InfMemoryFile;
+ MEMORY_FILE FvImageMemoryFile;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FFS_FILE_HEADER *VtfFileImage;
+ UINT8 *FvBufferHeader; // to make sure fvimage header 8 type alignment.
+ UINT8 *FvImage;
+ UINTN FvImageSize;
+ FILE *FvFile;
+ CHAR8 *FvMapName;
+ FILE *FvMapFile;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
+ FILE *FvExtHeaderFile;
+ UINTN FileSize;
+ CHAR8 *FvReportName;
+ FILE *FvReportFile;
+
+ FvBufferHeader = NULL;
+ FvFile = NULL;
+ FvMapName = NULL;
+ FvMapFile = NULL;
+ FvReportName = NULL;
+ FvReportFile = NULL;
+
+ if (InfFileImage != NULL) {
+ //
+ // Initialize file structures
+ //
+ InfMemoryFile.FileImage = InfFileImage;
+ InfMemoryFile.CurrentFilePointer = InfFileImage;
+ InfMemoryFile.Eof = InfFileImage + InfFileSize;
+
+ //
+ // Parse the FV inf file for header information
+ //
+ Status = ParseFvInf (&InfMemoryFile, &mFvDataInfo);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "Error parsing file", "the input FV INF file.");
+ return Status;
+ }
+ }
+
+ //
+ // Update the file name return values
+ //
+ if (FvFileName == NULL && mFvDataInfo.FvName[0] != '\0') {
+ FvFileName = mFvDataInfo.FvName;
+ }
+
+ if (FvFileName == NULL) {
+ Error (NULL, 0, 1001, "Missing option", "Output file name");
+ return EFI_ABORTED;
+ }
+
+ if (mFvDataInfo.FvBlocks[0].Length == 0) {
+ Error (NULL, 0, 1001, "Missing required argument", "Block Size");
+ return EFI_ABORTED;
+ }
+
+ //
+ // Debug message Fv File System Guid
+ //
+ if (mFvDataInfo.FvFileSystemGuidSet) {
+ DebugMsg (NULL, 0, 9, "FV File System Guid", "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ (unsigned) mFvDataInfo.FvFileSystemGuid.Data1,
+ mFvDataInfo.FvFileSystemGuid.Data2,
+ mFvDataInfo.FvFileSystemGuid.Data3,
+ mFvDataInfo.FvFileSystemGuid.Data4[0],
+ mFvDataInfo.FvFileSystemGuid.Data4[1],
+ mFvDataInfo.FvFileSystemGuid.Data4[2],
+ mFvDataInfo.FvFileSystemGuid.Data4[3],
+ mFvDataInfo.FvFileSystemGuid.Data4[4],
+ mFvDataInfo.FvFileSystemGuid.Data4[5],
+ mFvDataInfo.FvFileSystemGuid.Data4[6],
+ mFvDataInfo.FvFileSystemGuid.Data4[7]);
+ }
+
+ //
+ // Add PI FV extension header
+ //
+ FvExtHeader = NULL;
+ FvExtHeaderFile = NULL;
+ if (mFvDataInfo.FvExtHeaderFile[0] != 0) {
+ //
+ // Open the FV Extension Header file
+ //
+ FvExtHeaderFile = fopen (LongFilePath (mFvDataInfo.FvExtHeaderFile), "rb");
+ if (FvExtHeaderFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mFvDataInfo.FvExtHeaderFile);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Get the file size
+ //
+ FileSize = _filelength (fileno (FvExtHeaderFile));
+
+ //
+ // Allocate a buffer for the FV Extension Header
+ //
+ FvExtHeader = malloc(FileSize);
+ if (FvExtHeader == NULL) {
+ fclose (FvExtHeaderFile);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Read the FV Extension Header
+ //
+ fread (FvExtHeader, sizeof (UINT8), FileSize, FvExtHeaderFile);
+ fclose (FvExtHeaderFile);
+
+ //
+ // See if there is an override for the FV Name GUID
+ //
+ if (mFvDataInfo.FvNameGuidSet) {
+ memcpy (&FvExtHeader->FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));
+ }
+ memcpy (&mFvDataInfo.FvNameGuid, &FvExtHeader->FvName, sizeof (EFI_GUID));
+ mFvDataInfo.FvNameGuidSet = TRUE;
+ } else if (mFvDataInfo.FvNameGuidSet) {
+ //
+ // Allocate a buffer for the FV Extension Header
+ //
+ FvExtHeader = malloc(sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER));
+ if (FvExtHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memcpy (&FvExtHeader->FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));
+ FvExtHeader->ExtHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);
+ }
+
+ //
+ // Debug message Fv Name Guid
+ //
+ if (mFvDataInfo.FvNameGuidSet) {
+ DebugMsg (NULL, 0, 9, "FV Name Guid", "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ (unsigned) mFvDataInfo.FvNameGuid.Data1,
+ mFvDataInfo.FvNameGuid.Data2,
+ mFvDataInfo.FvNameGuid.Data3,
+ mFvDataInfo.FvNameGuid.Data4[0],
+ mFvDataInfo.FvNameGuid.Data4[1],
+ mFvDataInfo.FvNameGuid.Data4[2],
+ mFvDataInfo.FvNameGuid.Data4[3],
+ mFvDataInfo.FvNameGuid.Data4[4],
+ mFvDataInfo.FvNameGuid.Data4[5],
+ mFvDataInfo.FvNameGuid.Data4[6],
+ mFvDataInfo.FvNameGuid.Data4[7]);
+ }
+
+ if (CompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0 ||
+ CompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem3Guid) == 0) {
+ mFvDataInfo.IsPiFvImage = TRUE;
+ }
+
+ //
+ // FvMap file to log the function address of all modules in one Fvimage
+ //
+ if (MapFileName != NULL) {
+ if (strlen (MapFileName) > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "MapFileName %s is too long!", MapFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ FvMapName = malloc (strlen (MapFileName) + 1);
+ if (FvMapName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
+ strcpy (FvMapName, MapFileName);
+ } else {
+ if (strlen (FvFileName) + strlen (".map") > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "FvFileName %s is too long!", FvFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ FvMapName = malloc (strlen (FvFileName) + strlen (".map") + 1);
+ if (FvMapName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
+ strcpy (FvMapName, FvFileName);
+ strcat (FvMapName, ".map");
+ }
+ VerboseMsg ("FV Map file name is %s", FvMapName);
+
+ //
+ // FvReport file to log the FV information in one Fvimage
+ //
+ if (strlen (FvFileName) + strlen (".txt") > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "FvFileName %s is too long!", FvFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ FvReportName = malloc (strlen (FvFileName) + strlen (".txt") + 1);
+ if (FvReportName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
+ strcpy (FvReportName, FvFileName);
+ strcat (FvReportName, ".txt");
+
+ //
+ // Calculate the FV size and Update Fv Size based on the actual FFS files.
+ // And Update mFvDataInfo data.
+ //
+ Status = CalculateFvSize (&mFvDataInfo);
+ if (EFI_ERROR (Status)) {
+ goto Finish;
+ }
+ VerboseMsg ("the generated FV image size is %u bytes", (unsigned) mFvDataInfo.Size);
+
+ //
+ // support fv image and empty fv image
+ //
+ FvImageSize = mFvDataInfo.Size;
+
+ //
+ // Allocate the FV, assure FvImage Header 8 byte alignment
+ //
+ FvBufferHeader = malloc (FvImageSize + sizeof (UINT64));
+ if (FvBufferHeader == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+ FvImage = (UINT8 *) (((UINTN) FvBufferHeader + 7) & ~7);
+
+ //
+ // Initialize the FV to the erase polarity
+ //
+ if (mFvDataInfo.FvAttributes == 0) {
+ //
+ // Set Default Fv Attribute
+ //
+ mFvDataInfo.FvAttributes = FV_DEFAULT_ATTRIBUTE;
+ }
+ if (mFvDataInfo.FvAttributes & EFI_FVB2_ERASE_POLARITY) {
+ memset (FvImage, -1, FvImageSize);
+ } else {
+ memset (FvImage, 0, FvImageSize);
+ }
+
+ //
+ // Initialize FV header
+ //
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage;
+
+ //
+ // Initialize the zero vector to all zeros.
+ //
+ memset (FvHeader->ZeroVector, 0, 16);
+
+ //
+ // Copy the Fv file system GUID
+ //
+ memcpy (&FvHeader->FileSystemGuid, &mFvDataInfo.FvFileSystemGuid, sizeof (EFI_GUID));
+
+ FvHeader->FvLength = FvImageSize;
+ FvHeader->Signature = EFI_FVH_SIGNATURE;
+ FvHeader->Attributes = mFvDataInfo.FvAttributes;
+ FvHeader->Revision = EFI_FVH_REVISION;
+ FvHeader->ExtHeaderOffset = 0;
+ FvHeader->Reserved[0] = 0;
+
+ //
+ // Copy firmware block map
+ //
+ for (Index = 0; mFvDataInfo.FvBlocks[Index].Length != 0; Index++) {
+ FvHeader->BlockMap[Index].NumBlocks = mFvDataInfo.FvBlocks[Index].NumBlocks;
+ FvHeader->BlockMap[Index].Length = mFvDataInfo.FvBlocks[Index].Length;
+ }
+
+ //
+ // Add block map terminator
+ //
+ FvHeader->BlockMap[Index].NumBlocks = 0;
+ FvHeader->BlockMap[Index].Length = 0;
+
+ //
+ // Complete the header
+ //
+ FvHeader->HeaderLength = (UINT16) (((UINTN) &(FvHeader->BlockMap[Index + 1])) - (UINTN) FvImage);
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+
+ //
+ // If there is no FFS file, generate one empty FV
+ //
+ if (mFvDataInfo.FvFiles[0][0] == 0 && !mFvDataInfo.FvNameGuidSet) {
+ goto WriteFile;
+ }
+
+ //
+ // Initialize our "file" view of the buffer
+ //
+ FvImageMemoryFile.FileImage = (CHAR8 *)FvImage;
+ FvImageMemoryFile.CurrentFilePointer = (CHAR8 *)FvImage + FvHeader->HeaderLength;
+ FvImageMemoryFile.Eof = (CHAR8 *)FvImage + FvImageSize;
+
+ //
+ // Initialize the FV library.
+ //
+ InitializeFvLib (FvImageMemoryFile.FileImage, FvImageSize);
+
+ //
+ // Initialize the VTF file address.
+ //
+ VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof;
+
+ //
+ // Open FvMap file
+ //
+ FvMapFile = fopen (LongFilePath (FvMapName), "w");
+ if (FvMapFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", FvMapName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ //
+ // Open FvReport file
+ //
+ FvReportFile = fopen (LongFilePath (FvReportName), "w");
+ if (FvReportFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", FvReportName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+ //
+ // record FV size information into FvMap file.
+ //
+ if (mFvTotalSize != 0) {
+ fprintf (FvMapFile, EFI_FV_TOTAL_SIZE_STRING);
+ fprintf (FvMapFile, " = 0x%x\n", (unsigned) mFvTotalSize);
+ }
+ if (mFvTakenSize != 0) {
+ fprintf (FvMapFile, EFI_FV_TAKEN_SIZE_STRING);
+ fprintf (FvMapFile, " = 0x%x\n", (unsigned) mFvTakenSize);
+ }
+ if (mFvTotalSize != 0 && mFvTakenSize != 0) {
+ fprintf (FvMapFile, EFI_FV_SPACE_SIZE_STRING);
+ fprintf (FvMapFile, " = 0x%x\n\n", (unsigned) (mFvTotalSize - mFvTakenSize));
+ }
+
+ //
+ // record FV size information to FvReportFile.
+ //
+ fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
+ fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);
+
+ //
+ // Add PI FV extension header
+ //
+ if (FvExtHeader != NULL) {
+ //
+ // Add FV Extended Header contents to the FV as a PAD file
+ //
+ AddPadFile (&FvImageMemoryFile, 4, VtfFileImage, FvExtHeader, 0);
+
+ //
+ // Fv Extension header change update Fv Header Check sum
+ //
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
+ //
+ // Add files to FV
+ //
+ for (Index = 0; mFvDataInfo.FvFiles[Index][0] != 0; Index++) {
+ //
+ // Add the file
+ //
+ Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile, FvReportFile);
+
+ //
+ // Exit if error detected while adding the file
+ //
+ if (EFI_ERROR (Status)) {
+ goto Finish;
+ }
+ }
+
+ //
+ // If there is a VTF file, some special actions need to occur.
+ //
+ if ((UINTN) VtfFileImage != (UINTN) FvImageMemoryFile.Eof) {
+ //
+ // Pad from the end of the last file to the beginning of the VTF file.
+ // If the left space is less than sizeof (EFI_FFS_FILE_HEADER)?
+ //
+ Status = PadFvImage (&FvImageMemoryFile, VtfFileImage);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add pad file between the last file and the VTF file.");
+ goto Finish;
+ }
+
+ if (!mArm && !mRiscV) {
+ //
+ // Update reset vector (SALE_ENTRY for IPF)
+ // Now for IA32 and IA64 platform, the fv which has bsf file must have the
+ // EndAddress of 0xFFFFFFFF (unless the section was rebased).
+ // Thus, only this type fv needs to update the reset vector.
+ // If the PEI Core is found, the VTF file will probably get
+ // corrupted by updating the entry point.
+ //
+ if (mFvDataInfo.ForceRebase == 1 ||
+ (mFvDataInfo.BaseAddress + mFvDataInfo.Size) == FV_IMAGES_TOP_ADDRESS) {
+ Status = UpdateResetVector (&FvImageMemoryFile, &mFvDataInfo, VtfFileImage);
+ if (EFI_ERROR(Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
+ goto Finish;
+ }
+ DebugMsg (NULL, 0, 9, "Update Reset vector in VTF file", NULL);
+ }
+ }
+ }
+
+ if (mArm) {
+ Status = UpdateArmResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
+ goto Finish;
+ }
+
+ //
+ // Update Checksum for FvHeader
+ //
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
+ if (mRiscV) {
+ //
+ // Update RISCV reset vector.
+ //
+ Status = UpdateRiscvResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector for RISC-V.");
+ goto Finish;
+ }
+ //
+ // Update Checksum for FvHeader
+ //
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
+ //
+ // Update FV Alignment attribute to the largest alignment of all the FFS files in the FV
+ //
+ if (((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) &&
+ (((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16)) < MaxFfsAlignment) {
+ FvHeader->Attributes = ((MaxFfsAlignment << 16) | (FvHeader->Attributes & 0xFFFF));
+ //
+ // Update Checksum for FvHeader
+ //
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
+ //
+ // If there are large FFS in FV, the file system GUID should set to system 3 GUID.
+ //
+ if (mIsLargeFfs && CompareGuid (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0) {
+ memcpy (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem3Guid, sizeof (EFI_GUID));
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
+WriteFile:
+ //
+ // Write fv file
+ //
+ FvFile = fopen (LongFilePath (FvFileName), "wb");
+ if (FvFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", FvFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) {
+ Error (NULL, 0, 0002, "Error writing file", FvFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+Finish:
+ if (FvBufferHeader != NULL) {
+ free (FvBufferHeader);
+ }
+
+ if (FvExtHeader != NULL) {
+ free (FvExtHeader);
+ }
+
+ if (FvMapName != NULL) {
+ free (FvMapName);
+ }
+
+ if (FvReportName != NULL) {
+ free (FvReportName);
+ }
+
+ if (FvFile != NULL) {
+ fflush (FvFile);
+ fclose (FvFile);
+ }
+
+ if (FvMapFile != NULL) {
+ fflush (FvMapFile);
+ fclose (FvMapFile);
+ }
+
+ if (FvReportFile != NULL) {
+ fflush (FvReportFile);
+ fclose (FvReportFile);
+ }
+ return Status;
+}
+
+EFI_STATUS
+UpdatePeiCoreEntryInFit (
+ IN FIT_TABLE *FitTablePtr,
+ IN UINT64 PeiCorePhysicalAddress
+ )
+/*++
+
+Routine Description:
+
+ This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from
+ Sec to Pei Core
+
+Arguments:
+
+ FitTablePtr - The pointer of FIT_TABLE.
+ PeiCorePhysicalAddress - The address of Pei Core entry.
+
+Returns:
+
+ EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully.
+ EFI_NOT_FOUND - Not found the PEI_CORE FIT entry.
+
+--*/
+{
+ FIT_TABLE *TmpFitPtr;
+ UINTN Index;
+ UINTN NumFitComponents;
+
+ TmpFitPtr = FitTablePtr;
+ NumFitComponents = TmpFitPtr->CompSize;
+
+ for (Index = 0; Index < NumFitComponents; Index++) {
+ if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_PEICORE) {
+ TmpFitPtr->CompAddress = PeiCorePhysicalAddress;
+ return EFI_SUCCESS;
+ }
+
+ TmpFitPtr++;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+VOID
+UpdateFitCheckSum (
+ IN FIT_TABLE *FitTablePtr
+ )
+/*++
+
+Routine Description:
+
+ This function is used to update the checksum for FIT.
+
+
+Arguments:
+
+ FitTablePtr - The pointer of FIT_TABLE.
+
+Returns:
+
+ None.
+
+--*/
+{
+ if ((FitTablePtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {
+ FitTablePtr->CheckSum = 0;
+ FitTablePtr->CheckSum = CalculateChecksum8 ((UINT8 *) FitTablePtr, FitTablePtr->CompSize * 16);
+ }
+}
+
+EFI_STATUS
+CalculateFvSize (
+ FV_INFO *FvInfoPtr
+ )
+/*++
+Routine Description:
+ Calculate the FV size and Update Fv Size based on the actual FFS files.
+ And Update FvInfo data.
+
+Arguments:
+ FvInfoPtr - The pointer to FV_INFO structure.
+
+Returns:
+ EFI_ABORTED - Ffs Image Error
+ EFI_SUCCESS - Successfully update FvSize
+--*/
+{
+ UINTN CurrentOffset;
+ UINTN OrigOffset;
+ UINTN Index;
+ FILE *fpin;
+ UINTN FfsFileSize;
+ UINTN FvExtendHeaderSize;
+ UINT32 FfsAlignment;
+ UINT32 FfsHeaderSize;
+ EFI_FFS_FILE_HEADER FfsHeader;
+ UINTN VtfFileSize;
+ UINTN MaxPadFileSize;
+
+ FvExtendHeaderSize = 0;
+ MaxPadFileSize = 0;
+ VtfFileSize = 0;
+ fpin = NULL;
+ Index = 0;
+
+ //
+ // Compute size for easy access later
+ //
+ FvInfoPtr->Size = 0;
+ for (Index = 0; FvInfoPtr->FvBlocks[Index].NumBlocks > 0 && FvInfoPtr->FvBlocks[Index].Length > 0; Index++) {
+ FvInfoPtr->Size += FvInfoPtr->FvBlocks[Index].NumBlocks * FvInfoPtr->FvBlocks[Index].Length;
+ }
+
+ //
+ // Calculate the required sizes for all FFS files.
+ //
+ CurrentOffset = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
+
+ for (Index = 1;; Index ++) {
+ CurrentOffset += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+ if (FvInfoPtr->FvBlocks[Index].NumBlocks == 0 || FvInfoPtr->FvBlocks[Index].Length == 0) {
+ break;
+ }
+ }
+
+ //
+ // Calculate PI extension header
+ //
+ if (mFvDataInfo.FvExtHeaderFile[0] != '\0') {
+ fpin = fopen (LongFilePath (mFvDataInfo.FvExtHeaderFile), "rb");
+ if (fpin == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mFvDataInfo.FvExtHeaderFile);
+ return EFI_ABORTED;
+ }
+ FvExtendHeaderSize = _filelength (fileno (fpin));
+ fclose (fpin);
+ if (sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize >= MAX_FFS_SIZE) {
+ CurrentOffset += sizeof (EFI_FFS_FILE_HEADER2) + FvExtendHeaderSize;
+ mIsLargeFfs = TRUE;
+ } else {
+ CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize;
+ }
+ CurrentOffset = (CurrentOffset + 7) & (~7);
+ } else if (mFvDataInfo.FvNameGuidSet) {
+ CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);
+ CurrentOffset = (CurrentOffset + 7) & (~7);
+ }
+
+ //
+ // Accumulate every FFS file size.
+ //
+ for (Index = 0; FvInfoPtr->FvFiles[Index][0] != 0; Index++) {
+ //
+ // Open FFS file
+ //
+ fpin = NULL;
+ fpin = fopen (LongFilePath (FvInfoPtr->FvFiles[Index]), "rb");
+ if (fpin == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", FvInfoPtr->FvFiles[Index]);
+ return EFI_ABORTED;
+ }
+ //
+ // Get the file size
+ //
+ FfsFileSize = _filelength (fileno (fpin));
+ if (FfsFileSize >= MAX_FFS_SIZE) {
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
+ mIsLargeFfs = TRUE;
+ } else {
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER);
+ }
+ //
+ // Read Ffs File header
+ //
+ fread (&FfsHeader, sizeof (UINT8), sizeof (EFI_FFS_FILE_HEADER), fpin);
+ //
+ // close file
+ //
+ fclose (fpin);
+
+ if (FvInfoPtr->IsPiFvImage) {
+ //
+ // Check whether this ffs file is vtf file
+ //
+ if (IsVtfFile (&FfsHeader)) {
+ if (VtfFileFlag) {
+ //
+ // One Fv image can't have two vtf files.
+ //
+ Error (NULL, 0, 3000,"Invalid", "One Fv image can't have two vtf files.");
+ return EFI_ABORTED;
+ }
+ VtfFileFlag = TRUE;
+ VtfFileSize = FfsFileSize;
+ continue;
+ }
+
+ //
+ // Get the alignment of FFS file
+ //
+ ReadFfsAlignment (&FfsHeader, &FfsAlignment);
+ FfsAlignment = 1 << FfsAlignment;
+ //
+ // Add Pad file
+ //
+ if (((CurrentOffset + FfsHeaderSize) % FfsAlignment) != 0) {
+ //
+ // Only EFI_FFS_FILE_HEADER is needed for a pad section.
+ //
+ OrigOffset = CurrentOffset;
+ CurrentOffset = (CurrentOffset + FfsHeaderSize + sizeof(EFI_FFS_FILE_HEADER) + FfsAlignment - 1) & ~(FfsAlignment - 1);
+ CurrentOffset -= FfsHeaderSize;
+ if ((CurrentOffset - OrigOffset) > MaxPadFileSize) {
+ MaxPadFileSize = CurrentOffset - OrigOffset;
+ }
+ }
+ }
+
+ //
+ // Add ffs file size
+ //
+ if (FvInfoPtr->SizeofFvFiles[Index] > FfsFileSize) {
+ CurrentOffset += FvInfoPtr->SizeofFvFiles[Index];
+ } else {
+ CurrentOffset += FfsFileSize;
+ }
+
+ //
+ // Make next ffs file start at QWord Boundary
+ //
+ if (FvInfoPtr->IsPiFvImage) {
+ CurrentOffset = (CurrentOffset + EFI_FFS_FILE_HEADER_ALIGNMENT - 1) & ~(EFI_FFS_FILE_HEADER_ALIGNMENT - 1);
+ }
+ }
+ CurrentOffset += VtfFileSize;
+ DebugMsg (NULL, 0, 9, "FvImage size", "The calculated fv image size is 0x%x and the current set fv image size is 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size);
+
+ if (FvInfoPtr->Size == 0) {
+ //
+ // Update FvInfo data
+ //
+ FvInfoPtr->FvBlocks[0].NumBlocks = CurrentOffset / FvInfoPtr->FvBlocks[0].Length + ((CurrentOffset % FvInfoPtr->FvBlocks[0].Length)?1:0);
+ FvInfoPtr->Size = FvInfoPtr->FvBlocks[0].NumBlocks * FvInfoPtr->FvBlocks[0].Length;
+ FvInfoPtr->FvBlocks[1].NumBlocks = 0;
+ FvInfoPtr->FvBlocks[1].Length = 0;
+ } else if (FvInfoPtr->Size < CurrentOffset) {
+ //
+ // Not invalid
+ //
+ Error (NULL, 0, 3000, "Invalid", "the required fv image size 0x%x exceeds the set fv image size 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Set Fv Size Information
+ //
+ mFvTotalSize = FvInfoPtr->Size;
+ mFvTakenSize = CurrentOffset;
+ if ((mFvTakenSize == mFvTotalSize) && (MaxPadFileSize > 0)) {
+ //
+ // This FV means TOP FFS has been taken. Then, check whether there is padding data for use.
+ //
+ mFvTakenSize = mFvTakenSize - MaxPadFileSize;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FfsRebaseImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINT32 *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+
+ FileOffset - The offset, in bytes, into the file to read
+
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+
+ Buffer - A pointer to the buffer to read the data into.
+
+Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINT32 Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetChildFvFromFfs (
+ IN FV_INFO *FvInfo,
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINTN XipOffset
+ )
+/*++
+
+Routine Description:
+
+ This function gets all child FvImages in the input FfsFile, and records
+ their base address to the parent image.
+
+Arguments:
+ FvInfo A pointer to FV_INFO structure.
+ FfsFile A pointer to Ffs file image that may contain FvImage.
+ XipOffset The offset address to the parent FvImage base.
+
+Returns:
+
+ EFI_SUCCESS Base address of child Fv image is recorded.
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_FILE_SECTION_POINTER SubFvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *SubFvImageHeader;
+ EFI_PHYSICAL_ADDRESS SubFvBaseAddress;
+ EFI_FILE_SECTION_POINTER CorePe32;
+ UINT16 MachineType;
+
+ for (Index = 1;; Index++) {
+ //
+ // Find FV section
+ //
+ Status = GetSectionByType (FfsFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, Index, &SubFvSection);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + GetSectionHeaderLength(SubFvSection.FVImageSection));
+
+ //
+ // See if there's an SEC core in the child FV
+ Status = FindCorePeSection(SubFvImageHeader, SubFvImageHeader->FvLength, EFI_FV_FILETYPE_SECURITY_CORE, &CorePe32);
+
+ // if we couldn't find the SEC core, look for a PEI core
+ if (EFI_ERROR(Status)) {
+ Status = FindCorePeSection(SubFvImageHeader, SubFvImageHeader->FvLength, EFI_FV_FILETYPE_PEI_CORE, &CorePe32);
+ }
+
+ if (!EFI_ERROR(Status)) {
+ Status = GetCoreMachineType(CorePe32, &MachineType);
+ if (EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC/PEI Core.");
+ return EFI_ABORTED;
+ }
+
+ // machine type is ARM, set a flag so ARM reset vector processing occurs
+ if ((MachineType == EFI_IMAGE_MACHINE_ARMT) || (MachineType == EFI_IMAGE_MACHINE_AARCH64)) {
+ VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
+ mArm = TRUE;
+ }
+ }
+
+ //
+ // Rebase on Flash
+ //
+ SubFvBaseAddress = FvInfo->BaseAddress + (UINTN) SubFvImageHeader - (UINTN) FfsFile + XipOffset;
+ mFvBaseAddress[mFvBaseAddressNumber ++ ] = SubFvBaseAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FfsRebase (
+ IN OUT FV_INFO *FvInfo,
+ IN CHAR8 *FileName,
+ IN OUT EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINTN XipOffset,
+ IN FILE *FvMapFile
+ )
+/*++
+
+Routine Description:
+
+ This function determines if a file is XIP and should be rebased. It will
+ rebase any PE32 sections found in the file using the base address.
+
+Arguments:
+
+ FvInfo A pointer to FV_INFO structure.
+ FileName Ffs File PathName
+ FfsFile A pointer to Ffs file image.
+ XipOffset The offset address to use for rebasing the XIP file image.
+ FvMapFile FvMapFile to record the function address in one Fvimage
+
+Returns:
+
+ EFI_SUCCESS The image was properly rebased.
+ EFI_INVALID_PARAMETER An input parameter is invalid.
+ EFI_ABORTED An error occurred while rebasing the input file image.
+ EFI_OUT_OF_RESOURCES Could not allocate a required resource.
+ EFI_NOT_FOUND No compressed sections could be found.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ PE_COFF_LOADER_IMAGE_CONTEXT OrigImageContext;
+ EFI_PHYSICAL_ADDRESS XipBase;
+ EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;
+ UINTN Index;
+ EFI_FILE_SECTION_POINTER CurrentPe32Section;
+ EFI_FFS_FILE_STATE SavedState;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_TE_IMAGE_HEADER *TEImageHeader;
+ UINT8 *MemoryImagePointer;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ CHAR8 PeFileName [MAX_LONG_FILE_PATH];
+ CHAR8 *Cptr;
+ FILE *PeFile;
+ UINT8 *PeFileBuffer;
+ UINT32 PeFileSize;
+ CHAR8 *PdbPointer;
+ UINT32 FfsHeaderSize;
+ UINT32 CurSecHdrSize;
+
+ Index = 0;
+ MemoryImagePointer = NULL;
+ TEImageHeader = NULL;
+ ImgHdr = NULL;
+ SectionHeader = NULL;
+ Cptr = NULL;
+ PeFile = NULL;
+ PeFileBuffer = NULL;
+
+ //
+ // Don't need to relocate image when BaseAddress is zero and no ForceRebase Flag specified.
+ //
+ if ((FvInfo->BaseAddress == 0) && (FvInfo->ForceRebase == -1)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If ForceRebase Flag specified to FALSE, will always not take rebase action.
+ //
+ if (FvInfo->ForceRebase == 0) {
+ return EFI_SUCCESS;
+ }
+
+
+ XipBase = FvInfo->BaseAddress + XipOffset;
+
+ //
+ // We only process files potentially containing PE32 sections.
+ //
+ switch (FfsFile->Type) {
+ case EFI_FV_FILETYPE_SECURITY_CORE:
+ case EFI_FV_FILETYPE_PEI_CORE:
+ case EFI_FV_FILETYPE_PEIM:
+ case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
+ case EFI_FV_FILETYPE_DRIVER:
+ case EFI_FV_FILETYPE_DXE_CORE:
+ break;
+ case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
+ //
+ // Rebase the inside FvImage.
+ //
+ GetChildFvFromFfs (FvInfo, FfsFile, XipOffset);
+
+ //
+ // Search PE/TE section in FV sectin.
+ //
+ break;
+ default:
+ return EFI_SUCCESS;
+ }
+
+ FfsHeaderSize = GetFfsHeaderLength(FfsFile);
+ //
+ // Rebase each PE32 section
+ //
+ Status = EFI_SUCCESS;
+ for (Index = 1;; Index++) {
+ //
+ // Init Value
+ //
+ NewPe32BaseAddress = 0;
+
+ //
+ // Find Pe Image
+ //
+ Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader);
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
+ return Status;
+ }
+
+ if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_ARMT) ||
+ (ImageContext.Machine == EFI_IMAGE_MACHINE_AARCH64) ) {
+ mArm = TRUE;
+ }
+
+ if (ImageContext.Machine == EFI_IMAGE_MACHINE_RISCV64) {
+ mRiscV = TRUE;
+ }
+
+ //
+ // Keep Image Context for PE image in FV
+ //
+ memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext));
+
+ //
+ // Get File PdbPointer
+ //
+ PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);
+
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Calculate the PE32 base address, based on file type
+ //
+ switch (FfsFile->Type) {
+ case EFI_FV_FILETYPE_SECURITY_CORE:
+ case EFI_FV_FILETYPE_PEI_CORE:
+ case EFI_FV_FILETYPE_PEIM:
+ case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
+ //
+ // Check if section-alignment and file-alignment match or not
+ //
+ if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
+ //
+ // Xip module has the same section alignment and file alignment.
+ //
+ Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
+ return EFI_ABORTED;
+ }
+ //
+ // PeImage has no reloc section. It will try to get reloc data from the original EFI image.
+ //
+ if (ImageContext.RelocationsStripped) {
+ //
+ // Construct the original efi file Name
+ //
+ if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
+ Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);
+ return EFI_ABORTED;
+ }
+ strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);
+ PeFileName[MAX_LONG_FILE_PATH - 1] = 0;
+ Cptr = PeFileName + strlen (PeFileName);
+ while (*Cptr != '.') {
+ Cptr --;
+ }
+ if (*Cptr != '.') {
+ Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
+ return EFI_ABORTED;
+ } else {
+ *(Cptr + 1) = 'e';
+ *(Cptr + 2) = 'f';
+ *(Cptr + 3) = 'i';
+ *(Cptr + 4) = '\0';
+ }
+ PeFile = fopen (LongFilePath (PeFileName), "rb");
+ if (PeFile == NULL) {
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+ //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
+ //return EFI_ABORTED;
+ break;
+ }
+ //
+ // Get the file size
+ //
+ PeFileSize = _filelength (fileno (PeFile));
+ PeFileBuffer = (UINT8 *) malloc (PeFileSize);
+ if (PeFileBuffer == NULL) {
+ fclose (PeFile);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Read Pe File
+ //
+ fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);
+ //
+ // close file
+ //
+ fclose (PeFile);
+ //
+ // Handle pointer to the original efi image.
+ //
+ ImageContext.Handle = PeFileBuffer;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
+ return Status;
+ }
+ ImageContext.RelocationsStripped = FALSE;
+ }
+
+ NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
+ break;
+
+ case EFI_FV_FILETYPE_DRIVER:
+ case EFI_FV_FILETYPE_DXE_CORE:
+ //
+ // Check if section-alignment and file-alignment match or not
+ //
+ if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
+ //
+ // Xip module has the same section alignment and file alignment.
+ //
+ Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
+ return EFI_ABORTED;
+ }
+ NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
+ break;
+
+ default:
+ //
+ // Not supported file type
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Relocation doesn't exist
+ //
+ if (ImageContext.RelocationsStripped) {
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+ continue;
+ }
+
+ //
+ // Relocation exist and rebase
+ //
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy Relocated data to raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ CopyMem (
+ (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ }
+
+ free ((VOID *) MemoryImagePointer);
+ MemoryImagePointer = NULL;
+ if (PeFileBuffer != NULL) {
+ free (PeFileBuffer);
+ PeFileBuffer = NULL;
+ }
+
+ //
+ // Update Image Base Address
+ //
+ if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
+ } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
+ ImgHdr->Pe32.OptionalHeader.Magic,
+ FileName
+ );
+ return EFI_ABORTED;
+ }
+
+ //
+ // Now update file checksum
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
+ SavedState = FfsFile->State;
+ FfsFile->IntegrityCheck.Checksum.File = 0;
+ FfsFile->State = 0;
+ FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
+ (UINT8 *) ((UINT8 *)FfsFile + FfsHeaderSize),
+ GetFfsFileLength (FfsFile) - FfsHeaderSize
+ );
+ FfsFile->State = SavedState;
+ }
+
+ //
+ // Get this module function address from ModulePeMapFile and add them into FvMap file
+ //
+
+ //
+ // Default use FileName as map file path
+ //
+ if (PdbPointer == NULL) {
+ PdbPointer = FileName;
+ }
+
+ WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext);
+ }
+
+ if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
+ FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
+ FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
+ FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&
+ FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
+ ) {
+ //
+ // Only Peim code may have a TE section
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Now process TE sections
+ //
+ for (Index = 1;; Index++) {
+ NewPe32BaseAddress = 0;
+
+ //
+ // Find Te Image
+ //
+ Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader);
+
+ //
+ // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
+ // by GenTEImage
+ //
+ TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize);
+
+ //
+ // Initialize context, load image info.
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) TEImageHeader;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
+ return Status;
+ }
+
+ if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_ARMT) ||
+ (ImageContext.Machine == EFI_IMAGE_MACHINE_AARCH64) ) {
+ mArm = TRUE;
+ }
+
+ //
+ // Keep Image Context for TE image in FV
+ //
+ memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext));
+
+ //
+ // Get File PdbPointer
+ //
+ PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);
+
+ //
+ // Set new rebased address.
+ //
+ NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \
+ - TEImageHeader->StrippedSize - (UINTN) FfsFile;
+
+ //
+ // if reloc is stripped, try to get the original efi image to get reloc info.
+ //
+ if (ImageContext.RelocationsStripped) {
+ //
+ // Construct the original efi file name
+ //
+ if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
+ Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);
+ return EFI_ABORTED;
+ }
+ strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);
+ PeFileName[MAX_LONG_FILE_PATH - 1] = 0;
+ Cptr = PeFileName + strlen (PeFileName);
+ while (*Cptr != '.') {
+ Cptr --;
+ }
+
+ if (*Cptr != '.') {
+ Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
+ return EFI_ABORTED;
+ } else {
+ *(Cptr + 1) = 'e';
+ *(Cptr + 2) = 'f';
+ *(Cptr + 3) = 'i';
+ *(Cptr + 4) = '\0';
+ }
+
+ PeFile = fopen (LongFilePath (PeFileName), "rb");
+ if (PeFile == NULL) {
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+ //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
+ //return EFI_ABORTED;
+ } else {
+ //
+ // Get the file size
+ //
+ PeFileSize = _filelength (fileno (PeFile));
+ PeFileBuffer = (UINT8 *) malloc (PeFileSize);
+ if (PeFileBuffer == NULL) {
+ fclose (PeFile);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Read Pe File
+ //
+ fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);
+ //
+ // close file
+ //
+ fclose (PeFile);
+ //
+ // Append reloc section into TeImage
+ //
+ ImageContext.Handle = PeFileBuffer;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
+ return Status;
+ }
+ ImageContext.RelocationsStripped = FALSE;
+ }
+ }
+ //
+ // Relocation doesn't exist
+ //
+ if (ImageContext.RelocationsStripped) {
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+ continue;
+ }
+
+ //
+ // Relocation exist and rebase
+ //
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+ //
+ // Reloacate TeImage
+ //
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy the relocated image into raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
+ for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {
+ if (!ImageContext.IsTeImage) {
+ CopyMem (
+ (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ } else {
+ CopyMem (
+ (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ }
+ }
+
+ //
+ // Free the allocated memory resource
+ //
+ free ((VOID *) MemoryImagePointer);
+ MemoryImagePointer = NULL;
+ if (PeFileBuffer != NULL) {
+ free (PeFileBuffer);
+ PeFileBuffer = NULL;
+ }
+
+ //
+ // Update Image Base Address
+ //
+ TEImageHeader->ImageBase = NewPe32BaseAddress;
+
+ //
+ // Now update file checksum
+ //
+ if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
+ SavedState = FfsFile->State;
+ FfsFile->IntegrityCheck.Checksum.File = 0;
+ FfsFile->State = 0;
+ FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
+ (UINT8 *)((UINT8 *)FfsFile + FfsHeaderSize),
+ GetFfsFileLength (FfsFile) - FfsHeaderSize
+ );
+ FfsFile->State = SavedState;
+ }
+ //
+ // Get this module function address from ModulePeMapFile and add them into FvMap file
+ //
+
+ //
+ // Default use FileName as map file path
+ //
+ if (PdbPointer == NULL) {
+ PdbPointer = FileName;
+ }
+
+ WriteMapFile (
+ FvMapFile,
+ PdbPointer,
+ FfsFile,
+ NewPe32BaseAddress,
+ &OrigImageContext
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FindApResetVectorPosition (
+ IN MEMORY_FILE *FvImage,
+ OUT UINT8 **Pointer
+ )
+/*++
+
+Routine Description:
+
+ Find the position in this FvImage to place Ap reset vector.
+
+Arguments:
+
+ FvImage Memory file for the FV memory image.
+ Pointer Pointer to pointer to position.
+
+Returns:
+
+ EFI_NOT_FOUND - No satisfied position is found.
+ EFI_SUCCESS - The suitable position is return.
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *PadFile;
+ UINT32 Index;
+ EFI_STATUS Status;
+ UINT8 *FixPoint;
+ UINT32 FileLength;
+
+ for (Index = 1; ;Index ++) {
+ //
+ // Find Pad File to add ApResetVector info
+ //
+ Status = GetFileByType (EFI_FV_FILETYPE_FFS_PAD, Index, &PadFile);
+ if (EFI_ERROR (Status) || (PadFile == NULL)) {
+ //
+ // No Pad file to be found.
+ //
+ break;
+ }
+ //
+ // Get Pad file size.
+ //
+ FileLength = GetFfsFileLength(PadFile);
+ FileLength = (FileLength + EFI_FFS_FILE_HEADER_ALIGNMENT - 1) & ~(EFI_FFS_FILE_HEADER_ALIGNMENT - 1);
+ //
+ // FixPoint must be align on 0x1000 relative to FvImage Header
+ //
+ FixPoint = (UINT8*) PadFile + GetFfsHeaderLength(PadFile);
+ FixPoint = FixPoint + 0x1000 - (((UINTN) FixPoint - (UINTN) FvImage->FileImage) & 0xFFF);
+ //
+ // FixPoint be larger at the last place of one fv image.
+ //
+ while (((UINTN) FixPoint + SIZEOF_STARTUP_DATA_ARRAY - (UINTN) PadFile) <= FileLength) {
+ FixPoint += 0x1000;
+ }
+ FixPoint -= 0x1000;
+
+ if ((UINTN) FixPoint < ((UINTN) PadFile + GetFfsHeaderLength(PadFile))) {
+ //
+ // No alignment FixPoint in this Pad File.
+ //
+ continue;
+ }
+
+ if ((UINTN) FvImage->Eof - (UINTN)FixPoint <= 0x20000) {
+ //
+ // Find the position to place ApResetVector
+ //
+ *Pointer = FixPoint;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+ParseCapInf (
+ IN MEMORY_FILE *InfFile,
+ OUT CAP_INFO *CapInfo
+ )
+/*++
+
+Routine Description:
+
+ This function parses a Cap.INF file and copies info into a CAP_INFO structure.
+
+Arguments:
+
+ InfFile Memory file image.
+ CapInfo Information read from INF file.
+
+Returns:
+
+ EFI_SUCCESS INF file information successfully retrieved.
+ EFI_ABORTED INF file has an invalid format.
+ EFI_NOT_FOUND A required string was not found in the INF file.
+--*/
+{
+ CHAR8 Value[MAX_LONG_FILE_PATH];
+ UINT64 Value64;
+ UINTN Index, Number;
+ EFI_STATUS Status;
+
+ //
+ // Initialize Cap info
+ //
+ // memset (CapInfo, 0, sizeof (CAP_INFO));
+ //
+
+ //
+ // Read the Capsule Guid
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_CAPSULE_GUID_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ //
+ // Get the Capsule Guid
+ //
+ Status = StringToGuid (Value, &CapInfo->CapGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_CAPSULE_GUID_STRING, Value);
+ return EFI_ABORTED;
+ }
+ DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, Value);
+ }
+
+ //
+ // Read the Capsule Header Size
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_CAPSULE_HEADER_SIZE_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ Status = AsciiStringToUint64 (Value, FALSE, &Value64);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_CAPSULE_HEADER_SIZE_STRING, Value);
+ return EFI_ABORTED;
+ }
+ CapInfo->HeaderSize = (UINT32) Value64;
+ DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = %s", EFI_CAPSULE_HEADER_SIZE_STRING, Value);
+ }
+
+ //
+ // Read the Capsule Flag
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_CAPSULE_FLAGS_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ if (strstr (Value, "PopulateSystemTable") != NULL) {
+ CapInfo->Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
+ if (strstr (Value, "InitiateReset") != NULL) {
+ CapInfo->Flags |= CAPSULE_FLAGS_INITIATE_RESET;
+ }
+ } else if (strstr (Value, "PersistAcrossReset") != NULL) {
+ CapInfo->Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
+ if (strstr (Value, "InitiateReset") != NULL) {
+ CapInfo->Flags |= CAPSULE_FLAGS_INITIATE_RESET;
+ }
+ } else {
+ Error (NULL, 0, 2000, "Invalid parameter", "invalid Flag setting for %s.", EFI_CAPSULE_FLAGS_STRING);
+ return EFI_ABORTED;
+ }
+ DebugMsg (NULL, 0, 9, "Capsule Flag", Value);
+ }
+
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_OEM_CAPSULE_FLAGS_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ Status = AsciiStringToUint64 (Value, FALSE, &Value64);
+ if (EFI_ERROR (Status) || Value64 > 0xffff) {
+ Error (NULL, 0, 2000, "Invalid parameter",
+ "invalid Flag setting for %s. Must be integer value between 0x0000 and 0xffff.",
+ EFI_OEM_CAPSULE_FLAGS_STRING);
+ return EFI_ABORTED;
+ }
+ CapInfo->Flags |= Value64;
+ DebugMsg (NULL, 0, 9, "Capsule Extend Flag", Value);
+ }
+
+ //
+ // Read Capsule File name
+ //
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FILE_NAME_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ //
+ // Get output file name
+ //
+ strcpy (CapInfo->CapName, Value);
+ }
+
+ //
+ // Read the Capsule FileImage
+ //
+ Number = 0;
+ for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_CAP; Index++) {
+ if (CapInfo->CapFiles[Index][0] != '\0') {
+ continue;
+ }
+ //
+ // Read the capsule file name
+ //
+ Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Number++, Value);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Add the file
+ //
+ strcpy (CapInfo->CapFiles[Index], Value);
+ DebugMsg (NULL, 0, 9, "Capsule component file", "the %uth file name is %s", (unsigned) Index, CapInfo->CapFiles[Index]);
+ } else {
+ break;
+ }
+ }
+
+ if (Index == 0) {
+ Warning (NULL, 0, 0, "Capsule components are not specified.", NULL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GenerateCapImage (
+ IN CHAR8 *InfFileImage,
+ IN UINTN InfFileSize,
+ IN CHAR8 *CapFileName
+ )
+/*++
+
+Routine Description:
+
+ This is the main function which will be called from application to create UEFI Capsule image.
+
+Arguments:
+
+ InfFileImage Buffer containing the INF file contents.
+ InfFileSize Size of the contents of the InfFileImage buffer.
+ CapFileName Requested name for the Cap file.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_OUT_OF_RESOURCES Could not allocate required resources.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+{
+ UINT32 CapSize;
+ UINT8 *CapBuffer;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ MEMORY_FILE InfMemoryFile;
+ UINT32 FileSize;
+ UINT32 Index;
+ FILE *fpin, *fpout;
+ EFI_STATUS Status;
+
+ if (InfFileImage != NULL) {
+ //
+ // Initialize file structures
+ //
+ InfMemoryFile.FileImage = InfFileImage;
+ InfMemoryFile.CurrentFilePointer = InfFileImage;
+ InfMemoryFile.Eof = InfFileImage + InfFileSize;
+
+ //
+ // Parse the Cap inf file for header information
+ //
+ Status = ParseCapInf (&InfMemoryFile, &mCapDataInfo);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+ }
+
+ if (mCapDataInfo.HeaderSize == 0) {
+ //
+ // make header size align 16 bytes.
+ //
+ mCapDataInfo.HeaderSize = sizeof (EFI_CAPSULE_HEADER);
+ mCapDataInfo.HeaderSize = (mCapDataInfo.HeaderSize + 0xF) & ~0xF;
+ }
+
+ if (mCapDataInfo.HeaderSize < sizeof (EFI_CAPSULE_HEADER)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "The specified HeaderSize cannot be less than the size of EFI_CAPSULE_HEADER.");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (CapFileName == NULL && mCapDataInfo.CapName[0] != '\0') {
+ CapFileName = mCapDataInfo.CapName;
+ }
+
+ if (CapFileName == NULL) {
+ Error (NULL, 0, 2001, "Missing required argument", "Output Capsule file name");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Set Default Capsule Guid value
+ //
+ if (CompareGuid (&mCapDataInfo.CapGuid, &mZeroGuid) == 0) {
+ memcpy (&mCapDataInfo.CapGuid, &mDefaultCapsuleGuid, sizeof (EFI_GUID));
+ }
+ //
+ // Calculate the size of capsule image.
+ //
+ Index = 0;
+ FileSize = 0;
+ CapSize = mCapDataInfo.HeaderSize;
+ while (mCapDataInfo.CapFiles [Index][0] != '\0') {
+ fpin = fopen (LongFilePath (mCapDataInfo.CapFiles[Index]), "rb");
+ if (fpin == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mCapDataInfo.CapFiles[Index]);
+ return EFI_ABORTED;
+ }
+ FileSize = _filelength (fileno (fpin));
+ CapSize += FileSize;
+ fclose (fpin);
+ Index ++;
+ }
+
+ //
+ // Allocate buffer for capsule image.
+ //
+ CapBuffer = (UINT8 *) malloc (CapSize);
+ if (CapBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated for creating the capsule.");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the capsule header to zero
+ //
+ memset (CapBuffer, 0, mCapDataInfo.HeaderSize);
+
+ //
+ // create capsule header and get capsule body
+ //
+ CapsuleHeader = (EFI_CAPSULE_HEADER *) CapBuffer;
+ memcpy (&CapsuleHeader->CapsuleGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));
+ CapsuleHeader->HeaderSize = mCapDataInfo.HeaderSize;
+ CapsuleHeader->Flags = mCapDataInfo.Flags;
+ CapsuleHeader->CapsuleImageSize = CapSize;
+
+ Index = 0;
+ FileSize = 0;
+ CapSize = CapsuleHeader->HeaderSize;
+ while (mCapDataInfo.CapFiles [Index][0] != '\0') {
+ fpin = fopen (LongFilePath (mCapDataInfo.CapFiles[Index]), "rb");
+ if (fpin == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mCapDataInfo.CapFiles[Index]);
+ free (CapBuffer);
+ return EFI_ABORTED;
+ }
+ FileSize = _filelength (fileno (fpin));
+ fread (CapBuffer + CapSize, 1, FileSize, fpin);
+ fclose (fpin);
+ Index ++;
+ CapSize += FileSize;
+ }
+
+ //
+ // write capsule data into the output file
+ //
+ fpout = fopen (LongFilePath (CapFileName), "wb");
+ if (fpout == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", CapFileName);
+ free (CapBuffer);
+ return EFI_ABORTED;
+ }
+
+ fwrite (CapBuffer, 1, CapSize, fpout);
+ fclose (fpout);
+ free (CapBuffer);
+
+ VerboseMsg ("The size of the generated capsule image is %u bytes", (unsigned) CapSize);
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.h
new file mode 100644
index 00000000..acbebef5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/GenFvInternalLib.h
@@ -0,0 +1,402 @@
+/** @file
+This file contains describes the public interfaces to the GenFvImage Library.
+The basic purpose of the library is to create Firmware Volume images.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_GEN_FV_INTERNAL_LIB_H
+#define _EFI_GEN_FV_INTERNAL_LIB_H
+
+//
+// Include files
+//
+#include <stdlib.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/UefiCapsule.h>
+
+#include <Common/PiFirmwareFile.h>
+#include <Common/PiFirmwareVolume.h>
+#include <Guid/PiFirmwareFileSystem.h>
+#include <IndustryStandard/PeImage.h>
+
+#include "CommonLib.h"
+#include "ParseInf.h"
+#include "EfiUtilityMsgs.h"
+
+//
+// Different file separator for Linux and Windows
+//
+#define FILE_SEP_CHAR '/'
+
+//
+// The maximum number of Pad file guid entries.
+//
+#define MAX_NUMBER_OF_PAD_FILE_GUIDS 1024
+
+//
+// The maximum number of block map entries supported by the library
+//
+#define MAX_NUMBER_OF_FV_BLOCKS 100
+
+//
+// The maximum number of files in the FV supported by the library
+//
+#define MAX_NUMBER_OF_FILES_IN_FV 1000
+#define MAX_NUMBER_OF_FILES_IN_CAP 1000
+#define EFI_FFS_FILE_HEADER_ALIGNMENT 8
+//
+// INF file strings
+//
+#define OPTIONS_SECTION_STRING "[options]"
+#define ATTRIBUTES_SECTION_STRING "[attributes]"
+#define FILES_SECTION_STRING "[files]"
+#define FV_BASE_ADDRESS_STRING "[FV_BASE_ADDRESS]"
+
+//
+// Options section
+//
+#define EFI_FV_BASE_ADDRESS_STRING "EFI_BASE_ADDRESS"
+#define EFI_FV_FILE_NAME_STRING "EFI_FILE_NAME"
+#define EFI_NUM_BLOCKS_STRING "EFI_NUM_BLOCKS"
+#define EFI_BLOCK_SIZE_STRING "EFI_BLOCK_SIZE"
+#define EFI_GUID_STRING "EFI_GUID"
+#define EFI_FV_FILESYSTEMGUID_STRING "EFI_FV_GUID"
+#define EFI_FV_NAMEGUID_STRING "EFI_FVNAME_GUID"
+#define EFI_CAPSULE_GUID_STRING "EFI_CAPSULE_GUID"
+#define EFI_CAPSULE_HEADER_SIZE_STRING "EFI_CAPSULE_HEADER_SIZE"
+#define EFI_CAPSULE_FLAGS_STRING "EFI_CAPSULE_FLAGS"
+#define EFI_OEM_CAPSULE_FLAGS_STRING "EFI_OEM_CAPSULE_FLAGS"
+#define EFI_CAPSULE_VERSION_STRING "EFI_CAPSULE_VERSION"
+
+#define EFI_FV_TOTAL_SIZE_STRING "EFI_FV_TOTAL_SIZE"
+#define EFI_FV_TAKEN_SIZE_STRING "EFI_FV_TAKEN_SIZE"
+#define EFI_FV_SPACE_SIZE_STRING "EFI_FV_SPACE_SIZE"
+
+//
+// Attributes section
+//
+#define EFI_FVB2_READ_DISABLED_CAP_STRING "EFI_READ_DISABLED_CAP"
+#define EFI_FVB2_READ_ENABLED_CAP_STRING "EFI_READ_ENABLED_CAP"
+#define EFI_FVB2_READ_STATUS_STRING "EFI_READ_STATUS"
+
+#define EFI_FVB2_WRITE_DISABLED_CAP_STRING "EFI_WRITE_DISABLED_CAP"
+#define EFI_FVB2_WRITE_ENABLED_CAP_STRING "EFI_WRITE_ENABLED_CAP"
+#define EFI_FVB2_WRITE_STATUS_STRING "EFI_WRITE_STATUS"
+
+#define EFI_FVB2_LOCK_CAP_STRING "EFI_LOCK_CAP"
+#define EFI_FVB2_LOCK_STATUS_STRING "EFI_LOCK_STATUS"
+
+#define EFI_FVB2_STICKY_WRITE_STRING "EFI_STICKY_WRITE"
+#define EFI_FVB2_MEMORY_MAPPED_STRING "EFI_MEMORY_MAPPED"
+#define EFI_FVB2_ERASE_POLARITY_STRING "EFI_ERASE_POLARITY"
+
+#define EFI_FVB2_READ_LOCK_CAP_STRING "EFI_READ_LOCK_CAP"
+#define EFI_FVB2_READ_LOCK_STATUS_STRING "EFI_READ_LOCK_STATUS"
+#define EFI_FVB2_WRITE_LOCK_CAP_STRING "EFI_WRITE_LOCK_CAP"
+#define EFI_FVB2_WRITE_LOCK_STATUS_STRING "EFI_WRITE_LOCK_STATUS"
+
+#define EFI_FVB2_ALIGNMENT_1_STRING "EFI_FVB2_ALIGNMENT_1"
+#define EFI_FVB2_ALIGNMENT_2_STRING "EFI_FVB2_ALIGNMENT_2"
+#define EFI_FVB2_ALIGNMENT_4_STRING "EFI_FVB2_ALIGNMENT_4"
+#define EFI_FVB2_ALIGNMENT_8_STRING "EFI_FVB2_ALIGNMENT_8"
+#define EFI_FVB2_ALIGNMENT_16_STRING "EFI_FVB2_ALIGNMENT_16"
+#define EFI_FVB2_ALIGNMENT_32_STRING "EFI_FVB2_ALIGNMENT_32"
+#define EFI_FVB2_ALIGNMENT_64_STRING "EFI_FVB2_ALIGNMENT_64"
+#define EFI_FVB2_ALIGNMENT_128_STRING "EFI_FVB2_ALIGNMENT_128"
+#define EFI_FVB2_ALIGNMENT_256_STRING "EFI_FVB2_ALIGNMENT_256"
+#define EFI_FVB2_ALIGNMENT_512_STRING "EFI_FVB2_ALIGNMENT_512"
+#define EFI_FVB2_ALIGNMENT_1K_STRING "EFI_FVB2_ALIGNMENT_1K"
+#define EFI_FVB2_ALIGNMENT_2K_STRING "EFI_FVB2_ALIGNMENT_2K"
+#define EFI_FVB2_ALIGNMENT_4K_STRING "EFI_FVB2_ALIGNMENT_4K"
+#define EFI_FVB2_ALIGNMENT_8K_STRING "EFI_FVB2_ALIGNMENT_8K"
+#define EFI_FVB2_ALIGNMENT_16K_STRING "EFI_FVB2_ALIGNMENT_16K"
+#define EFI_FVB2_ALIGNMENT_32K_STRING "EFI_FVB2_ALIGNMENT_32K"
+#define EFI_FVB2_ALIGNMENT_64K_STRING "EFI_FVB2_ALIGNMENT_64K"
+#define EFI_FVB2_ALIGNMENT_128K_STRING "EFI_FVB2_ALIGNMENT_128K"
+#define EFI_FVB2_ALIGNMENT_256K_STRING "EFI_FVB2_ALIGNMENT_256K"
+#define EFI_FVB2_ALIGNMENT_512K_STRING "EFI_FVB2_ALIGNMENT_512K"
+#define EFI_FVB2_ALIGNMENT_1M_STRING "EFI_FVB2_ALIGNMENT_1M"
+#define EFI_FVB2_ALIGNMENT_2M_STRING "EFI_FVB2_ALIGNMENT_2M"
+#define EFI_FVB2_ALIGNMENT_4M_STRING "EFI_FVB2_ALIGNMENT_4M"
+#define EFI_FVB2_ALIGNMENT_8M_STRING "EFI_FVB2_ALIGNMENT_8M"
+#define EFI_FVB2_ALIGNMENT_16M_STRING "EFI_FVB2_ALIGNMENT_16M"
+#define EFI_FVB2_ALIGNMENT_32M_STRING "EFI_FVB2_ALIGNMENT_32M"
+#define EFI_FVB2_ALIGNMENT_64M_STRING "EFI_FVB2_ALIGNMENT_64M"
+#define EFI_FVB2_ALIGNMENT_128M_STRING "EFI_FVB2_ALIGNMENT_128M"
+#define EFI_FVB2_ALIGNMENT_256M_STRING "EFI_FVB2_ALIGNMENT_256M"
+#define EFI_FVB2_ALIGNMENT_512M_STRING "EFI_FVB2_ALIGNMENT_512M"
+#define EFI_FVB2_ALIGNMENT_1G_STRING "EFI_FVB2_ALIGNMENT_1G"
+#define EFI_FVB2_ALIGNMENT_2G_STRING "EFI_FVB2_ALIGNMENT_2G"
+
+#define EFI_FV_WEAK_ALIGNMENT_STRING "EFI_WEAK_ALIGNMENT"
+
+//
+// File sections
+//
+#define EFI_FILE_NAME_STRING "EFI_FILE_NAME"
+
+#define ONE_STRING "1"
+#define ZERO_STRING "0"
+#define TRUE_STRING "TRUE"
+#define FALSE_STRING "FALSE"
+#define NULL_STRING "NULL"
+
+//
+//
+//
+#define EFI_FV_EXT_HEADER_FILE_NAME "EFI_FV_EXT_HEADER_FILE_NAME"
+
+
+//
+// VTF (Firmware Volume Top File) signatures
+//
+#define IA32_X64_VTF_SIGNATURE_OFFSET 0x14
+#define IA32_X64_VTF0_SIGNATURE SIGNATURE_32('V','T','F',0)
+
+//
+// Defines to calculate the offset for PEI CORE entry points
+//
+#define IA32_PEI_CORE_ENTRY_OFFSET 0x20
+
+//
+// Defines to calculate the offset for IA32 SEC CORE entry point
+//
+#define IA32_SEC_CORE_ENTRY_OFFSET 0xD
+
+//
+// Symbol file definitions, current max size if 512K
+//
+#define SYMBOL_FILE_SIZE 0x80000
+
+#define FV_IMAGES_TOP_ADDRESS 0x100000000ULL
+
+//
+// Following definition is used for FIT in IPF
+//
+#define COMP_TYPE_FIT_PEICORE 0x10
+#define COMP_TYPE_FIT_UNUSED 0x7F
+
+#define FIT_TYPE_MASK 0x7F
+#define CHECKSUM_BIT_MASK 0x80
+
+//
+// Private data types
+//
+//
+// Component information
+//
+typedef struct {
+ UINTN Size;
+ CHAR8 ComponentName[MAX_LONG_FILE_PATH];
+} COMPONENT_INFO;
+
+//
+// FV and capsule information holder
+//
+typedef struct {
+ BOOLEAN BaseAddressSet;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_GUID FvFileSystemGuid;
+ BOOLEAN FvFileSystemGuidSet;
+ EFI_GUID FvNameGuid;
+ BOOLEAN FvNameGuidSet;
+ CHAR8 FvExtHeaderFile[MAX_LONG_FILE_PATH];
+ UINTN Size;
+ EFI_FVB_ATTRIBUTES_2 FvAttributes;
+ CHAR8 FvName[MAX_LONG_FILE_PATH];
+ EFI_FV_BLOCK_MAP_ENTRY FvBlocks[MAX_NUMBER_OF_FV_BLOCKS];
+ CHAR8 FvFiles[MAX_NUMBER_OF_FILES_IN_FV][MAX_LONG_FILE_PATH];
+ UINT32 SizeofFvFiles[MAX_NUMBER_OF_FILES_IN_FV];
+ BOOLEAN IsPiFvImage;
+ INT8 ForceRebase;
+} FV_INFO;
+
+typedef struct {
+ EFI_GUID CapGuid;
+ UINT32 HeaderSize;
+ UINT32 Flags;
+ CHAR8 CapName[MAX_LONG_FILE_PATH];
+ CHAR8 CapFiles[MAX_NUMBER_OF_FILES_IN_CAP][MAX_LONG_FILE_PATH];
+} CAP_INFO;
+
+#pragma pack(1)
+
+typedef struct {
+ UINT64 CompAddress;
+ UINT32 CompSize;
+ UINT16 CompVersion;
+ UINT8 CvAndType;
+ UINT8 CheckSum;
+} FIT_TABLE;
+
+#pragma pack()
+
+#define FV_DEFAULT_ATTRIBUTE 0x0004FEFF
+extern FV_INFO mFvDataInfo;
+extern CAP_INFO mCapDataInfo;
+extern EFI_GUID mEfiFirmwareFileSystem2Guid;
+extern EFI_GUID mEfiFirmwareFileSystem3Guid;
+extern UINT32 mFvTotalSize;
+extern UINT32 mFvTakenSize;
+
+extern EFI_PHYSICAL_ADDRESS mFvBaseAddress[];
+extern UINT32 mFvBaseAddressNumber;
+//
+// Local function prototypes
+//
+EFI_STATUS
+ParseFvInf (
+ IN MEMORY_FILE *InfFile,
+ OUT FV_INFO *FvInfo
+ )
+;
+
+EFI_STATUS
+UpdatePeiCoreEntryInFit (
+ IN FIT_TABLE *FitTablePtr,
+ IN UINT64 PeiCorePhysicalAddress
+ )
+/*++
+
+Routine Description:
+
+ This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from
+ Sec to Pei Core
+
+Arguments:
+
+ FitTablePtr - The pointer of FIT_TABLE.
+ PeiCorePhysicalAddress - The address of Pei Core entry.
+
+Returns:
+
+ EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully.
+ EFI_NOT_FOUND - Not found the PEI_CORE FIT entry.
+
+--*/
+;
+
+VOID
+UpdateFitCheckSum (
+ IN FIT_TABLE *FitTablePtr
+ )
+/*++
+
+Routine Description:
+
+ This function is used to update the checksum for FIT.
+
+
+Arguments:
+
+ FitTablePtr - The pointer of FIT_TABLE.
+
+Returns:
+
+ None.
+
+--*/
+;
+
+EFI_STATUS
+GetPe32Info (
+ IN UINT8 *Pe32,
+ OUT UINT32 *EntryPoint,
+ OUT UINT32 *BaseOfCode,
+ OUT UINT16 *MachineType
+ );
+
+EFI_STATUS
+ParseCapInf (
+ IN MEMORY_FILE *InfFile,
+ OUT CAP_INFO *CapInfo
+ );
+
+EFI_STATUS
+FindApResetVectorPosition (
+ IN MEMORY_FILE *FvImage,
+ OUT UINT8 **Pointer
+ );
+
+EFI_STATUS
+CalculateFvSize (
+ FV_INFO *FvInfoPtr
+ );
+
+EFI_STATUS
+FfsRebase (
+ IN OUT FV_INFO *FvInfo,
+ IN CHAR8 *FileName,
+ IN OUT EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINTN XipOffset,
+ IN FILE *FvMapFile
+ );
+
+//
+// Exported function prototypes
+//
+EFI_STATUS
+GenerateCapImage (
+ IN CHAR8 *InfFileImage,
+ IN UINTN InfFileSize,
+ IN CHAR8 *CapFileName
+ )
+/*++
+
+Routine Description:
+
+ This is the main function which will be called from application to
+ generate UEFI Capsule image.
+
+Arguments:
+
+ InfFileImage Buffer containing the INF file contents.
+ InfFileSize Size of the contents of the InfFileImage buffer.
+ CapFileName Requested name for the Cap file.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_OUT_OF_RESOURCES Could not allocate required resources.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+;
+
+EFI_STATUS
+GenerateFvImage (
+ IN CHAR8 *InfFileImage,
+ IN UINTN InfFileSize,
+ IN CHAR8 *FvFileName,
+ IN CHAR8 *MapFileName
+ )
+/*++
+
+Routine Description:
+
+ This is the main function which will be called from application to
+ generate Firmware Image conforms to PI spec.
+
+Arguments:
+
+ InfFileImage Buffer containing the INF file contents.
+ InfFileSize Size of the contents of the InfFileImage buffer.
+ FvFileName Requested name for the FV file.
+ MapFileName Fv map file to log fv driver information.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_OUT_OF_RESOURCES Could not allocate required resources.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+
+--*/
+;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile
new file mode 100644
index 00000000..e4550afd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile
@@ -0,0 +1,16 @@
+## @file
+# Windows makefile for 'GenFv' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenFv
+
+LIBS = $(LIB_PATH)\Common.lib RpcRT4.lib
+
+OBJECTS = GenFv.obj GenFvInternalLib.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile.kmk
new file mode 100644
index 00000000..1da959c6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFv/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI GenFv build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += GenFv
+GenFv_TEMPLATE = VBoxEfiBldProg
+GenFv_SOURCES = GenFv.c GenFvInternalLib.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.c
new file mode 100644
index 00000000..f93eeb47
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.c
@@ -0,0 +1,1177 @@
+/** @file
+Elf32 Convert solution
+
+Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WinNtInclude.h"
+
+#ifndef __GNUC__
+#include <windows.h>
+#include <io.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h>
+
+#include "PeCoffLib.h"
+#include "EfiUtilityMsgs.h"
+
+#include "GenFw.h"
+#include "ElfConvert.h"
+#include "Elf32Convert.h"
+
+STATIC
+VOID
+ScanSections32 (
+ VOID
+ );
+
+STATIC
+BOOLEAN
+WriteSections32 (
+ SECTION_FILTER_TYPES FilterType
+ );
+
+STATIC
+VOID
+WriteRelocations32 (
+ VOID
+ );
+
+STATIC
+VOID
+WriteDebug32 (
+ VOID
+ );
+
+STATIC
+VOID
+SetImageSize32 (
+ VOID
+ );
+
+STATIC
+VOID
+CleanUp32 (
+ VOID
+ );
+
+//
+// Rename ELF32 structures to common names to help when porting to ELF64.
+//
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Phdr Elf_Phdr;
+typedef Elf32_Dyn Elf_Dyn;
+#define ELFCLASS ELFCLASS32
+#define ELF_R_TYPE(r) ELF32_R_TYPE(r)
+#define ELF_R_SYM(r) ELF32_R_SYM(r)
+
+//
+// Well known ELF structures.
+//
+STATIC Elf_Ehdr *mEhdr;
+STATIC Elf_Shdr *mShdrBase;
+STATIC Elf_Phdr *mPhdrBase;
+
+//
+// Coff information
+//
+STATIC UINT32 mCoffAlignment = 0x20;
+
+//
+// PE section alignment.
+//
+STATIC const UINT16 mCoffNbrSections = 4;
+
+//
+// ELF sections to offset in Coff file.
+//
+STATIC UINT32 *mCoffSectionsOffset = NULL;
+
+//
+// Offsets in COFF file
+//
+STATIC UINT32 mNtHdrOffset;
+STATIC UINT32 mTextOffset;
+STATIC UINT32 mDataOffset;
+STATIC UINT32 mHiiRsrcOffset;
+STATIC UINT32 mRelocOffset;
+STATIC UINT32 mDebugOffset;
+
+//
+// Initialization Function
+//
+BOOLEAN
+InitializeElf32 (
+ UINT8 *FileBuffer,
+ ELF_FUNCTION_TABLE *ElfFunctions
+ )
+{
+ //
+ // Initialize data pointer and structures.
+ //
+ mEhdr = (Elf_Ehdr*) FileBuffer;
+
+ //
+ // Check the ELF32 specific header information.
+ //
+ if (mEhdr->e_ident[EI_CLASS] != ELFCLASS32) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS32");
+ return FALSE;
+ }
+ if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");
+ return FALSE;
+ }
+ if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
+ return FALSE;
+ }
+ if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM) || (mEhdr->e_machine == EM_RISCV))) {
+ Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf32 machine.");
+ }
+ if (mEhdr->e_version != EV_CURRENT) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT);
+ return FALSE;
+ }
+
+ //
+ // Update section header pointers
+ //
+ mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff);
+ mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff);
+
+ //
+ // Create COFF Section offset buffer and zero.
+ //
+ mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32));
+ if (mCoffSectionsOffset == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return FALSE;
+ }
+ memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32));
+
+ //
+ // Fill in function pointers.
+ //
+ ElfFunctions->ScanSections = ScanSections32;
+ ElfFunctions->WriteSections = WriteSections32;
+ ElfFunctions->WriteRelocations = WriteRelocations32;
+ ElfFunctions->WriteDebug = WriteDebug32;
+ ElfFunctions->SetImageSize = SetImageSize32;
+ ElfFunctions->CleanUp = CleanUp32;
+
+ return TRUE;
+}
+
+
+//
+// Header by Index functions
+//
+STATIC
+Elf_Shdr*
+GetShdrByIndex (
+ UINT32 Num
+ )
+{
+ if (Num >= mEhdr->e_shnum) {
+ Error (NULL, 0, 3000, "Invalid", "GetShdrByIndex: Index %u is too high.", Num);
+ exit(EXIT_FAILURE);
+ }
+
+ return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize);
+}
+
+STATIC
+Elf_Phdr*
+GetPhdrByIndex (
+ UINT32 num
+ )
+{
+ if (num >= mEhdr->e_phnum) {
+ Error (NULL, 0, 3000, "Invalid", "GetPhdrByIndex: Index %u is too high.", num);
+ exit(EXIT_FAILURE);
+ }
+
+ return (Elf_Phdr *)((UINT8*)mPhdrBase + num * mEhdr->e_phentsize);
+}
+
+STATIC
+UINT32
+CoffAlign (
+ UINT32 Offset
+ )
+{
+ return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1);
+}
+
+STATIC
+UINT32
+DebugRvaAlign (
+ UINT32 Offset
+ )
+{
+ return (Offset + 3) & ~3;
+}
+
+//
+// filter functions
+//
+STATIC
+BOOLEAN
+IsTextShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC);
+}
+
+STATIC
+BOOLEAN
+IsHiiRsrcShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);
+
+ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0);
+}
+
+STATIC
+BOOLEAN
+IsDataShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ if (IsHiiRsrcShdr(Shdr)) {
+ return FALSE;
+ }
+ return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
+}
+
+STATIC
+BOOLEAN
+IsStrtabShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);
+
+ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_STRTAB_SECTION_NAME) == 0);
+}
+
+STATIC
+Elf_Shdr *
+FindStrtabShdr (
+ VOID
+ )
+{
+ UINT32 i;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsStrtabShdr(shdr)) {
+ return shdr;
+ }
+ }
+ return NULL;
+}
+
+STATIC
+const UINT8 *
+GetSymName (
+ Elf_Sym *Sym
+ )
+{
+ Elf_Shdr *StrtabShdr;
+ UINT8 *StrtabContents;
+ BOOLEAN foundEnd;
+ UINT32 i;
+
+ if (Sym->st_name == 0) {
+ return NULL;
+ }
+
+ StrtabShdr = FindStrtabShdr();
+ if (StrtabShdr == NULL) {
+ return NULL;
+ }
+
+ assert(Sym->st_name < StrtabShdr->sh_size);
+
+ StrtabContents = (UINT8*)mEhdr + StrtabShdr->sh_offset;
+
+ foundEnd = FALSE;
+ for (i = Sym->st_name; (i < StrtabShdr->sh_size) && !foundEnd; i++) {
+ foundEnd = (BOOLEAN)(StrtabContents[i] == 0);
+ }
+ assert(foundEnd);
+
+ return StrtabContents + Sym->st_name;
+}
+
+//
+// Elf functions interface implementation
+//
+
+STATIC
+VOID
+ScanSections32 (
+ VOID
+ )
+{
+ UINT32 i;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+ UINT32 CoffEntry;
+ UINT32 SectionCount;
+ BOOLEAN FoundSection;
+
+ CoffEntry = 0;
+ mCoffOffset = 0;
+
+ //
+ // Coff file start with a DOS header.
+ //
+ mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;
+ mNtHdrOffset = mCoffOffset;
+ switch (mEhdr->e_machine) {
+ case EM_386:
+ case EM_ARM:
+ mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);
+ break;
+ default:
+ VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine);
+ mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);
+ break;
+ }
+
+ mTableOffset = mCoffOffset;
+ mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);
+
+ //
+ // Set mCoffAlignment to the maximum alignment of the input sections
+ // we care about
+ //
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (shdr->sh_addralign <= mCoffAlignment) {
+ continue;
+ }
+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {
+ mCoffAlignment = (UINT32)shdr->sh_addralign;
+ }
+ }
+
+ //
+ // Check if mCoffAlignment is larger than MAX_COFF_ALIGNMENT
+ //
+ if (mCoffAlignment > MAX_COFF_ALIGNMENT) {
+ Error (NULL, 0, 3000, "Invalid", "Section alignment is larger than MAX_COFF_ALIGNMENT.");
+ assert (FALSE);
+ }
+
+ //
+ // Move the PE/COFF header right before the first section. This will help us
+ // save space when converting to TE.
+ //
+ if (mCoffAlignment > mCoffOffset) {
+ mNtHdrOffset += mCoffAlignment - mCoffOffset;
+ mTableOffset += mCoffAlignment - mCoffOffset;
+ mCoffOffset = mCoffAlignment;
+ }
+
+ //
+ // First text sections.
+ //
+ mCoffOffset = CoffAlign(mCoffOffset);
+ mTextOffset = mCoffOffset;
+ FoundSection = FALSE;
+ SectionCount = 0;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsTextShdr(shdr)) {
+ if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {
+ // the alignment field is valid
+ if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
+ // if the section address is aligned we must align PE/COFF
+ mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
+ }
+ }
+
+ /* Relocate entry. */
+ if ((mEhdr->e_entry >= shdr->sh_addr) &&
+ (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) {
+ CoffEntry = mCoffOffset + mEhdr->e_entry - shdr->sh_addr;
+ }
+
+ //
+ // Set mTextOffset with the offset of the first '.text' section
+ //
+ if (!FoundSection) {
+ mTextOffset = mCoffOffset;
+ FoundSection = TRUE;
+ }
+
+ mCoffSectionsOffset[i] = mCoffOffset;
+ mCoffOffset += shdr->sh_size;
+ SectionCount ++;
+ }
+ }
+
+ if (!FoundSection) {
+ Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section.");
+ assert (FALSE);
+ }
+
+ mDebugOffset = DebugRvaAlign(mCoffOffset);
+ mCoffOffset = CoffAlign(mCoffOffset);
+
+ if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {
+ Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName);
+ }
+
+ //
+ // Then data sections.
+ //
+ mDataOffset = mCoffOffset;
+ FoundSection = FALSE;
+ SectionCount = 0;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsDataShdr(shdr)) {
+ if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {
+ // the alignment field is valid
+ if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
+ // if the section address is aligned we must align PE/COFF
+ mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
+ }
+ }
+
+ //
+ // Set mDataOffset with the offset of the first '.data' section
+ //
+ if (!FoundSection) {
+ mDataOffset = mCoffOffset;
+ FoundSection = TRUE;
+ }
+
+ mCoffSectionsOffset[i] = mCoffOffset;
+ mCoffOffset += shdr->sh_size;
+ SectionCount ++;
+ }
+ }
+
+ if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {
+ Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);
+ }
+
+ //
+ // Make room for .debug data in .data (or .text if .data is empty) instead of
+ // putting it in a section of its own. This is explicitly allowed by the
+ // PE/COFF spec, and prevents bloat in the binary when using large values for
+ // section alignment.
+ //
+ if (SectionCount > 0) {
+ mDebugOffset = DebugRvaAlign(mCoffOffset);
+ }
+ mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +
+ sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +
+ strlen(mInImageName) + 1;
+
+ mCoffOffset = CoffAlign(mCoffOffset);
+ if (SectionCount == 0) {
+ mDataOffset = mCoffOffset;
+ }
+
+ //
+ // The HII resource sections.
+ //
+ mHiiRsrcOffset = mCoffOffset;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsHiiRsrcShdr(shdr)) {
+ if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {
+ // the alignment field is valid
+ if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
+ // if the section address is aligned we must align PE/COFF
+ mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
+ }
+ }
+ if (shdr->sh_size != 0) {
+ mHiiRsrcOffset = mCoffOffset;
+ mCoffSectionsOffset[i] = mCoffOffset;
+ mCoffOffset += shdr->sh_size;
+ mCoffOffset = CoffAlign(mCoffOffset);
+ SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset);
+ }
+ break;
+ }
+ }
+
+ mRelocOffset = mCoffOffset;
+
+ //
+ // Allocate base Coff file. Will be expanded later for relocations.
+ //
+ mCoffFile = (UINT8 *)malloc(mCoffOffset);
+ if (mCoffFile == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ }
+ assert (mCoffFile != NULL);
+ memset(mCoffFile, 0, mCoffOffset);
+
+ //
+ // Fill headers.
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile;
+ DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;
+ DosHdr->e_lfanew = mNtHdrOffset;
+
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset);
+
+ NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE;
+
+ switch (mEhdr->e_machine) {
+ case EM_386:
+ NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;
+ NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EM_ARM:
+ NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT;
+ NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ default:
+ VerboseMsg ("%s unknown e_machine type %hu. Assume IA-32", mInImageName, mEhdr->e_machine);
+ NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;
+ NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ }
+
+ NtHdr->Pe32.FileHeader.NumberOfSections = mCoffNbrSections;
+ NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL);
+ mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp;
+ NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0;
+ NtHdr->Pe32.FileHeader.NumberOfSymbols = 0;
+ NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader);
+ NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE
+ | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED
+ | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED
+ | EFI_IMAGE_FILE_32BIT_MACHINE;
+
+ NtHdr->Pe32.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;
+ NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;
+ NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0;
+ NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry;
+
+ NtHdr->Pe32.OptionalHeader.BaseOfCode = mTextOffset;
+
+ NtHdr->Pe32.OptionalHeader.BaseOfData = mDataOffset;
+ NtHdr->Pe32.OptionalHeader.ImageBase = 0;
+ NtHdr->Pe32.OptionalHeader.SectionAlignment = mCoffAlignment;
+ NtHdr->Pe32.OptionalHeader.FileAlignment = mCoffAlignment;
+ NtHdr->Pe32.OptionalHeader.SizeOfImage = 0;
+
+ NtHdr->Pe32.OptionalHeader.SizeOfHeaders = mTextOffset;
+ NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
+
+ //
+ // Section headers.
+ //
+ if ((mDataOffset - mTextOffset) > 0) {
+ CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset,
+ EFI_IMAGE_SCN_CNT_CODE
+ | EFI_IMAGE_SCN_MEM_EXECUTE
+ | EFI_IMAGE_SCN_MEM_READ);
+ } else {
+ // Don't make a section of size 0.
+ NtHdr->Pe32.FileHeader.NumberOfSections--;
+ }
+
+ if ((mHiiRsrcOffset - mDataOffset) > 0) {
+ CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_WRITE
+ | EFI_IMAGE_SCN_MEM_READ);
+ } else {
+ // Don't make a section of size 0.
+ NtHdr->Pe32.FileHeader.NumberOfSections--;
+ }
+
+ if ((mRelocOffset - mHiiRsrcOffset) > 0) {
+ CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_READ);
+
+ NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset;
+ NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset;
+ } else {
+ // Don't make a section of size 0.
+ NtHdr->Pe32.FileHeader.NumberOfSections--;
+ }
+
+}
+
+STATIC
+BOOLEAN
+WriteSections32 (
+ SECTION_FILTER_TYPES FilterType
+ )
+{
+ UINT32 Idx;
+ Elf_Shdr *SecShdr;
+ UINT32 SecOffset;
+ BOOLEAN (*Filter)(Elf_Shdr *);
+
+ //
+ // Initialize filter pointer
+ //
+ switch (FilterType) {
+ case SECTION_TEXT:
+ Filter = IsTextShdr;
+ break;
+ case SECTION_HII:
+ Filter = IsHiiRsrcShdr;
+ break;
+ case SECTION_DATA:
+ Filter = IsDataShdr;
+ break;
+ default:
+ return FALSE;
+ }
+
+ //
+ // First: copy sections.
+ //
+ for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {
+ Elf_Shdr *Shdr = GetShdrByIndex(Idx);
+ if ((*Filter)(Shdr)) {
+ switch (Shdr->sh_type) {
+ case SHT_PROGBITS:
+ /* Copy. */
+ if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) {
+ return FALSE;
+ }
+ memcpy(mCoffFile + mCoffSectionsOffset[Idx],
+ (UINT8*)mEhdr + Shdr->sh_offset,
+ Shdr->sh_size);
+ break;
+
+ case SHT_NOBITS:
+ memset(mCoffFile + mCoffSectionsOffset[Idx], 0, Shdr->sh_size);
+ break;
+
+ default:
+ //
+ // Ignore for unknown section type.
+ //
+ VerboseMsg ("%s unknown section type %x. We ignore this unknown section type.", mInImageName, (unsigned)Shdr->sh_type);
+ break;
+ }
+ }
+ }
+
+ //
+ // Second: apply relocations.
+ //
+ for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {
+ //
+ // Determine if this is a relocation section.
+ //
+ Elf_Shdr *RelShdr = GetShdrByIndex(Idx);
+ if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {
+ continue;
+ }
+
+ //
+ // Relocation section found. Now extract section information that the relocations
+ // apply to in the ELF data and the new COFF data.
+ //
+ SecShdr = GetShdrByIndex(RelShdr->sh_info);
+ SecOffset = mCoffSectionsOffset[RelShdr->sh_info];
+
+ //
+ // Only process relocations for the current filter type.
+ //
+ if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {
+ UINT32 RelOffset;
+
+ //
+ // Determine the symbol table referenced by the relocation data.
+ //
+ Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);
+ UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;
+
+ //
+ // Process all relocation entries for this section.
+ //
+ for (RelOffset = 0; RelOffset < RelShdr->sh_size; RelOffset += RelShdr->sh_entsize) {
+ //
+ // Set pointer to relocation entry
+ //
+ Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelOffset);
+
+ //
+ // Set pointer to symbol table entry associated with the relocation entry.
+ //
+ Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);
+
+ Elf_Shdr *SymShdr;
+ UINT8 *Targ;
+ UINT16 Address;
+
+ //
+ // Check section header index found in symbol table and get the section
+ // header location.
+ //
+ if (Sym->st_shndx == SHN_UNDEF
+ || Sym->st_shndx >= mEhdr->e_shnum) {
+ const UINT8 *SymName = GetSymName(Sym);
+ if (SymName == NULL) {
+ SymName = (const UINT8 *)"<unknown>";
+ }
+
+ Error (NULL, 0, 3000, "Invalid",
+ "%s: Bad definition for symbol '%s'@%#x or unsupported symbol type. "
+ "For example, absolute and undefined symbols are not supported.",
+ mInImageName, SymName, Sym->st_value);
+
+ exit(EXIT_FAILURE);
+ }
+ SymShdr = GetShdrByIndex(Sym->st_shndx);
+
+ //
+ // Convert the relocation data to a pointer into the coff file.
+ //
+ // Note:
+ // r_offset is the virtual address of the storage unit to be relocated.
+ // sh_addr is the virtual address for the base of the section.
+ //
+ Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);
+
+ //
+ // Determine how to handle each relocation type based on the machine type.
+ //
+ if (mEhdr->e_machine == EM_386) {
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_386_NONE:
+ break;
+ case R_386_32:
+ //
+ // Absolute relocation.
+ // Converts Targ from a absolute virtual address to the absolute
+ // COFF address.
+ //
+ *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr
+ + mCoffSectionsOffset[Sym->st_shndx];
+ break;
+ case R_386_PC32:
+ //
+ // Relative relocation: Symbol - Ip + Addend
+ //
+ *(UINT32 *)Targ = *(UINT32 *)Targ
+ + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)
+ - (SecOffset - SecShdr->sh_addr);
+ break;
+ default:
+ Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else if (mEhdr->e_machine == EM_ARM) {
+ switch (ELF32_R_TYPE(Rel->r_info)) {
+ case R_ARM_RBASE:
+ // No relocation - no action required
+ // break skipped
+
+ case R_ARM_PC24:
+ case R_ARM_REL32:
+ case R_ARM_XPC25:
+ case R_ARM_THM_PC22:
+ case R_ARM_THM_JUMP19:
+ case R_ARM_CALL:
+ case R_ARM_JMP24:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_PREL31:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
+ case R_ARM_THM_JMP6:
+ case R_ARM_THM_ALU_PREL_11_0:
+ case R_ARM_THM_PC12:
+ case R_ARM_REL32_NOI:
+ case R_ARM_ALU_PC_G0_NC:
+ case R_ARM_ALU_PC_G0:
+ case R_ARM_ALU_PC_G1_NC:
+ case R_ARM_ALU_PC_G1:
+ case R_ARM_ALU_PC_G2:
+ case R_ARM_LDR_PC_G1:
+ case R_ARM_LDR_PC_G2:
+ case R_ARM_LDRS_PC_G0:
+ case R_ARM_LDRS_PC_G1:
+ case R_ARM_LDRS_PC_G2:
+ case R_ARM_LDC_PC_G0:
+ case R_ARM_LDC_PC_G1:
+ case R_ARM_LDC_PC_G2:
+ case R_ARM_THM_JUMP11:
+ case R_ARM_THM_JUMP8:
+ case R_ARM_TLS_GD32:
+ case R_ARM_TLS_LDM32:
+ case R_ARM_TLS_IE32:
+ // Thease are all PC-relative relocations and don't require modification
+ // GCC does not seem to have the concept of a application that just needs to get relocated.
+ break;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ // MOVW is only lower 16-bits of the addres
+ Address = (UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
+ ThumbMovtImmediatePatch ((UINT16 *)Targ, Address);
+ break;
+
+ case R_ARM_THM_MOVT_ABS:
+ // MOVT is only upper 16-bits of the addres
+ Address = (UINT16)((Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]) >> 16);
+ ThumbMovtImmediatePatch ((UINT16 *)Targ, Address);
+ break;
+
+ case R_ARM_ABS32:
+ case R_ARM_RABS32:
+ //
+ // Absolute relocation.
+ //
+ *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteSections (): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));
+ }
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+UINTN gMovwOffset = 0;
+
+STATIC
+VOID
+WriteRelocations32 (
+ VOID
+ )
+{
+ UINT32 Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+ EFI_IMAGE_DATA_DIRECTORY *Dir;
+ BOOLEAN FoundRelocations;
+ Elf_Dyn *Dyn;
+ Elf_Rel *Rel;
+ UINTN RelElementSize;
+ UINTN RelSize;
+ UINTN RelOffset;
+ UINTN K;
+ Elf32_Phdr *DynamicSegment;
+
+ for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) {
+ Elf_Shdr *RelShdr = GetShdrByIndex(Index);
+ if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) {
+ Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info);
+ if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {
+ UINT32 RelIdx;
+
+ FoundRelocations = TRUE;
+ for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
+ Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);
+
+ if (mEhdr->e_machine == EM_386) {
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_386_NONE:
+ case R_386_PC32:
+ //
+ // No fixup entry required.
+ //
+ break;
+ case R_386_32:
+ //
+ // Creates a relative relocation entry from the absolute entry.
+ //
+ CoffAddFixup(mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr),
+ EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+ default:
+ Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else if (mEhdr->e_machine == EM_ARM) {
+ switch (ELF32_R_TYPE(Rel->r_info)) {
+ case R_ARM_RBASE:
+ // No relocation - no action required
+ // break skipped
+
+ case R_ARM_PC24:
+ case R_ARM_REL32:
+ case R_ARM_XPC25:
+ case R_ARM_THM_PC22:
+ case R_ARM_THM_JUMP19:
+ case R_ARM_CALL:
+ case R_ARM_JMP24:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_PREL31:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
+ case R_ARM_THM_JMP6:
+ case R_ARM_THM_ALU_PREL_11_0:
+ case R_ARM_THM_PC12:
+ case R_ARM_REL32_NOI:
+ case R_ARM_ALU_PC_G0_NC:
+ case R_ARM_ALU_PC_G0:
+ case R_ARM_ALU_PC_G1_NC:
+ case R_ARM_ALU_PC_G1:
+ case R_ARM_ALU_PC_G2:
+ case R_ARM_LDR_PC_G1:
+ case R_ARM_LDR_PC_G2:
+ case R_ARM_LDRS_PC_G0:
+ case R_ARM_LDRS_PC_G1:
+ case R_ARM_LDRS_PC_G2:
+ case R_ARM_LDC_PC_G0:
+ case R_ARM_LDC_PC_G1:
+ case R_ARM_LDC_PC_G2:
+ case R_ARM_THM_JUMP11:
+ case R_ARM_THM_JUMP8:
+ case R_ARM_TLS_GD32:
+ case R_ARM_TLS_LDM32:
+ case R_ARM_TLS_IE32:
+ // Thease are all PC-relative relocations and don't require modification
+ break;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ CoffAddFixup (
+ mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr),
+ EFI_IMAGE_REL_BASED_ARM_MOV32T
+ );
+
+ // PE/COFF treats MOVW/MOVT relocation as single 64-bit instruction
+ // Track this address so we can log an error for unsupported sequence of MOVW/MOVT
+ gMovwOffset = mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr);
+ break;
+
+ case R_ARM_THM_MOVT_ABS:
+ if ((gMovwOffset + 4) != (mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr))) {
+ Error (NULL, 0, 3000, "Not Supported", "PE/COFF requires MOVW+MOVT instruction sequence %x +4 != %x.", gMovwOffset, mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
+ }
+ break;
+
+ case R_ARM_ABS32:
+ case R_ARM_RABS32:
+ CoffAddFixup (
+ mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr),
+ EFI_IMAGE_REL_BASED_HIGHLOW
+ );
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteRelocations(): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));
+ }
+ } else {
+ Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);
+ }
+ }
+ }
+ }
+ }
+
+ if (!FoundRelocations && (mEhdr->e_machine == EM_ARM)) {
+ /* Try again, but look for PT_DYNAMIC instead of SHT_REL */
+
+ for (Index = 0; Index < mEhdr->e_phnum; Index++) {
+ RelElementSize = 0;
+ RelSize = 0;
+ RelOffset = 0;
+
+ DynamicSegment = GetPhdrByIndex (Index);
+
+ if (DynamicSegment->p_type == PT_DYNAMIC) {
+ Dyn = (Elf32_Dyn *) ((UINT8 *)mEhdr + DynamicSegment->p_offset);
+
+ while (Dyn->d_tag != DT_NULL) {
+ switch (Dyn->d_tag) {
+ case DT_REL:
+ RelOffset = Dyn->d_un.d_val;
+ break;
+
+ case DT_RELSZ:
+ RelSize = Dyn->d_un.d_val;
+ break;
+
+ case DT_RELENT:
+ RelElementSize = Dyn->d_un.d_val;
+ break;
+
+ default:
+ break;
+ }
+ Dyn++;
+ }
+ if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) {
+ Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName);
+ }
+
+ for (Index = 0; Index < mEhdr->e_shnum; Index++) {
+ Elf_Shdr *shdr = GetShdrByIndex(Index);
+
+ //
+ // The PT_DYNAMIC section contains DT_REL relocations whose r_offset
+ // field is relative to the base of a segment (or the entire image),
+ // and not to the base of an ELF input section as is the case for
+ // SHT_REL sections. This means that we cannot fix up such relocations
+ // unless we cross-reference ELF sections and segments, considering
+ // that the output placement recorded in mCoffSectionsOffset[] is
+ // section based, not segment based.
+ //
+ // Fortunately, there is a simple way around this: we require that the
+ // in-memory layout of the ELF and PE/COFF versions of the binary is
+ // identical. That way, r_offset will retain its validity as a PE/COFF
+ // image offset, and we can record it in the COFF fixup table
+ // unmodified.
+ //
+ if (shdr->sh_addr != mCoffSectionsOffset[Index]) {
+ Error (NULL, 0, 3000,
+ "Invalid", "%s: PT_DYNAMIC relocations require identical ELF and PE/COFF section offsets.",
+ mInImageName);
+ }
+ }
+
+ for (K = 0; K < RelSize; K += RelElementSize) {
+
+ if (DynamicSegment->p_paddr == 0) {
+ // Older versions of the ARM ELF (SWS ESPC 0003 B-02) specification define DT_REL
+ // as an offset in the dynamic segment. p_paddr is defined to be zero for ARM tools
+ Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + DynamicSegment->p_offset + RelOffset + K);
+ } else {
+ // This is how it reads in the generic ELF specification
+ Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + RelOffset + K);
+ }
+
+ switch (ELF32_R_TYPE (Rel->r_info)) {
+ case R_ARM_RBASE:
+ break;
+
+ case R_ARM_RABS32:
+ CoffAddFixup (Rel->r_offset, EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unknown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info));
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ //
+ // Pad by adding empty entries.
+ //
+ while (mCoffOffset & (mCoffAlignment - 1)) {
+ CoffAddFixupEntry(0);
+ }
+
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
+ Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ Dir->Size = mCoffOffset - mRelocOffset;
+ if (Dir->Size == 0) {
+ // If no relocations, null out the directory entry and don't add the .reloc section
+ Dir->VirtualAddress = 0;
+ NtHdr->Pe32.FileHeader.NumberOfSections--;
+ } else {
+ Dir->VirtualAddress = mRelocOffset;
+ CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_DISCARDABLE
+ | EFI_IMAGE_SCN_MEM_READ);
+ }
+
+}
+
+STATIC
+VOID
+WriteDebug32 (
+ VOID
+ )
+{
+ UINT32 Len;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+ EFI_IMAGE_DATA_DIRECTORY *DataDir;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;
+ EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;
+
+ Len = strlen(mInImageName) + 1;
+
+ Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);
+ Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;
+ Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;
+ Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+
+ Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);
+ Nb10->Signature = CODEVIEW_SIGNATURE_NB10;
+ strcpy ((char *)(Nb10 + 1), mInImageName);
+
+
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
+ DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ DataDir->VirtualAddress = mDebugOffset;
+ DataDir->Size = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+}
+
+STATIC
+VOID
+SetImageSize32 (
+ VOID
+ )
+{
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+
+ //
+ // Set image size
+ //
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
+ NtHdr->Pe32.OptionalHeader.SizeOfImage = mCoffOffset;
+}
+
+STATIC
+VOID
+CleanUp32 (
+ VOID
+ )
+{
+ if (mCoffSectionsOffset != NULL) {
+ free (mCoffSectionsOffset);
+ }
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.h
new file mode 100644
index 00000000..d1b15123
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf32Convert.h
@@ -0,0 +1,19 @@
+/** @file
+Header file for Elf32 Convert solution
+
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ELF_32_CONVERT_
+#define _ELF_32_CONVERT_
+
+BOOLEAN
+InitializeElf32 (
+ UINT8 *FileBuffer,
+ ELF_FUNCTION_TABLE *ElfFunctions
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.c
new file mode 100644
index 00000000..989c1fa8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -0,0 +1,1668 @@
+/** @file
+Elf64 convert solution
+
+Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WinNtInclude.h"
+
+#ifndef __GNUC__
+#include <windows.h>
+#include <io.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h>
+
+#include "PeCoffLib.h"
+#include "EfiUtilityMsgs.h"
+
+#include "GenFw.h"
+#include "ElfConvert.h"
+#include "Elf64Convert.h"
+
+STATIC
+VOID
+ScanSections64 (
+ VOID
+ );
+
+STATIC
+BOOLEAN
+WriteSections64 (
+ SECTION_FILTER_TYPES FilterType
+ );
+
+STATIC
+VOID
+WriteRelocations64 (
+ VOID
+ );
+
+STATIC
+VOID
+WriteDebug64 (
+ VOID
+ );
+
+STATIC
+VOID
+SetImageSize64 (
+ VOID
+ );
+
+STATIC
+VOID
+CleanUp64 (
+ VOID
+ );
+
+//
+// Rename ELF32 structures to common names to help when porting to ELF64.
+//
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Phdr Elf_Phdr;
+typedef Elf64_Dyn Elf_Dyn;
+#define ELFCLASS ELFCLASS64
+#define ELF_R_TYPE(r) ELF64_R_TYPE(r)
+#define ELF_R_SYM(r) ELF64_R_SYM(r)
+
+//
+// Well known ELF structures.
+//
+STATIC Elf_Ehdr *mEhdr;
+STATIC Elf_Shdr *mShdrBase;
+STATIC Elf_Phdr *mPhdrBase;
+
+//
+// GOT information
+//
+STATIC Elf_Shdr *mGOTShdr = NULL;
+STATIC UINT32 mGOTShindex = 0;
+STATIC UINT32 *mGOTCoffEntries = NULL;
+STATIC UINT32 mGOTMaxCoffEntries = 0;
+STATIC UINT32 mGOTNumCoffEntries = 0;
+
+//
+// Coff information
+//
+STATIC UINT32 mCoffAlignment = 0x20;
+
+//
+// PE section alignment.
+//
+STATIC const UINT16 mCoffNbrSections = 4;
+
+//
+// ELF sections to offset in Coff file.
+//
+STATIC UINT32 *mCoffSectionsOffset = NULL;
+
+//
+// Offsets in COFF file
+//
+STATIC UINT32 mNtHdrOffset;
+STATIC UINT32 mTextOffset;
+STATIC UINT32 mDataOffset;
+STATIC UINT32 mHiiRsrcOffset;
+STATIC UINT32 mRelocOffset;
+STATIC UINT32 mDebugOffset;
+
+//
+// Used for RISC-V relocations.
+//
+STATIC UINT8 *mRiscVPass1Targ = NULL;
+STATIC Elf_Shdr *mRiscVPass1Sym = NULL;
+STATIC Elf64_Half mRiscVPass1SymSecIndex = 0;
+
+//
+// Initialization Function
+//
+BOOLEAN
+InitializeElf64 (
+ UINT8 *FileBuffer,
+ ELF_FUNCTION_TABLE *ElfFunctions
+ )
+{
+ //
+ // Initialize data pointer and structures.
+ //
+ VerboseMsg ("Set EHDR");
+ mEhdr = (Elf_Ehdr*) FileBuffer;
+
+ //
+ // Check the ELF64 specific header information.
+ //
+ VerboseMsg ("Check ELF64 Header Information");
+ if (mEhdr->e_ident[EI_CLASS] != ELFCLASS64) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS64");
+ return FALSE;
+ }
+ if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");
+ return FALSE;
+ }
+ if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
+ return FALSE;
+ }
+ if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {
+ Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");
+ }
+ if (mEhdr->e_version != EV_CURRENT) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT);
+ return FALSE;
+ }
+
+ //
+ // Update section header pointers
+ //
+ VerboseMsg ("Update Header Pointers");
+ mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff);
+ mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff);
+
+ //
+ // Create COFF Section offset buffer and zero.
+ //
+ VerboseMsg ("Create COFF Section Offset Buffer");
+ mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32));
+ if (mCoffSectionsOffset == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return FALSE;
+ }
+ memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32));
+
+ //
+ // Fill in function pointers.
+ //
+ VerboseMsg ("Fill in Function Pointers");
+ ElfFunctions->ScanSections = ScanSections64;
+ ElfFunctions->WriteSections = WriteSections64;
+ ElfFunctions->WriteRelocations = WriteRelocations64;
+ ElfFunctions->WriteDebug = WriteDebug64;
+ ElfFunctions->SetImageSize = SetImageSize64;
+ ElfFunctions->CleanUp = CleanUp64;
+
+ return TRUE;
+}
+
+
+//
+// Header by Index functions
+//
+STATIC
+Elf_Shdr*
+GetShdrByIndex (
+ UINT32 Num
+ )
+{
+ if (Num >= mEhdr->e_shnum) {
+ Error (NULL, 0, 3000, "Invalid", "GetShdrByIndex: Index %u is too high.", Num);
+ exit(EXIT_FAILURE);
+ }
+
+ return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize);
+}
+
+STATIC
+UINT32
+CoffAlign (
+ UINT32 Offset
+ )
+{
+ return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1);
+}
+
+STATIC
+UINT32
+DebugRvaAlign (
+ UINT32 Offset
+ )
+{
+ return (Offset + 3) & ~3;
+}
+
+//
+// filter functions
+//
+STATIC
+BOOLEAN
+IsTextShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC);
+}
+
+STATIC
+BOOLEAN
+IsHiiRsrcShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);
+
+ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0);
+}
+
+STATIC
+BOOLEAN
+IsDataShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ if (IsHiiRsrcShdr(Shdr)) {
+ return FALSE;
+ }
+ return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
+}
+
+STATIC
+BOOLEAN
+IsStrtabShdr (
+ Elf_Shdr *Shdr
+ )
+{
+ Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);
+
+ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_STRTAB_SECTION_NAME) == 0);
+}
+
+STATIC
+Elf_Shdr *
+FindStrtabShdr (
+ VOID
+ )
+{
+ UINT32 i;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsStrtabShdr(shdr)) {
+ return shdr;
+ }
+ }
+ return NULL;
+}
+
+STATIC
+const UINT8 *
+GetSymName (
+ Elf_Sym *Sym
+ )
+{
+ Elf_Shdr *StrtabShdr;
+ UINT8 *StrtabContents;
+ BOOLEAN foundEnd;
+ UINT32 i;
+
+ if (Sym->st_name == 0) {
+ return NULL;
+ }
+
+ StrtabShdr = FindStrtabShdr();
+ if (StrtabShdr == NULL) {
+ return NULL;
+ }
+
+ assert(Sym->st_name < StrtabShdr->sh_size);
+
+ StrtabContents = (UINT8*)mEhdr + StrtabShdr->sh_offset;
+
+ foundEnd = FALSE;
+ for (i= Sym->st_name; (i < StrtabShdr->sh_size) && !foundEnd; i++) {
+ foundEnd = (BOOLEAN)(StrtabContents[i] == 0);
+ }
+ assert(foundEnd);
+
+ return StrtabContents + Sym->st_name;
+}
+
+//
+// Find the ELF section hosting the GOT from an ELF Rva
+// of a single GOT entry. Normally, GOT is placed in
+// ELF .text section, so assume once we find in which
+// section the GOT is, all GOT entries are there, and
+// just verify this.
+//
+STATIC
+VOID
+FindElfGOTSectionFromGOTEntryElfRva (
+ Elf64_Addr GOTEntryElfRva
+ )
+{
+ UINT32 i;
+ if (mGOTShdr != NULL) {
+ if (GOTEntryElfRva >= mGOTShdr->sh_addr &&
+ GOTEntryElfRva < mGOTShdr->sh_addr + mGOTShdr->sh_size) {
+ return;
+ }
+ Error (NULL, 0, 3000, "Unsupported", "FindElfGOTSectionFromGOTEntryElfRva: GOT entries found in multiple sections.");
+ exit(EXIT_FAILURE);
+ }
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (GOTEntryElfRva >= shdr->sh_addr &&
+ GOTEntryElfRva < shdr->sh_addr + shdr->sh_size) {
+ mGOTShdr = shdr;
+ mGOTShindex = i;
+ return;
+ }
+ }
+ Error (NULL, 0, 3000, "Invalid", "FindElfGOTSectionFromGOTEntryElfRva: ElfRva 0x%016LX for GOT entry not found in any section.", GOTEntryElfRva);
+ exit(EXIT_FAILURE);
+}
+
+//
+// Stores locations of GOT entries in COFF image.
+// Returns TRUE if GOT entry is new.
+// Simple implementation as number of GOT
+// entries is expected to be low.
+//
+
+STATIC
+BOOLEAN
+AccumulateCoffGOTEntries (
+ UINT32 GOTCoffEntry
+ )
+{
+ UINT32 i;
+ if (mGOTCoffEntries != NULL) {
+ for (i = 0; i < mGOTNumCoffEntries; i++) {
+ if (mGOTCoffEntries[i] == GOTCoffEntry) {
+ return FALSE;
+ }
+ }
+ }
+ if (mGOTCoffEntries == NULL) {
+ mGOTCoffEntries = (UINT32*)malloc(5 * sizeof *mGOTCoffEntries);
+ if (mGOTCoffEntries == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ }
+ assert (mGOTCoffEntries != NULL);
+ mGOTMaxCoffEntries = 5;
+ mGOTNumCoffEntries = 0;
+ } else if (mGOTNumCoffEntries == mGOTMaxCoffEntries) {
+ mGOTCoffEntries = (UINT32*)realloc(mGOTCoffEntries, 2 * mGOTMaxCoffEntries * sizeof *mGOTCoffEntries);
+ if (mGOTCoffEntries == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ }
+ assert (mGOTCoffEntries != NULL);
+ mGOTMaxCoffEntries += mGOTMaxCoffEntries;
+ }
+ mGOTCoffEntries[mGOTNumCoffEntries++] = GOTCoffEntry;
+ return TRUE;
+}
+
+//
+// 32-bit Unsigned integer comparator for qsort.
+//
+STATIC
+int
+UINT32Comparator (
+ const void* lhs,
+ const void* rhs
+ )
+{
+ if (*(const UINT32*)lhs < *(const UINT32*)rhs) {
+ return -1;
+ }
+ return *(const UINT32*)lhs > *(const UINT32*)rhs;
+}
+
+//
+// Emit accumulated Coff GOT entry relocations into
+// Coff image. This function performs its job
+// once and then releases the entry list, so
+// it can safely be called multiple times.
+//
+STATIC
+VOID
+EmitGOTRelocations (
+ VOID
+ )
+{
+ UINT32 i;
+ if (mGOTCoffEntries == NULL) {
+ return;
+ }
+ //
+ // Emit Coff relocations with Rvas ordered.
+ //
+ qsort(
+ mGOTCoffEntries,
+ mGOTNumCoffEntries,
+ sizeof *mGOTCoffEntries,
+ UINT32Comparator);
+ for (i = 0; i < mGOTNumCoffEntries; i++) {
+ VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", mGOTCoffEntries[i]);
+ CoffAddFixup(
+ mGOTCoffEntries[i],
+ EFI_IMAGE_REL_BASED_DIR64);
+ }
+ free(mGOTCoffEntries);
+ mGOTCoffEntries = NULL;
+ mGOTMaxCoffEntries = 0;
+ mGOTNumCoffEntries = 0;
+}
+//
+// RISC-V 64 specific Elf WriteSection function.
+//
+STATIC
+VOID
+WriteSectionRiscV64 (
+ Elf_Rela *Rel,
+ UINT8 *Targ,
+ Elf_Shdr *SymShdr,
+ Elf_Sym *Sym
+ )
+{
+ UINT32 Value;
+ UINT32 Value2;
+
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_RISCV_NONE:
+ break;
+
+ case R_RISCV_32:
+ *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
+ break;
+
+ case R_RISCV_64:
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ break;
+
+ case R_RISCV_HI20:
+ mRiscVPass1Targ = Targ;
+ mRiscVPass1Sym = SymShdr;
+ mRiscVPass1SymSecIndex = Sym->st_shndx;
+ break;
+
+ case R_RISCV_LO12_I:
+ if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) {
+ Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12));
+ *(UINT32 *)Targ = (RV_X (Value, 0, 12) << 20) | \
+ (RV_X (*(UINT32 *)Targ, 0, 20));
+ }
+ mRiscVPass1Sym = NULL;
+ mRiscVPass1Targ = NULL;
+ mRiscVPass1SymSecIndex = 0;
+ break;
+
+ case R_RISCV_LO12_S:
+ if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) {
+ Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5) | (RV_X(*(UINT32 *)Targ, 25, 7) << 5));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12));
+ Value2 = *(UINT32 *)Targ & 0x01fff07f;
+ Value &= RISCV_IMM_REACH - 1;
+ *(UINT32 *)Targ = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
+ }
+ mRiscVPass1Sym = NULL;
+ mRiscVPass1Targ = NULL;
+ mRiscVPass1SymSecIndex = 0;
+ break;
+
+ case R_RISCV_PCREL_HI20:
+ mRiscVPass1Targ = Targ;
+ mRiscVPass1Sym = SymShdr;
+ mRiscVPass1SymSecIndex = Sym->st_shndx;
+
+ Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20));
+ break;
+
+ case R_RISCV_PCREL_LO12_I:
+ if (mRiscVPass1Targ != NULL && mRiscVPass1Sym != NULL && mRiscVPass1SymSecIndex != 0) {
+ int i;
+ Value2 = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20));
+ Value = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));
+ if(Value & (RISCV_IMM_REACH/2)) {
+ Value |= ~(RISCV_IMM_REACH-1);
+ }
+ Value = Value - (UINT32)mRiscVPass1Sym->sh_addr + mCoffSectionsOffset[mRiscVPass1SymSecIndex];
+ if(-2048 > (INT32)Value) {
+ i = (((INT32)Value * -1) / 4096);
+ Value2 -= i;
+ Value += 4096 * i;
+ if(-2048 > (INT32)Value) {
+ Value2 -= 1;
+ Value += 4096;
+ }
+ }
+ else if( 2047 < (INT32)Value) {
+ i = (Value / 4096);
+ Value2 += i;
+ Value -= 4096 * i;
+ if(2047 < (INT32)Value) {
+ Value2 += 1;
+ Value -= 4096;
+ }
+ }
+
+ *(UINT32 *)Targ = (RV_X(Value, 0, 12) << 20) | (RV_X(*(UINT32*)Targ, 0, 20));
+ *(UINT32 *)mRiscVPass1Targ = (RV_X(Value2, 0, 20)<<12) | (RV_X(*(UINT32 *)mRiscVPass1Targ, 0, 12));
+ }
+ mRiscVPass1Sym = NULL;
+ mRiscVPass1Targ = NULL;
+ mRiscVPass1SymSecIndex = 0;
+ break;
+
+ case R_RISCV_ADD64:
+ case R_RISCV_SUB64:
+ case R_RISCV_ADD32:
+ case R_RISCV_SUB32:
+ case R_RISCV_BRANCH:
+ case R_RISCV_JAL:
+ case R_RISCV_GPREL_I:
+ case R_RISCV_GPREL_S:
+ case R_RISCV_CALL:
+ case R_RISCV_RVC_BRANCH:
+ case R_RISCV_RVC_JUMP:
+ case R_RISCV_RELAX:
+ case R_RISCV_SUB6:
+ case R_RISCV_SET6:
+ case R_RISCV_SET8:
+ case R_RISCV_SET16:
+ case R_RISCV_SET32:
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+}
+
+//
+// Elf functions interface implementation
+//
+
+STATIC
+VOID
+ScanSections64 (
+ VOID
+ )
+{
+ UINT32 i;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+ UINT32 CoffEntry;
+ UINT32 SectionCount;
+ BOOLEAN FoundSection;
+
+ CoffEntry = 0;
+ mCoffOffset = 0;
+
+ //
+ // Coff file start with a DOS header.
+ //
+ mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;
+ mNtHdrOffset = mCoffOffset;
+ switch (mEhdr->e_machine) {
+ case EM_X86_64:
+ case EM_AARCH64:
+ case EM_RISCV64:
+ mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
+ break;
+ default:
+ VerboseMsg ("%s unknown e_machine type %hu. Assume X64", mInImageName, mEhdr->e_machine);
+ mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
+ break;
+ }
+
+ mTableOffset = mCoffOffset;
+ mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);
+
+ //
+ // Set mCoffAlignment to the maximum alignment of the input sections
+ // we care about
+ //
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (shdr->sh_addralign <= mCoffAlignment) {
+ continue;
+ }
+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {
+ mCoffAlignment = (UINT32)shdr->sh_addralign;
+ }
+ }
+
+ //
+ // Check if mCoffAlignment is larger than MAX_COFF_ALIGNMENT
+ //
+ if (mCoffAlignment > MAX_COFF_ALIGNMENT) {
+ Error (NULL, 0, 3000, "Invalid", "Section alignment is larger than MAX_COFF_ALIGNMENT.");
+ assert (FALSE);
+ }
+
+
+ //
+ // Move the PE/COFF header right before the first section. This will help us
+ // save space when converting to TE.
+ //
+ if (mCoffAlignment > mCoffOffset) {
+ mNtHdrOffset += mCoffAlignment - mCoffOffset;
+ mTableOffset += mCoffAlignment - mCoffOffset;
+ mCoffOffset = mCoffAlignment;
+ }
+
+ //
+ // First text sections.
+ //
+ mCoffOffset = CoffAlign(mCoffOffset);
+ mTextOffset = mCoffOffset;
+ FoundSection = FALSE;
+ SectionCount = 0;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsTextShdr(shdr)) {
+ if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {
+ // the alignment field is valid
+ if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
+ // if the section address is aligned we must align PE/COFF
+ mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
+ } else {
+#ifdef VBOX
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment. sec#%i addr=%#llx align=%#llx", i, shdr->sh_addr, shdr->sh_addralign);
+#else
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
+#endif
+ }
+ }
+
+ /* Relocate entry. */
+ if ((mEhdr->e_entry >= shdr->sh_addr) &&
+ (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) {
+ CoffEntry = (UINT32) (mCoffOffset + mEhdr->e_entry - shdr->sh_addr);
+ }
+
+ //
+ // Set mTextOffset with the offset of the first '.text' section
+ //
+ if (!FoundSection) {
+ mTextOffset = mCoffOffset;
+ FoundSection = TRUE;
+ }
+
+ mCoffSectionsOffset[i] = mCoffOffset;
+ mCoffOffset += (UINT32) shdr->sh_size;
+ SectionCount ++;
+ }
+ }
+
+ if (!FoundSection) {
+ Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section.");
+ assert (FALSE);
+ }
+
+ mDebugOffset = DebugRvaAlign(mCoffOffset);
+ mCoffOffset = CoffAlign(mCoffOffset);
+
+ if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {
+ Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName);
+ }
+
+ //
+ // Then data sections.
+ //
+ mDataOffset = mCoffOffset;
+ FoundSection = FALSE;
+ SectionCount = 0;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsDataShdr(shdr)) {
+ if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {
+ // the alignment field is valid
+ if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
+ // if the section address is aligned we must align PE/COFF
+ mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
+ } else {
+#ifdef VBOX
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment. sec#%i addr=%#llx align=%#llx", i, shdr->sh_addr, shdr->sh_addralign);
+#else
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
+#endif
+ }
+ }
+
+ //
+ // Set mDataOffset with the offset of the first '.data' section
+ //
+ if (!FoundSection) {
+ mDataOffset = mCoffOffset;
+ FoundSection = TRUE;
+ }
+ mCoffSectionsOffset[i] = mCoffOffset;
+ mCoffOffset += (UINT32) shdr->sh_size;
+ SectionCount ++;
+ }
+ }
+
+ //
+ // Make room for .debug data in .data (or .text if .data is empty) instead of
+ // putting it in a section of its own. This is explicitly allowed by the
+ // PE/COFF spec, and prevents bloat in the binary when using large values for
+ // section alignment.
+ //
+ if (SectionCount > 0) {
+ mDebugOffset = DebugRvaAlign(mCoffOffset);
+ }
+ mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +
+ sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +
+ strlen(mInImageName) + 1;
+
+ mCoffOffset = CoffAlign(mCoffOffset);
+ if (SectionCount == 0) {
+ mDataOffset = mCoffOffset;
+ }
+
+ if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {
+ Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);
+ }
+
+ //
+ // The HII resource sections.
+ //
+ mHiiRsrcOffset = mCoffOffset;
+ for (i = 0; i < mEhdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsHiiRsrcShdr(shdr)) {
+ if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {
+ // the alignment field is valid
+ if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
+ // if the section address is aligned we must align PE/COFF
+ mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
+ } else {
+#ifdef VBOX
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment. sec#%i addr=%#llx align=%#llx", i, shdr->sh_addr, shdr->sh_addralign);
+#else
+ Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
+#endif
+ }
+ }
+ if (shdr->sh_size != 0) {
+ mHiiRsrcOffset = mCoffOffset;
+ mCoffSectionsOffset[i] = mCoffOffset;
+ mCoffOffset += (UINT32) shdr->sh_size;
+ mCoffOffset = CoffAlign(mCoffOffset);
+ SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset);
+ }
+ break;
+ }
+ }
+
+ mRelocOffset = mCoffOffset;
+
+ //
+ // Allocate base Coff file. Will be expanded later for relocations.
+ //
+ mCoffFile = (UINT8 *)malloc(mCoffOffset);
+ if (mCoffFile == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ }
+ assert (mCoffFile != NULL);
+ memset(mCoffFile, 0, mCoffOffset);
+
+ //
+ // Fill headers.
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile;
+ DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;
+ DosHdr->e_lfanew = mNtHdrOffset;
+
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset);
+
+ NtHdr->Pe32Plus.Signature = EFI_IMAGE_NT_SIGNATURE;
+
+ switch (mEhdr->e_machine) {
+ case EM_X86_64:
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ case EM_AARCH64:
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64;
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ case EM_RISCV64:
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+
+ default:
+ VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ }
+
+ NtHdr->Pe32Plus.FileHeader.NumberOfSections = mCoffNbrSections;
+ NtHdr->Pe32Plus.FileHeader.TimeDateStamp = (UINT32) time(NULL);
+ mImageTimeStamp = NtHdr->Pe32Plus.FileHeader.TimeDateStamp;
+ NtHdr->Pe32Plus.FileHeader.PointerToSymbolTable = 0;
+ NtHdr->Pe32Plus.FileHeader.NumberOfSymbols = 0;
+ NtHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32Plus.OptionalHeader);
+ NtHdr->Pe32Plus.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE
+ | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED
+ | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED
+ | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE;
+
+ NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;
+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;
+ NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0;
+ NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry;
+
+ NtHdr->Pe32Plus.OptionalHeader.BaseOfCode = mTextOffset;
+
+ NtHdr->Pe32Plus.OptionalHeader.ImageBase = 0;
+ NtHdr->Pe32Plus.OptionalHeader.SectionAlignment = mCoffAlignment;
+ NtHdr->Pe32Plus.OptionalHeader.FileAlignment = mCoffAlignment;
+ NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = 0;
+
+ NtHdr->Pe32Plus.OptionalHeader.SizeOfHeaders = mTextOffset;
+ NtHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
+
+ //
+ // Section headers.
+ //
+ if ((mDataOffset - mTextOffset) > 0) {
+ CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset,
+ EFI_IMAGE_SCN_CNT_CODE
+ | EFI_IMAGE_SCN_MEM_EXECUTE
+ | EFI_IMAGE_SCN_MEM_READ);
+ } else {
+ // Don't make a section of size 0.
+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;
+ }
+
+ if ((mHiiRsrcOffset - mDataOffset) > 0) {
+ CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_WRITE
+ | EFI_IMAGE_SCN_MEM_READ);
+ } else {
+ // Don't make a section of size 0.
+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;
+ }
+
+ if ((mRelocOffset - mHiiRsrcOffset) > 0) {
+ CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_READ);
+
+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset;
+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset;
+ } else {
+ // Don't make a section of size 0.
+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;
+ }
+
+}
+
+STATIC
+BOOLEAN
+WriteSections64 (
+ SECTION_FILTER_TYPES FilterType
+ )
+{
+ UINT32 Idx;
+ Elf_Shdr *SecShdr;
+ UINT32 SecOffset;
+ BOOLEAN (*Filter)(Elf_Shdr *);
+ Elf64_Addr GOTEntryRva;
+
+ //
+ // Initialize filter pointer
+ //
+ switch (FilterType) {
+ case SECTION_TEXT:
+ Filter = IsTextShdr;
+ break;
+ case SECTION_HII:
+ Filter = IsHiiRsrcShdr;
+ break;
+ case SECTION_DATA:
+ Filter = IsDataShdr;
+ break;
+ default:
+ return FALSE;
+ }
+
+ //
+ // First: copy sections.
+ //
+ for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {
+ Elf_Shdr *Shdr = GetShdrByIndex(Idx);
+ if ((*Filter)(Shdr)) {
+ switch (Shdr->sh_type) {
+ case SHT_PROGBITS:
+ /* Copy. */
+ if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) {
+ return FALSE;
+ }
+ memcpy(mCoffFile + mCoffSectionsOffset[Idx],
+ (UINT8*)mEhdr + Shdr->sh_offset,
+ (size_t) Shdr->sh_size);
+ break;
+
+ case SHT_NOBITS:
+ memset(mCoffFile + mCoffSectionsOffset[Idx], 0, (size_t) Shdr->sh_size);
+ break;
+
+ default:
+ //
+ // Ignore for unknown section type.
+ //
+ VerboseMsg ("%s unknown section type %x. We ignore this unknown section type.", mInImageName, (unsigned)Shdr->sh_type);
+ break;
+ }
+ }
+ }
+
+ //
+ // Second: apply relocations.
+ //
+ VerboseMsg ("Applying Relocations...");
+ for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {
+ //
+ // Determine if this is a relocation section.
+ //
+ Elf_Shdr *RelShdr = GetShdrByIndex(Idx);
+ if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {
+ continue;
+ }
+
+ //
+ // If this is a ET_DYN (PIE) executable, we will encounter a dynamic SHT_RELA
+ // section that applies to the entire binary, and which will have its section
+ // index set to #0 (which is a NULL section with the SHF_ALLOC bit cleared).
+ //
+ // In the absence of GOT based relocations,
+ // this RELA section will contain redundant R_xxx_RELATIVE relocations, one
+ // for every R_xxx_xx64 relocation appearing in the per-section RELA sections.
+ // (i.e., .rela.text and .rela.data)
+ //
+ if (RelShdr->sh_info == 0) {
+ continue;
+ }
+
+ //
+ // Relocation section found. Now extract section information that the relocations
+ // apply to in the ELF data and the new COFF data.
+ //
+ SecShdr = GetShdrByIndex(RelShdr->sh_info);
+ SecOffset = mCoffSectionsOffset[RelShdr->sh_info];
+
+ //
+ // Only process relocations for the current filter type.
+ //
+ if (RelShdr->sh_type == SHT_RELA && (*Filter)(SecShdr)) {
+ UINT64 RelIdx;
+
+ //
+ // Determine the symbol table referenced by the relocation data.
+ //
+ Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);
+ UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;
+
+ //
+ // Process all relocation entries for this section.
+ //
+ for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINT32) RelShdr->sh_entsize) {
+
+ //
+ // Set pointer to relocation entry
+ //
+ Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);
+
+ //
+ // Set pointer to symbol table entry associated with the relocation entry.
+ //
+ Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);
+
+ Elf_Shdr *SymShdr;
+ UINT8 *Targ;
+
+ //
+ // Check section header index found in symbol table and get the section
+ // header location.
+ //
+ if (Sym->st_shndx == SHN_UNDEF
+ || Sym->st_shndx >= mEhdr->e_shnum) {
+ const UINT8 *SymName = GetSymName(Sym);
+ if (SymName == NULL) {
+ SymName = (const UINT8 *)"<unknown>";
+ }
+
+ //
+ // Skip error on EM_RISCV64 becasue no symble name is built
+ // from RISC-V toolchain.
+ //
+ if (mEhdr->e_machine != EM_RISCV64) {
+ Error (NULL, 0, 3000, "Invalid",
+ "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "
+ "For example, absolute and undefined symbols are not supported.",
+ mInImageName, SymName, Sym->st_value);
+
+ exit(EXIT_FAILURE);
+ }
+ }
+ SymShdr = GetShdrByIndex(Sym->st_shndx);
+
+ //
+ // Convert the relocation data to a pointer into the coff file.
+ //
+ // Note:
+ // r_offset is the virtual address of the storage unit to be relocated.
+ // sh_addr is the virtual address for the base of the section.
+ //
+ // r_offset in a memory address.
+ // Convert it to a pointer in the coff file.
+ //
+ Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);
+
+ //
+ // Determine how to handle each relocation type based on the machine type.
+ //
+ if (mEhdr->e_machine == EM_X86_64) {
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_X86_64_NONE:
+ break;
+ case R_X86_64_64:
+ //
+ // Absolute relocation.
+ //
+ VerboseMsg ("R_X86_64_64");
+ VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX",
+ (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
+ *(UINT64 *)Targ);
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ);
+ break;
+ case R_X86_64_32:
+ VerboseMsg ("R_X86_64_32");
+ VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
+ (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
+ *(UINT32 *)Targ);
+ *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
+ VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ);
+ break;
+ case R_X86_64_32S:
+ VerboseMsg ("R_X86_64_32S");
+ VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
+ (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
+ *(UINT32 *)Targ);
+ *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
+ VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ);
+ break;
+
+ case R_X86_64_PLT32:
+ //
+ // Treat R_X86_64_PLT32 relocations as R_X86_64_PC32: this is
+ // possible since we know all code symbol references resolve to
+ // definitions in the same module (UEFI has no shared libraries),
+ // and so there is never a reason to jump via a PLT entry,
+ // allowing us to resolve the reference using the symbol directly.
+ //
+ VerboseMsg ("Treating R_X86_64_PLT32 as R_X86_64_PC32 ...");
+ /* fall through */
+ case R_X86_64_PC32:
+ //
+ // Relative relocation: Symbol - Ip + Addend
+ //
+ VerboseMsg ("R_X86_64_PC32");
+ VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
+ (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
+ *(UINT32 *)Targ);
+ *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ
+ + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)
+ - (SecOffset - SecShdr->sh_addr));
+ VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ);
+ break;
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCRELX:
+ case R_X86_64_REX_GOTPCRELX:
+ VerboseMsg ("R_X86_64_GOTPCREL family");
+ VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X",
+ (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)),
+ *(UINT32 *)Targ);
+ GOTEntryRva = Rel->r_offset - Rel->r_addend + *(INT32 *)Targ;
+ FindElfGOTSectionFromGOTEntryElfRva(GOTEntryRva);
+ *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ
+ + (mCoffSectionsOffset[mGOTShindex] - mGOTShdr->sh_addr)
+ - (SecOffset - SecShdr->sh_addr));
+ VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ);
+ GOTEntryRva += (mCoffSectionsOffset[mGOTShindex] - mGOTShdr->sh_addr); // ELF Rva -> COFF Rva
+ if (AccumulateCoffGOTEntries((UINT32)GOTEntryRva)) {
+ //
+ // Relocate GOT entry if it's the first time we run into it
+ //
+ Targ = mCoffFile + GOTEntryRva;
+ //
+ // Limitation: The following three statements assume memory
+ // at *Targ is valid because the section containing the GOT
+ // has already been copied from the ELF image to the Coff image.
+ // This pre-condition presently holds because the GOT is placed
+ // in section .text, and the ELF text sections are all copied
+ // prior to reaching this point.
+ // If the pre-condition is violated in the future, this fixup
+ // either needs to be deferred after the GOT section is copied
+ // to the Coff image, or the fixup should be performed on the
+ // source Elf image instead of the destination Coff image.
+ //
+ VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX",
+ (UINT32)GOTEntryRva,
+ *(UINT64 *)Targ);
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ);
+ }
+ break;
+ default:
+ Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else if (mEhdr->e_machine == EM_AARCH64) {
+
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ INT64 Offset;
+
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ //
+ // Convert into an ADD instruction - see R_AARCH64_ADR_GOT_PAGE below.
+ //
+ *(UINT32 *)Targ &= 0x3ff;
+ *(UINT32 *)Targ |= 0x91000000 | ((Sym->st_value & 0xfff) << 10);
+ break;
+
+ case R_AARCH64_ADR_GOT_PAGE:
+ //
+ // This relocation points to the GOT entry that contains the absolute
+ // address of the symbol we are referring to. Since EDK2 only uses
+ // fully linked binaries, we can avoid the indirection, and simply
+ // refer to the symbol directly. This implies having to patch the
+ // subsequent LDR instruction (covered by a R_AARCH64_LD64_GOT_LO12_NC
+ // relocation) into an ADD instruction - this is handled above.
+ //
+ Offset = (Sym->st_value - (Rel->r_offset & ~0xfff)) >> 12;
+
+ *(UINT32 *)Targ &= 0x9000001f;
+ *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29);
+
+ /* fall through */
+
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ //
+ // In order to handle Cortex-A53 erratum #843419, the LD linker may
+ // convert ADRP instructions into ADR instructions, but without
+ // updating the static relocation type, and so we may end up here
+ // while the instruction in question is actually ADR. So let's
+ // just disregard it: the section offset check we apply below to
+ // ADR instructions will trigger for its R_AARCH64_xxx_ABS_LO12_NC
+ // companion instruction as well, so it is safe to omit it here.
+ //
+ if ((*(UINT32 *)Targ & BIT31) == 0) {
+ break;
+ }
+
+ //
+ // AArch64 PG_H21 relocations are typically paired with ABS_LO12
+ // relocations, where a PC-relative reference with +/- 4 GB range is
+ // split into a relative high part and an absolute low part. Since
+ // the absolute low part represents the offset into a 4 KB page, we
+ // either have to convert the ADRP into an ADR instruction, or we
+ // need to use a section alignment of at least 4 KB, so that the
+ // binary appears at a correct offset at runtime. In any case, we
+ // have to make sure that the 4 KB relative offsets of both the
+ // section containing the reference as well as the section to which
+ // it refers have not been changed during PE/COFF conversion (i.e.,
+ // in ScanSections64() above).
+ //
+ if (mCoffAlignment < 0x1000) {
+ //
+ // Attempt to convert the ADRP into an ADR instruction.
+ // This is only possible if the symbol is within +/- 1 MB.
+ //
+
+ // Decode the ADRP instruction
+ Offset = (INT32)((*(UINT32 *)Targ & 0xffffe0) << 8);
+ Offset = (Offset << (6 - 5)) | ((*(UINT32 *)Targ & 0x60000000) >> (29 - 12));
+
+ //
+ // ADRP offset is relative to the previous page boundary,
+ // whereas ADR offset is relative to the instruction itself.
+ // So fix up the offset so it points to the page containing
+ // the symbol.
+ //
+ Offset -= (UINTN)(Targ - mCoffFile) & 0xfff;
+
+ if (Offset < -0x100000 || Offset > 0xfffff) {
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s due to its size (> 1 MB), this module requires 4 KB section alignment.",
+ mInImageName);
+ break;
+ }
+
+ // Re-encode the offset as an ADR instruction
+ *(UINT32 *)Targ &= 0x1000001f;
+ *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29);
+ }
+ /* fall through */
+
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ case R_AARCH64_LDST8_ABS_LO12_NC:
+ case R_AARCH64_LDST16_ABS_LO12_NC:
+ case R_AARCH64_LDST32_ABS_LO12_NC:
+ case R_AARCH64_LDST64_ABS_LO12_NC:
+ case R_AARCH64_LDST128_ABS_LO12_NC:
+ if (((SecShdr->sh_addr ^ SecOffset) & 0xfff) != 0 ||
+ ((SymShdr->sh_addr ^ mCoffSectionsOffset[Sym->st_shndx]) & 0xfff) != 0) {
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s AARCH64 small code model requires identical ELF and PE/COFF section offsets modulo 4 KB.",
+ mInImageName);
+ break;
+ }
+ /* fall through */
+
+ case R_AARCH64_ADR_PREL_LO21:
+ case R_AARCH64_CONDBR19:
+ case R_AARCH64_LD_PREL_LO19:
+ case R_AARCH64_CALL26:
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_PREL64:
+ case R_AARCH64_PREL32:
+ case R_AARCH64_PREL16:
+ //
+ // The GCC toolchains (i.e., binutils) may corrupt section relative
+ // relocations when emitting relocation sections into fully linked
+ // binaries. More specifically, they tend to fail to take into
+ // account the fact that a '.rodata + XXX' relocation needs to have
+ // its addend recalculated once .rodata is merged into the .text
+ // section, and the relocation emitted into the .rela.text section.
+ //
+ // We cannot really recover from this loss of information, so the
+ // only workaround is to prevent having to recalculate any relative
+ // relocations at all, by using a linker script that ensures that
+ // the offset between the Place and the Symbol is the same in both
+ // the ELF and the PE/COFF versions of the binary.
+ //
+ if ((SymShdr->sh_addr - SecShdr->sh_addr) !=
+ (mCoffSectionsOffset[Sym->st_shndx] - SecOffset)) {
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s AARCH64 relative relocations require identical ELF and PE/COFF section offsets",
+ mInImageName);
+ }
+ break;
+
+ // Absolute relocations.
+ case R_AARCH64_ABS64:
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else if (mEhdr->e_machine == EM_RISCV64) {
+ //
+ // Write section for RISC-V 64 architecture.
+ //
+ WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+STATIC
+VOID
+WriteRelocations64 (
+ VOID
+ )
+{
+ UINT32 Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+ EFI_IMAGE_DATA_DIRECTORY *Dir;
+ UINT32 RiscVRelType;
+
+ for (Index = 0; Index < mEhdr->e_shnum; Index++) {
+ Elf_Shdr *RelShdr = GetShdrByIndex(Index);
+ if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) {
+ Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info);
+ if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {
+ UINT64 RelIdx;
+
+ for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
+ Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);
+
+ if (mEhdr->e_machine == EM_X86_64) {
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_X86_64_NONE:
+ case R_X86_64_PC32:
+ case R_X86_64_PLT32:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCRELX:
+ case R_X86_64_REX_GOTPCRELX:
+ break;
+ case R_X86_64_64:
+ VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X",
+ mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_DIR64);
+ break;
+ //
+ // R_X86_64_32 and R_X86_64_32S are ELF64 relocations emitted when using
+ // the SYSV X64 ABI small non-position-independent code model.
+ // R_X86_64_32 is used for unsigned 32-bit immediates with a 32-bit operand
+ // size. The value is either not extended, or zero-extended to 64 bits.
+ // R_X86_64_32S is used for either signed 32-bit non-rip-relative displacements
+ // or signed 32-bit immediates with a 64-bit operand size. The value is
+ // sign-extended to 64 bits.
+ // EFI_IMAGE_REL_BASED_HIGHLOW is a PE relocation that uses 32-bit arithmetic
+ // for rebasing an image.
+ // EFI PE binaries declare themselves EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE and
+ // may load above 2GB. If an EFI PE binary with a converted R_X86_64_32S
+ // relocation is loaded above 2GB, the value will get sign-extended to the
+ // negative part of the 64-bit address space. The negative part of the 64-bit
+ // address space is unmapped, so accessing such an address page-faults.
+ // In order to support R_X86_64_32S, it is necessary to unset
+ // EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE, and the EFI PE loader must implement
+ // this flag and abstain from loading such a PE binary above 2GB.
+ // Since this feature is not supported, support for R_X86_64_32S (and hence
+ // the small non-position-independent code model) is disabled.
+ //
+ // case R_X86_64_32S:
+ case R_X86_64_32:
+ VerboseMsg ("EFI_IMAGE_REL_BASED_HIGHLOW Offset: 0x%08X",
+ mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+ default:
+ Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else if (mEhdr->e_machine == EM_AARCH64) {
+
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_AARCH64_ADR_PREL_LO21:
+ case R_AARCH64_CONDBR19:
+ case R_AARCH64_LD_PREL_LO19:
+ case R_AARCH64_CALL26:
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_PREL64:
+ case R_AARCH64_PREL32:
+ case R_AARCH64_PREL16:
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ case R_AARCH64_LDST8_ABS_LO12_NC:
+ case R_AARCH64_LDST16_ABS_LO12_NC:
+ case R_AARCH64_LDST32_ABS_LO12_NC:
+ case R_AARCH64_LDST64_ABS_LO12_NC:
+ case R_AARCH64_LDST128_ABS_LO12_NC:
+ case R_AARCH64_ADR_GOT_PAGE:
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ //
+ // No fixups are required for relative relocations, provided that
+ // the relative offsets between sections have been preserved in
+ // the ELF to PE/COFF conversion. We have already asserted that
+ // this is the case in WriteSections64 ().
+ //
+ break;
+
+ case R_AARCH64_ABS64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_DIR64);
+ break;
+
+ case R_AARCH64_ABS32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else if (mEhdr->e_machine == EM_RISCV64) {
+ RiscVRelType = ELF_R_TYPE(Rel->r_info);
+ switch (RiscVRelType) {
+ case R_RISCV_NONE:
+ break;
+
+ case R_RISCV_32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+
+ case R_RISCV_64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_DIR64);
+ break;
+
+ case R_RISCV_HI20:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_RISCV_HI20);
+ break;
+
+ case R_RISCV_LO12_I:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_RISCV_LOW12I);
+ break;
+
+ case R_RISCV_LO12_S:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_RISCV_LOW12S);
+ break;
+
+ case R_RISCV_ADD64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_SUB64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_ADD32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_SUB32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_BRANCH:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_JAL:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_GPREL_I:
+ case R_RISCV_GPREL_S:
+ case R_RISCV_CALL:
+ case R_RISCV_RVC_BRANCH:
+ case R_RISCV_RVC_JUMP:
+ case R_RISCV_RELAX:
+ case R_RISCV_SUB6:
+ case R_RISCV_SET6:
+ case R_RISCV_SET8:
+ case R_RISCV_SET16:
+ case R_RISCV_SET32:
+ case R_RISCV_PCREL_HI20:
+ case R_RISCV_PCREL_LO12_I:
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
+ } else {
+ Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);
+ }
+ }
+ if (mEhdr->e_machine == EM_X86_64 && RelShdr->sh_info == mGOTShindex) {
+ //
+ // Tack relocations for GOT entries after other relocations for
+ // the section the GOT is in, as it's usually found at the end
+ // of the section. This is done in order to maintain Rva order
+ // of Coff relocations.
+ //
+ EmitGOTRelocations();
+ }
+ }
+ }
+ }
+
+ if (mEhdr->e_machine == EM_X86_64) {
+ //
+ // This is a safety net just in case the GOT is in a section
+ // with no other relocations and the first invocation of
+ // EmitGOTRelocations() above was skipped. This invocation
+ // does not maintain Rva order of Coff relocations.
+ // At present, with a single text section, all references to
+ // the GOT and the GOT itself reside in section .text, so
+ // if there's a GOT at all, the first invocation above
+ // is executed.
+ //
+ EmitGOTRelocations();
+ }
+ //
+ // Pad by adding empty entries.
+ //
+ while (mCoffOffset & (mCoffAlignment - 1)) {
+ CoffAddFixupEntry(0);
+ }
+
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
+ Dir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ Dir->Size = mCoffOffset - mRelocOffset;
+ if (Dir->Size == 0) {
+ // If no relocations, null out the directory entry and don't add the .reloc section
+ Dir->VirtualAddress = 0;
+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;
+ } else {
+ Dir->VirtualAddress = mRelocOffset;
+ CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_DISCARDABLE
+ | EFI_IMAGE_SCN_MEM_READ);
+ }
+}
+
+STATIC
+VOID
+WriteDebug64 (
+ VOID
+ )
+{
+ UINT32 Len;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+ EFI_IMAGE_DATA_DIRECTORY *DataDir;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;
+ EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;
+
+ Len = strlen(mInImageName) + 1;
+
+ Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);
+ Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;
+ Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;
+ Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+
+ Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);
+ Nb10->Signature = CODEVIEW_SIGNATURE_NB10;
+ strcpy ((char *)(Nb10 + 1), mInImageName);
+
+
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
+ DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ DataDir->VirtualAddress = mDebugOffset;
+ DataDir->Size = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+}
+
+STATIC
+VOID
+SetImageSize64 (
+ VOID
+ )
+{
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
+
+ //
+ // Set image size
+ //
+ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
+ NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = mCoffOffset;
+}
+
+STATIC
+VOID
+CleanUp64 (
+ VOID
+ )
+{
+ if (mCoffSectionsOffset != NULL) {
+ free (mCoffSectionsOffset);
+ }
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.h
new file mode 100644
index 00000000..69746f4e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Elf64Convert.h
@@ -0,0 +1,19 @@
+/** @file
+Header file for Elf64 convert solution
+
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ELF_64_CONVERT_
+#define _ELF_64_CONVERT_
+
+BOOLEAN
+InitializeElf64 (
+ UINT8 *FileBuffer,
+ ELF_FUNCTION_TABLE *ElfFunctions
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.c
new file mode 100644
index 00000000..1dfc947f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.c
@@ -0,0 +1,245 @@
+/** @file
+Elf convert solution
+
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WinNtInclude.h"
+
+#ifndef __GNUC__
+#include <windows.h>
+#include <io.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h>
+
+#include "EfiUtilityMsgs.h"
+
+#include "GenFw.h"
+#include "ElfConvert.h"
+#include "Elf32Convert.h"
+#include "Elf64Convert.h"
+
+//
+// Result Coff file in memory.
+//
+UINT8 *mCoffFile = NULL;
+
+//
+// COFF relocation data
+//
+EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel;
+UINT16 *mCoffEntryRel;
+
+//
+// Current offset in coff file.
+//
+UINT32 mCoffOffset;
+
+//
+// Offset in Coff file of headers and sections.
+//
+UINT32 mTableOffset;
+
+//
+//mFileBufferSize
+//
+UINT32 mFileBufferSize;
+
+//
+//*****************************************************************************
+// Common ELF Functions
+//*****************************************************************************
+//
+
+VOID
+CoffAddFixupEntry(
+ UINT16 Val
+ )
+{
+ *mCoffEntryRel = Val;
+ mCoffEntryRel++;
+ mCoffBaseRel->SizeOfBlock += 2;
+ mCoffOffset += 2;
+}
+
+VOID
+CoffAddFixup(
+ UINT32 Offset,
+ UINT8 Type
+ )
+{
+ if (mCoffBaseRel == NULL
+ || mCoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {
+ if (mCoffBaseRel != NULL) {
+ //
+ // Add a null entry (is it required ?)
+ //
+ CoffAddFixupEntry (0);
+
+ //
+ // Pad for alignment.
+ //
+ if (mCoffOffset % 4 != 0)
+ CoffAddFixupEntry (0);
+ }
+
+ mCoffFile = realloc (
+ mCoffFile,
+ mCoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT
+ );
+ if (mCoffFile == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ }
+ assert (mCoffFile != NULL);
+ memset (
+ mCoffFile + mCoffOffset, 0,
+ sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT
+ );
+
+ mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset);
+ mCoffBaseRel->VirtualAddress = Offset & ~0xfff;
+ mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);
+
+ mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1);
+ mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);
+ }
+
+ //
+ // Fill the entry.
+ //
+ CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));
+}
+
+VOID
+CreateSectionHeader (
+ const CHAR8 *Name,
+ UINT32 Offset,
+ UINT32 Size,
+ UINT32 Flags
+ )
+{
+ EFI_IMAGE_SECTION_HEADER *Hdr;
+ Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset);
+
+ strcpy((char *)Hdr->Name, Name);
+ Hdr->Misc.VirtualSize = Size;
+ Hdr->VirtualAddress = Offset;
+ Hdr->SizeOfRawData = Size;
+ Hdr->PointerToRawData = Offset;
+ Hdr->PointerToRelocations = 0;
+ Hdr->PointerToLinenumbers = 0;
+ Hdr->NumberOfRelocations = 0;
+ Hdr->NumberOfLinenumbers = 0;
+ Hdr->Characteristics = Flags;
+
+ mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+}
+
+//
+//*****************************************************************************
+// Functions called from GenFw main code.
+//*****************************************************************************
+//
+
+INTN
+IsElfHeader (
+ UINT8 *FileBuffer
+)
+{
+ return (FileBuffer[EI_MAG0] == ELFMAG0 &&
+ FileBuffer[EI_MAG1] == ELFMAG1 &&
+ FileBuffer[EI_MAG2] == ELFMAG2 &&
+ FileBuffer[EI_MAG3] == ELFMAG3);
+}
+
+BOOLEAN
+ConvertElf (
+ UINT8 **FileBuffer,
+ UINT32 *FileLength
+ )
+{
+ ELF_FUNCTION_TABLE ElfFunctions;
+ UINT8 EiClass;
+
+ mFileBufferSize = *FileLength;
+ //
+ // Determine ELF type and set function table pointer correctly.
+ //
+ VerboseMsg ("Check Elf Image Header");
+ EiClass = (*FileBuffer)[EI_CLASS];
+ if (EiClass == ELFCLASS32) {
+ if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) {
+ return FALSE;
+ }
+ } else if (EiClass == ELFCLASS64) {
+ if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) {
+ return FALSE;
+ }
+ } else {
+ Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported.");
+ return FALSE;
+ }
+
+ //
+ // Compute sections new address.
+ //
+ VerboseMsg ("Compute sections new address.");
+ ElfFunctions.ScanSections ();
+
+ //
+ // Write and relocate sections.
+ //
+ VerboseMsg ("Write and relocate sections.");
+ if (!ElfFunctions.WriteSections (SECTION_TEXT)) {
+ return FALSE;
+ }
+ if (!ElfFunctions.WriteSections (SECTION_DATA)) {
+ return FALSE;
+ }
+ if (!ElfFunctions.WriteSections (SECTION_HII)) {
+ return FALSE;
+ }
+
+ //
+ // Translate and write relocations.
+ //
+ VerboseMsg ("Translate and write relocations.");
+ ElfFunctions.WriteRelocations ();
+
+ //
+ // Write debug info.
+ //
+ VerboseMsg ("Write debug info.");
+ ElfFunctions.WriteDebug ();
+
+ //
+ // Make sure image size is correct before returning the new image.
+ //
+ VerboseMsg ("Set image size.");
+ ElfFunctions.SetImageSize ();
+
+ //
+ // Replace.
+ //
+ free (*FileBuffer);
+ *FileBuffer = mCoffFile;
+ *FileLength = mCoffOffset;
+
+ //
+ // Free resources used by ELF functions.
+ //
+ ElfFunctions.CleanUp ();
+
+ return TRUE;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.h
new file mode 100644
index 00000000..27917942
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/ElfConvert.h
@@ -0,0 +1,81 @@
+/** @file
+Header file for Elf convert solution
+
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ELF_CONVERT_H_
+#define _ELF_CONVERT_H_
+
+#include "elf_common.h"
+#include "elf32.h"
+#include "elf64.h"
+
+//
+// Externally defined variables
+//
+extern UINT32 mCoffOffset;
+extern CHAR8 *mInImageName;
+extern UINT32 mImageTimeStamp;
+extern UINT8 *mCoffFile;
+extern UINT32 mTableOffset;
+extern UINT32 mOutImageType;
+extern UINT32 mFileBufferSize;
+
+//
+// Common EFI specific data.
+//
+#define ELF_HII_SECTION_NAME ".hii"
+#define ELF_STRTAB_SECTION_NAME ".strtab"
+#define MAX_COFF_ALIGNMENT 0x10000
+
+//
+// Filter Types
+//
+typedef enum {
+ SECTION_TEXT,
+ SECTION_HII,
+ SECTION_DATA
+
+} SECTION_FILTER_TYPES;
+
+//
+// FunctionTable
+//
+typedef struct {
+ VOID (*ScanSections) ();
+ BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType);
+ VOID (*WriteRelocations) ();
+ VOID (*WriteDebug) ();
+ VOID (*SetImageSize) ();
+ VOID (*CleanUp) ();
+
+} ELF_FUNCTION_TABLE;
+
+//
+// Common functions
+//
+VOID
+CoffAddFixup (
+ UINT32 Offset,
+ UINT8 Type
+ );
+
+VOID
+CoffAddFixupEntry (
+ UINT16 Val
+ );
+
+
+VOID
+CreateSectionHeader (
+ const CHAR8 *Name,
+ UINT32 Offset,
+ UINT32 Size,
+ UINT32 Flags
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GNUmakefile
new file mode 100644
index 00000000..79916b4f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GNUmakefile
@@ -0,0 +1,23 @@
+## @file
+# GNU/Linux makefile for 'GenFw' module build.
+#
+# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = GenFw
+
+OBJECTS = GenFw.o ElfConvert.o Elf32Convert.o Elf64Convert.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+ifeq ($(CYGWIN), CYGWIN)
+ LIBS += -L/lib/e2fsprogs -luuid
+endif
+
+ifeq ($(LINUX), Linux)
+ LIBS += -luuid
+endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.c
new file mode 100644
index 00000000..4faf329b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.c
@@ -0,0 +1,3255 @@
+/** @file
+Converts a pe32+ image to an FW, Te image type, or other specific image.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WinNtInclude.h"
+
+#ifndef __GNUC__
+#include <windows.h>
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <IndustryStandard/PeImage.h>
+#include <Common/UefiInternalFormRepresentation.h>
+
+//
+// Acpi Table definition
+//
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Acpi1_0.h>
+#include <IndustryStandard/Acpi2_0.h>
+#include <IndustryStandard/Acpi3_0.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+
+#include "CommonLib.h"
+#include "PeCoffLib.h"
+#include "ParseInf.h"
+#include "EfiUtilityMsgs.h"
+
+#include "GenFw.h"
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+
+//
+// Version of this utility
+//
+#define UTILITY_NAME "GenFw"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 2
+
+#define HII_RESOURCE_SECTION_INDEX 1
+#define HII_RESOURCE_SECTION_NAME "HII"
+
+#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF
+#define DEFAULT_MC_ALIGNMENT 16
+
+#define STATUS_IGNORE 0xA
+//
+// Structure definition for a microcode header
+//
+typedef struct {
+ UINT32 HeaderVersion;
+ UINT32 PatchId;
+ UINT32 Date;
+ UINT32 CpuId;
+ UINT32 Checksum;
+ UINT32 LoaderVersion;
+ UINT32 PlatformId;
+ UINT32 DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid
+ UINT32 TotalSize; // number of bytes
+ UINT32 Reserved[3];
+} MICROCODE_IMAGE_HEADER;
+
+static EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+
+static const char *gHiiPackageRCFileHeader[] = {
+ "//",
+ "// DO NOT EDIT -- auto-generated file",
+ "//",
+ NULL
+};
+
+//
+// Module image information
+//
+CHAR8 *mInImageName;
+UINT32 mImageTimeStamp = 0;
+UINT32 mImageSize = 0;
+UINT32 mOutImageType = FW_DUMMY_IMAGE;
+BOOLEAN mIsConvertXip = FALSE;
+
+
+STATIC
+EFI_STATUS
+ZeroDebugData (
+ IN OUT UINT8 *FileBuffer,
+ BOOLEAN ZeroDebug
+ );
+
+STATIC
+EFI_STATUS
+SetStamp (
+ IN OUT UINT8 *FileBuffer,
+ IN CHAR8 *TimeStamp
+ );
+
+STATIC
+STATUS
+MicrocodeReadData (
+ FILE *InFptr,
+ UINT32 *Data
+ );
+
+STATIC
+VOID
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print out version information for this utility.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print Help message.
+
+Arguments:
+
+ VOID
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "\nUsage: %s [options] <input_file>\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " -o FileName, --outputfile FileName\n\
+ File will be created to store the output content.\n");
+ fprintf (stdout, " -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\
+ Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\
+ PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\
+ SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\
+ DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\
+ MM_STANDALONE, MM_CORE_STANDALONE,\n\
+ PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\
+ APPLICATION, SAL_RT_DRIVER to support all module types\n\
+ It can only be used together with --keepexceptiontable,\n\
+ --keepzeropending, --keepoptionalheader, -r, -o option.\n\
+ It is a action option. If it is combined with other action options,\n\
+ the later input action option will override the previous one.\n");
+ fprintf (stdout, " -c, --acpi Create Acpi table.\n\
+ It can't be combined with other action options\n\
+ except for -o, -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -t, --terse Create Te Image.\n\
+ It can only be used together with --keepexceptiontable,\n\
+ --keepzeropending, --keepoptionalheader, -r, -o option.\n\
+ It is a action option. If it is combined with other action options,\n\
+ the later input action option will override the previous one.\n");
+ fprintf (stdout, " -u, --dump Dump TeImage Header.\n\
+ It can't be combined with other action options\n\
+ except for -o, -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -z, --zero Zero the Debug Data Fields in the PE input image file.\n\
+ It also zeros the time stamp fields.\n\
+ This option can be used to compare the binary efi image.\n\
+ It can't be combined with other action options\n\
+ except for -o, -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -b, --exe2bin Convert the input EXE to the output BIN file.\n\
+ It can't be combined with other action options\n\
+ except for -o, -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");;
+ fprintf (stdout, " -l, --stripped Strip off the relocation info from PE or TE image.\n\
+ It can't be combined with other action options\n\
+ except for -o, -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -s timedate, --stamp timedate\n\
+ timedate format is \"yyyy-mm-dd 00:00:00\". if timedata \n\
+ is set to NOW, current system time is used. The support\n\
+ date scope is 1970-01-01 00+timezone:00:00\n\
+ ~ 2038-01-19 03+timezone:14:07\n\
+ The scope is adjusted according to the different zones.\n\
+ It can't be combined with other action options\n\
+ except for -o, -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -m, --mcifile Convert input microcode txt file to microcode bin file.\n\
+ It can't be combined with other action options\n\
+ except for -o option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -j, --join Combine multi microcode bin files to one file.\n\
+ It can be specified with -a, -p, -o option.\n\
+ No other options can be combined with it.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -a NUM, --align NUM NUM is one HEX or DEC format alignment value.\n\
+ This option is only used together with -j option.\n");
+ fprintf (stdout, " -p NUM, --pad NUM NUM is one HEX or DEC format padding value.\n\
+ This option is only used together with -j option.\n");
+ fprintf (stdout, " --keepexceptiontable Don't clear exception table.\n\
+ This option can be used together with -e or -t.\n\
+ It doesn't work for other options.\n");
+ fprintf (stdout, " --keepoptionalheader Don't zero PE/COFF optional header fields.\n\
+ This option can be used together with -e or -t.\n\
+ It doesn't work for other options.\n");
+ fprintf (stdout, " --keepzeropending Don't strip zero pending of .reloc.\n\
+ This option can be used together with -e or -t.\n\
+ It doesn't work for other options.\n");
+ fprintf (stdout, " -r, --replace Overwrite the input file with the output content.\n\
+ If more input files are specified,\n\
+ the last input file will be as the output file.\n");
+ fprintf (stdout, " -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\
+ Guid is used to specify hii package list guid.\n\
+ Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\
+ If not specified, the first Form FormSet guid is used.\n");
+ fprintf (stdout, " --hiipackage Combine all input binary hii packages into \n\
+ a single package list as the text resource data(RC).\n\
+ It can't be combined with other action options\n\
+ except for -o option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " --hiibinpackage Combine all input binary hii packages into \n\
+ a single package list as the binary resource section.\n\
+ It can't be combined with other action options\n\
+ except for -o option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " --rebase NewAddress Rebase image to new base address. New address \n\
+ is also set to the first none code section header.\n\
+ It can't be combined with other action options\n\
+ except for -o or -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " --address NewAddress Set new address into the first none code \n\
+ section header of the input image.\n\
+ It can't be combined with other action options\n\
+ except for -o or -r option. It is a action option.\n\
+ If it is combined with other action options, the later\n\
+ input action option will override the previous one.\n");
+ fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
+ fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
+ fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
+ fprintf (stdout, " --version Show program's version number and exit\n");
+ fprintf (stdout, " -h, --help Show this help message and exit\n");
+}
+
+STATIC
+STATUS
+CheckAcpiTable (
+ VOID *AcpiTable,
+ UINT32 Length
+ )
+/*++
+
+Routine Description:
+
+ Check Acpi Table
+
+Arguments:
+
+ AcpiTable Buffer for AcpiSection
+ Length AcpiSection Length
+
+Returns:
+
+ 0 success
+ non-zero otherwise
+
+--*/
+{
+ EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader;
+ EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+ UINT32 ExpectedLength;
+
+ AcpiHeader = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable;
+
+ //
+ // Generic check for AcpiTable length.
+ //
+ if (AcpiHeader->Length > Length) {
+ Error (NULL, 0, 3000, "Invalid", "AcpiTable length check failed.", NULL);
+ return STATUS_ERROR;
+ }
+
+ //
+ // Currently, we only check must-have tables: FADT, FACS, DSDT,
+ // and some important tables: MADT, MCFG.
+ //
+ switch (AcpiHeader->Signature) {
+
+ //
+ // "FACP" Fixed ACPI Description Table
+ //
+ case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+ switch (AcpiHeader->Revision) {
+ case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:
+ ExpectedLength = sizeof(EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE);
+ break;
+ case EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:
+ ExpectedLength = sizeof(EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE);
+ break;
+ case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:
+ ExpectedLength = sizeof(EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE);
+ break;
+ default:
+ if (AcpiHeader->Revision > EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
+ ExpectedLength = AcpiHeader->Length;
+ break;
+ }
+ Error (NULL, 0, 3000, "Invalid", "FACP revision check failed.");
+ return STATUS_ERROR;
+ }
+ if (ExpectedLength != AcpiHeader->Length) {
+ Error (NULL, 0, 3000, "Invalid", "FACP length check failed.");
+ return STATUS_ERROR;
+ }
+ break;
+
+ //
+ // "FACS" Firmware ACPI Control Structure
+ //
+ case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
+ Facs = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)AcpiTable;
+ if (Facs->Version > EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) {
+ break;
+ }
+ if ((Facs->Version != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&
+ (Facs->Version != EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&
+ (Facs->Version != EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION)){
+ Error (NULL, 0, 3000, "Invalid", "FACS version check failed.");
+ return STATUS_ERROR;
+ }
+ if ((Facs->Length != sizeof(EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) &&
+ (Facs->Length != sizeof(EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) &&
+ (Facs->Length != sizeof(EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE))) {
+ Error (NULL, 0, 3000, "Invalid", "FACS length check failed.");
+ return STATUS_ERROR;
+ }
+ break;
+
+ //
+ // "DSDT" Differentiated System Description Table
+ //
+ case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+ if (AcpiHeader->Revision > EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION) {
+ break;
+ }
+ if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER)) {
+ Error (NULL, 0, 3000, "Invalid", "DSDT length check failed.");
+ return STATUS_ERROR;
+ }
+ break;
+
+ //
+ // "APIC" Multiple APIC Description Table
+ //
+ case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+ if (AcpiHeader->Revision > EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) {
+ break;
+ }
+ if ((AcpiHeader->Revision != EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) &&
+ (AcpiHeader->Revision != EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) &&
+ (AcpiHeader->Revision != EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION)) {
+ Error (NULL, 0, 3000, "Invalid", "APIC revision check failed.");
+ return STATUS_ERROR;
+ }
+ if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT32) + sizeof(UINT32)) {
+ Error (NULL, 0, 3000, "Invalid", "APIC length check failed.");
+ return STATUS_ERROR;
+ }
+ break;
+
+ //
+ // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
+ //
+ case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
+ if (AcpiHeader->Revision > EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) {
+ break;
+ }
+ if (AcpiHeader->Revision != EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) {
+ Error (NULL, 0, 3000, "Invalid", "MCFG revision check failed.");
+ return STATUS_ERROR;
+ }
+ if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64)) {
+ Error (NULL, 0, 3000, "Invalid", "MCFG length check failed.");
+ return STATUS_ERROR;
+ }
+ break;
+
+ //
+ // Other table pass check
+ //
+ default:
+ break;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+SetHiiResourceHeader (
+ UINT8 *HiiBinData,
+ UINT32 OffsetToFile
+ )
+{
+ UINT32 Index;
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
+
+ //
+ // Fill Resource section entry
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData);
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
+ for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index ++) {
+ if (ResourceDirectoryEntry->u1.s.NameIsString) {
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset);
+
+ if (ResourceDirectoryString->Length == 3 &&
+ ResourceDirectoryString->String[0] == L'H' &&
+ ResourceDirectoryString->String[1] == L'I' &&
+ ResourceDirectoryString->String[2] == L'I') {
+ //
+ // Resource Type "HII" found
+ //
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {
+ //
+ // Move to next level - resource Name
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
+
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {
+ //
+ // Move to next level - resource Language
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
+ }
+ }
+
+ //
+ // Now it ought to be resource Data and update its OffsetToData value
+ //
+ if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData);
+ ResourceDataEntry->OffsetToData = ResourceDataEntry->OffsetToData + OffsetToFile;
+ break;
+ }
+ }
+ }
+ ResourceDirectoryEntry++;
+ }
+
+ return;
+}
+
+EFI_IMAGE_OPTIONAL_HEADER_UNION *
+GetPeCoffHeader (
+ void *Data
+ )
+{
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
+
+ //
+ // Read the dos & pe hdrs of the image
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Data;
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ // NO DOS header, check for PE/COFF header
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Data);
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ return NULL;
+ }
+ } else {
+
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(((UINT8 *)Data) + DosHdr->e_lfanew);
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ return NULL;
+ }
+ }
+
+ return PeHdr;
+}
+
+void
+PeCoffConvertImageToXip (
+ UINT8 **FileBuffer,
+ UINT32 *FileLength
+ )
+{
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NewPeHdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ UINTN TotalNecessaryFileSize;
+ UINTN SectionSize;
+ UINT8 *XipFile;
+ UINT32 XipLength;
+ UINTN Index;
+ UINTN FirstSectionOffset;
+ BOOLEAN ConversionNeeded;
+
+ PeHdr = GetPeCoffHeader ((void *) *FileBuffer);
+ if (PeHdr == NULL) {
+ return;
+ }
+
+ if (PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment) {
+ //
+ // The only reason to expand zero fill sections is to make them compatible with XIP images.
+ // If SectionAlignment is not equal to FileAlignment then it is not an XIP type image.
+ //
+ return;
+ }
+
+ //
+ // Calculate size of XIP file, and determine if the conversion is needed.
+ //
+ ConversionNeeded = FALSE;
+ XipLength = 0;
+ FirstSectionOffset = *FileLength;
+ TotalNecessaryFileSize = 0;
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ SectionSize = MAX (SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData);
+ TotalNecessaryFileSize += SectionSize;
+ if (SectionSize > 0) {
+ FirstSectionOffset = MIN (FirstSectionOffset, SectionHeader->VirtualAddress);
+ XipLength = MAX (XipLength, SectionHeader->VirtualAddress + SectionSize);
+ if (SectionHeader->VirtualAddress != SectionHeader->PointerToRawData) {
+ ConversionNeeded = TRUE;
+ }
+ }
+ if (SectionHeader->Misc.VirtualSize > SectionHeader->SizeOfRawData) {
+ ConversionNeeded = TRUE;
+ }
+ }
+
+ if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {
+ //
+ // If one of the sections should be loaded to an offset overlapping with
+ // the executable header, then it cannot be made into an XIP image.
+ //
+ VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");
+ VerboseMsg ("of section data with the executable header.");
+ return;
+ }
+
+ if (FirstSectionOffset == *FileLength) {
+ //
+ // If we never found a section with a non-zero size, then we
+ // skip the conversion.
+ //
+ return;
+ }
+
+ TotalNecessaryFileSize += FirstSectionOffset;
+
+ if (!ConversionNeeded) {
+ return;
+ }
+
+ if (XipLength > (2 * TotalNecessaryFileSize)) {
+ VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary.");
+ VerboseMsg ("The image linking process may have left unused memory ranges.");
+ }
+
+ if (PeHdr->Pe32.FileHeader.PointerToSymbolTable != 0) {
+ //
+ // This field is obsolete and should be zero
+ //
+ PeHdr->Pe32.FileHeader.PointerToSymbolTable = 0;
+ }
+
+ //
+ // Allocate the extra space that we need to grow the image
+ //
+ XipFile = malloc (XipLength);
+ if (XipFile == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return;
+ }
+ memset (XipFile, 0, XipLength);
+
+ //
+ // Copy the file headers
+ //
+ memcpy (XipFile, *FileBuffer, PeHdr->Pe32.OptionalHeader.SizeOfHeaders);
+
+ NewPeHdr = GetPeCoffHeader ((void *)XipFile);
+ if (NewPeHdr == NULL) {
+ free (XipFile);
+ return;
+ }
+
+ //
+ // Copy the section data over to the appropriate XIP offsets
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ if (SectionHeader->SizeOfRawData > 0) {
+ memcpy (
+ XipFile + SectionHeader->VirtualAddress,
+ *FileBuffer + SectionHeader->PointerToRawData,
+ SectionHeader->SizeOfRawData
+ );
+ }
+ //
+ // Make the size of raw data in section header alignment.
+ //
+ SectionSize = (SectionHeader->Misc.VirtualSize + PeHdr->Pe32.OptionalHeader.FileAlignment - 1) & (~(PeHdr->Pe32.OptionalHeader.FileAlignment - 1));
+ if (SectionSize < SectionHeader->SizeOfRawData) {
+ SectionHeader->SizeOfRawData = SectionSize;
+ }
+
+ SectionHeader->PointerToRawData = SectionHeader->VirtualAddress;
+ }
+
+ free (*FileBuffer);
+ *FileLength = XipLength;
+ *FileBuffer = XipFile;
+
+ mIsConvertXip = TRUE;
+}
+
+UINT8 *
+CreateHiiResouceSectionHeader (
+ UINT32 *pSectionHeaderSize,
+ UINT32 HiiDataSize
+ )
+/*++
+
+Routine Description:
+
+ Create COFF resource section header
+
+Arguments:
+
+ pSectionHeaderSize - Pointer to section header size.
+ HiiDataSize - Size of the total HII data in section.
+
+Returns:
+ The created section header buffer.
+
+--*/
+{
+ UINT32 HiiSectionHeaderSize;
+ UINT32 HiiSectionOffset;
+ UINT8 *HiiSectionHeader;
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeResourceDirectoryEntry;
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameResourceDirectoryEntry;
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LanguageResourceDirectoryEntry;
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
+
+ //
+ // Calculate the total size for the resource header (include Type, Name and Language)
+ // then allocate memory for the resource header.
+ //
+ HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY))
+ + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16))
+ + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);
+ HiiSectionHeader = malloc (HiiSectionHeaderSize);
+ if (HiiSectionHeader == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return NULL;
+ }
+ memset (HiiSectionHeader, 0, HiiSectionHeaderSize);
+
+ HiiSectionOffset = 0;
+ //
+ // Create Type entry
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
+ ResourceDirectory->NumberOfNamedEntries = 1;
+ TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
+ TypeResourceDirectoryEntry->u1.s.NameIsString = 1;
+ TypeResourceDirectoryEntry->u2.s.DataIsDirectory = 1;
+ TypeResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;
+ //
+ // Create Name entry
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
+ ResourceDirectory->NumberOfNamedEntries = 1;
+ NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
+ NameResourceDirectoryEntry->u1.s.NameIsString = 1;
+ NameResourceDirectoryEntry->u2.s.DataIsDirectory = 1;
+ NameResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;
+ //
+ // Create Language entry
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
+ ResourceDirectory->NumberOfNamedEntries = 1;
+ LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
+ LanguageResourceDirectoryEntry->u1.s.NameIsString = 1;
+ //
+ // Create string entry for Type
+ //
+ TypeResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);
+ ResourceDirectoryString->Length = 3;
+ ResourceDirectoryString->String[0] = L'H';
+ ResourceDirectoryString->String[1] = L'I';
+ ResourceDirectoryString->String[2] = L'I';
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);
+ //
+ // Create string entry for Name
+ //
+ NameResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);
+ ResourceDirectoryString->Length = 3;
+ ResourceDirectoryString->String[0] = L'E';
+ ResourceDirectoryString->String[1] = L'F';
+ ResourceDirectoryString->String[2] = L'I';
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);
+ //
+ // Create string entry for Language
+ //
+ LanguageResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);
+ ResourceDirectoryString->Length = 3;
+ ResourceDirectoryString->String[0] = L'B';
+ ResourceDirectoryString->String[1] = L'I';
+ ResourceDirectoryString->String[2] = L'N';
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);
+ //
+ // Create Leaf data
+ //
+ LanguageResourceDirectoryEntry->u2.OffsetToData = HiiSectionOffset;
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);
+ ResourceDataEntry->OffsetToData = HiiSectionOffset;
+ ResourceDataEntry->Size = HiiDataSize;
+
+ *pSectionHeaderSize = HiiSectionHeaderSize;
+ return HiiSectionHeader;
+}
+
+EFI_STATUS
+RebaseImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINT32 *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+
+ FileOffset - The offset, in bytes, into the file to read
+
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+
+ Buffer - A pointer to the buffer to read the data into.
+
+Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINT32 Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SetAddressToSectionHeader (
+ IN CHAR8 *FileName,
+ IN OUT UINT8 *FileBuffer,
+ IN UINT64 NewPe32BaseAddress
+ )
+/*++
+
+Routine Description:
+
+ Set new base address into the section header of PeImage
+
+Arguments:
+
+ FileName - Name of file
+ FileBuffer - Pointer to PeImage.
+ NewPe32BaseAddress - New Base Address for PE image.
+
+Returns:
+
+ EFI_SUCCESS Set new base address into this image successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
+ return Status;
+ }
+
+ if (ImageContext.RelocationsStripped) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
+ return Status;
+ }
+
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Get section header list
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ //
+ // Set base address into the first section header that doesn't point to code section.
+ //
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
+ *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;
+ break;
+ }
+ }
+
+ //
+ // BaseAddress is set to section header.
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RebaseImage (
+ IN CHAR8 *FileName,
+ IN OUT UINT8 *FileBuffer,
+ IN UINT64 NewPe32BaseAddress
+ )
+/*++
+
+Routine Description:
+
+ Set new base address into PeImage, and fix up PeImage based on new address.
+
+Arguments:
+
+ FileName - Name of file
+ FileBuffer - Pointer to PeImage.
+ NewPe32BaseAddress - New Base Address for PE image.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - BaseAddress is not valid.
+ EFI_SUCCESS - Update PeImage is correctly.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ UINT8 *MemoryImagePointer;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
+ return Status;
+ }
+
+ if (ImageContext.RelocationsStripped) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
+ return Status;
+ }
+
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy Relocated data to raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ CopyMem (
+ FileBuffer + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData < SectionHeader->Misc.VirtualSize ? SectionHeader->SizeOfRawData : SectionHeader->Misc.VirtualSize
+ );
+ }
+
+ free ((VOID *) MemoryImagePointer);
+
+ //
+ // Update Image Base Address
+ //
+ if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
+ } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
+ ImgHdr->Pe32.OptionalHeader.Magic,
+ FileName
+ );
+ return EFI_ABORTED;
+ }
+
+ //
+ // Set new base address into section header
+ //
+ Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);
+
+ return Status;
+}
+
+int
+main (
+ int argc,
+ char *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main function.
+
+Arguments:
+
+ argc - Number of command line parameters.
+ argv - Array of pointers to command line parameter strings.
+
+Returns:
+ STATUS_SUCCESS - Utility exits successfully.
+ STATUS_ERROR - Some error occurred during execution.
+
+--*/
+{
+ UINT32 Type;
+ UINT32 InputFileNum;
+ CHAR8 **InputFileName;
+ char *OutImageName;
+ char *ModuleType;
+ CHAR8 *TimeStamp;
+ FILE *fpIn;
+ FILE *fpOut;
+ FILE *fpInOut;
+ UINT32 Data;
+ UINT32 *DataPointer;
+ UINT32 *OldDataPointer;
+ UINT32 CheckSum;
+ UINT32 Index;
+ UINT32 Index1;
+ UINT32 Index2;
+ UINT64 Temp64;
+ UINT32 MciAlignment;
+ UINT8 MciPadValue;
+ UINT32 AllignedRelocSize;
+ UINT8 *FileBuffer;
+ UINT32 FileLength;
+ UINT8 *OutputFileBuffer;
+ UINT32 OutputFileLength;
+ UINT8 *InputFileBuffer;
+ UINT32 InputFileLength;
+ RUNTIME_FUNCTION *RuntimeFunction;
+ UNWIND_INFO *UnwindInfo;
+ STATUS Status;
+ BOOLEAN ReplaceFlag;
+ BOOLEAN KeepExceptionTableFlag;
+ BOOLEAN KeepOptionalHeaderFlag;
+ BOOLEAN KeepZeroPendingFlag;
+ UINT64 LogLevel;
+ EFI_TE_IMAGE_HEADER TEImageHeader;
+ EFI_TE_IMAGE_HEADER *TeHdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;
+ EFI_IMAGE_DOS_HEADER BackupDosHdr;
+ MICROCODE_IMAGE_HEADER *MciHeader;
+ UINT8 *HiiPackageListBuffer;
+ UINT8 *HiiPackageDataPointer;
+ EFI_GUID HiiPackageListGuid;
+ EFI_HII_PACKAGE_LIST_HEADER HiiPackageListHeader;
+ EFI_HII_PACKAGE_HEADER HiiPackageHeader;
+ EFI_IFR_FORM_SET IfrFormSet;
+ UINT8 NumberOfFormPackage;
+ EFI_HII_PACKAGE_HEADER EndPackage;
+ UINT32 HiiSectionHeaderSize;
+ UINT8 *HiiSectionHeader;
+ UINT64 NewBaseAddress;
+ BOOLEAN NegativeAddr;
+ FILE *ReportFile;
+ CHAR8 *ReportFileName;
+ UINTN FileLen;
+ time_t InputFileTime;
+ time_t OutputFileTime;
+ struct stat Stat_Buf;
+ BOOLEAN ZeroDebugFlag;
+
+ SetUtilityName (UTILITY_NAME);
+
+ //
+ // Assign to fix compile warning
+ //
+ FileLen = 0;
+ InputFileNum = 0;
+ InputFileName = NULL;
+ mInImageName = NULL;
+ OutImageName = NULL;
+ ModuleType = NULL;
+ Type = 0;
+ Status = STATUS_SUCCESS;
+ FileBuffer = NULL;
+ fpIn = NULL;
+ fpOut = NULL;
+ fpInOut = NULL;
+ TimeStamp = NULL;
+ MciAlignment = DEFAULT_MC_ALIGNMENT;
+ MciPadValue = DEFAULT_MC_PAD_BYTE_VALUE;
+ FileLength = 0;
+ MciHeader = NULL;
+ CheckSum = 0;
+ ReplaceFlag = FALSE;
+ LogLevel = 0;
+ OutputFileBuffer = NULL;
+ OutputFileLength = 0;
+ InputFileBuffer = NULL;
+ InputFileLength = 0;
+ Optional32 = NULL;
+ Optional64 = NULL;
+ KeepExceptionTableFlag = FALSE;
+ KeepOptionalHeaderFlag = FALSE;
+ KeepZeroPendingFlag = FALSE;
+ NumberOfFormPackage = 0;
+ HiiPackageListBuffer = NULL;
+ HiiPackageDataPointer = NULL;
+ EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);
+ EndPackage.Type = EFI_HII_PACKAGE_END;
+ memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));
+ HiiSectionHeaderSize = 0;
+ HiiSectionHeader = NULL;
+ NewBaseAddress = 0;
+ NegativeAddr = FALSE;
+ InputFileTime = 0;
+ OutputFileTime = 0;
+ ZeroDebugFlag = FALSE;
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No input options.");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ argc --;
+ argv ++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[0], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Output file name is missing for -o option");
+ goto Finish;
+ }
+ OutImageName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-e") == 0) || (stricmp (argv[0], "--efiImage") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Module Type is missing for -o option");
+ goto Finish;
+ }
+ ModuleType = argv[1];
+ if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {
+ ZeroDebugFlag = TRUE;
+ }
+ if (mOutImageType != FW_TE_IMAGE) {
+ mOutImageType = FW_EFI_IMAGE;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--stripped") == 0)) {
+ mOutImageType = FW_RELOC_STRIPEED_IMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--acpi") == 0)) {
+ mOutImageType = FW_ACPI_IMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--terse") == 0)) {
+ if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {
+ ZeroDebugFlag = TRUE;
+ }
+ mOutImageType = FW_TE_IMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--dump") == 0)) {
+ mOutImageType = DUMP_TE_HEADER;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--exe2bin") == 0)) {
+ mOutImageType = FW_BIN_IMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-z") == 0) || (stricmp (argv[0], "--zero") == 0)) {
+ if (mOutImageType == FW_DUMMY_IMAGE) {
+ mOutImageType = FW_ZERO_DEBUG_IMAGE;
+ }
+ if (mOutImageType == FW_TE_IMAGE || mOutImageType == FW_EFI_IMAGE) {
+ ZeroDebugFlag = TRUE;
+ }
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--stamp") == 0)) {
+ mOutImageType = FW_SET_STAMP_IMAGE;
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "time stamp is missing for -s option");
+ goto Finish;
+ }
+ TimeStamp = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--replace") == 0)) {
+ ReplaceFlag = TRUE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--keepexceptiontable") == 0) {
+ KeepExceptionTableFlag = TRUE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if (stricmp(argv[0], "--keepoptionalheader") == 0) {
+ KeepOptionalHeaderFlag = TRUE;
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--keepzeropending") == 0) {
+ KeepZeroPendingFlag = TRUE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) {
+ mOutImageType = FW_MCI_IMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--join") == 0)) {
+ mOutImageType = FW_MERGE_IMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {
+ if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ MciAlignment = (UINT32) Temp64;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "--rebase") == 0)) {
+ if (argv[1][0] == '-') {
+ NegativeAddr = TRUE;
+ Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);
+ } else {
+ NegativeAddr = FALSE;
+ Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);
+ }
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ mOutImageType = FW_REBASE_IMAGE;
+ NewBaseAddress = (UINT64) Temp64;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "--address") == 0)) {
+ if (argv[1][0] == '-') {
+ NegativeAddr = TRUE;
+ Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);
+ } else {
+ NegativeAddr = FALSE;
+ Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);
+ }
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ mOutImageType = FW_SET_ADDRESS_IMAGE;
+ NewBaseAddress = (UINT64) Temp64;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--pad") == 0)) {
+ if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ MciPadValue = (UINT8) Temp64;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
+ SetPrintLevel (VERBOSE_LOG_LEVEL);
+ VerboseMsg ("Verbose output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ SetPrintLevel (KEY_LOG_LEVEL);
+ KeyMsg ("Quiet output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ if (LogLevel > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
+ goto Finish;
+ }
+ SetPrintLevel (LogLevel);
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--hiiguid") == 0)) {
+ Status = StringToGuid (argv[1], &HiiPackageListGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--hiipackage") == 0) {
+ mOutImageType = FW_HII_PACKAGE_LIST_RCIMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--hiibinpackage") == 0) {
+ mOutImageType = FW_HII_PACKAGE_LIST_BINIMAGE;
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if (argv[0][0] == '-') {
+ Error (NULL, 0, 1000, "Unknown option", argv[0]);
+ goto Finish;
+ }
+ //
+ // Get Input file name
+ //
+ if ((InputFileNum == 0) && (InputFileName == NULL)) {
+ InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+
+ memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
+ } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
+ //
+ // InputFileName buffer too small, need to realloc
+ //
+ InputFileName = (CHAR8 **) realloc (
+ InputFileName,
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
+ );
+
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+
+ memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
+ }
+
+ InputFileName [InputFileNum ++] = argv[0];
+ argc --;
+ argv ++;
+ }
+
+ VerboseMsg ("%s tool start.", UTILITY_NAME);
+
+ if (mOutImageType == FW_DUMMY_IMAGE) {
+ Error (NULL, 0, 1001, "Missing option", "No create file action specified; pls specify -e, -c or -t option to create efi image, or acpi table or TeImage!");
+ if (ReplaceFlag) {
+ Error (NULL, 0, 1001, "Missing option", "-r option is not supported as the independent option. It can be used together with other create file option specified at the above.");
+ }
+ goto Finish;
+ }
+
+ //
+ // check input files
+ //
+ if (InputFileNum == 0) {
+ Error (NULL, 0, 1001, "Missing option", "Input files");
+ goto Finish;
+ }
+
+ //
+ // Combine MciBinary files to one file
+ //
+ if ((mOutImageType == FW_MERGE_IMAGE) && ReplaceFlag) {
+ Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with -j merge files option.");
+ goto Finish;
+ }
+
+ //
+ // Combine HiiBinary packages to a single package list
+ //
+ if ((mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) {
+ Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiipackage merge files option.");
+ goto Finish;
+ }
+
+ if ((mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) && ReplaceFlag) {
+ Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option.");
+ goto Finish;
+ }
+
+ //
+ // Input image file
+ //
+ mInImageName = InputFileName [InputFileNum - 1];
+ VerboseMsg ("the input file name is %s", mInImageName);
+
+ //
+ // Action will be taken for the input file.
+ //
+ switch (mOutImageType) {
+ case FW_EFI_IMAGE:
+ VerboseMsg ("Create efi image on module type %s based on the input PE image.", ModuleType);
+ break;
+ case FW_TE_IMAGE:
+ VerboseMsg ("Create Te Image based on the input PE image.");
+ break;
+ case FW_ACPI_IMAGE:
+ VerboseMsg ("Get acpi table data from the input PE image.");
+ break;
+ case FW_RELOC_STRIPEED_IMAGE:
+ VerboseMsg ("Remove relocation section from Pe or Te image.");
+ break;
+ case FW_BIN_IMAGE:
+ VerboseMsg ("Convert the input EXE to the output BIN file.");
+ break;
+ case FW_ZERO_DEBUG_IMAGE:
+ VerboseMsg ("Zero the Debug Data Fields and Time Stamp in input PE image.");
+ break;
+ case FW_SET_STAMP_IMAGE:
+ VerboseMsg ("Set new time stamp %s in the input PE image.", TimeStamp);
+ break;
+ case DUMP_TE_HEADER:
+ VerboseMsg ("Dump the TE header information of the input TE image.");
+ break;
+ case FW_MCI_IMAGE:
+ VerboseMsg ("Convert input MicroCode.txt file to MicroCode.bin file.");
+ break;
+ case FW_MERGE_IMAGE:
+ VerboseMsg ("Combine the input multi microcode bin files to one bin file.");
+ break;
+ case FW_HII_PACKAGE_LIST_RCIMAGE:
+ VerboseMsg ("Combine the input multi hii bin packages to one text package list RC file.");
+ break;
+ case FW_HII_PACKAGE_LIST_BINIMAGE:
+ VerboseMsg ("Combine the input multi hii bin packages to one binary package list file.");
+ break;
+ case FW_REBASE_IMAGE:
+ VerboseMsg ("Rebase the input image to new base address.");
+ break;
+ case FW_SET_ADDRESS_IMAGE:
+ VerboseMsg ("Set the preferred address into the section header of the input image");
+ break;
+ default:
+ break;
+ }
+
+ if (ReplaceFlag) {
+ VerboseMsg ("Overwrite the input file with the output content.");
+ }
+
+ //
+ // Open output file and Write image into the output file.
+ //
+ if (OutImageName != NULL) {
+ fpOut = fopen (LongFilePath (OutImageName), "rb");
+ if (fpOut != NULL) {
+ //
+ // Get Output file time stamp
+ //
+ fstat(fileno (fpOut), &Stat_Buf);
+ OutputFileTime = Stat_Buf.st_mtime;
+ //
+ // Get Output file data
+ //
+ OutputFileLength = _filelength (fileno (fpOut));
+ OutputFileBuffer = malloc (OutputFileLength);
+ if (OutputFileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ fclose (fpOut);
+ fpOut = NULL;
+ goto Finish;
+ }
+ fread (OutputFileBuffer, 1, OutputFileLength, fpOut);
+ fclose (fpOut);
+ fpOut = NULL;
+ }
+ VerboseMsg ("Output file name is %s", OutImageName);
+ } else if (!ReplaceFlag && mOutImageType != DUMP_TE_HEADER) {
+ Error (NULL, 0, 1001, "Missing option", "output file");
+ goto Finish;
+ }
+
+ //
+ // Open input file and read file data into file buffer.
+ //
+ fpIn = fopen (LongFilePath (mInImageName), "rb");
+ if (fpIn == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+ //
+ // Get Iutput file time stamp
+ //
+ fstat(fileno (fpIn), &Stat_Buf);
+ InputFileTime = Stat_Buf.st_mtime;
+ //
+ // Get Input file data
+ //
+ InputFileLength = _filelength (fileno (fpIn));
+ InputFileBuffer = malloc (InputFileLength);
+ if (InputFileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ fclose (fpIn);
+ goto Finish;
+ }
+ fread (InputFileBuffer, 1, InputFileLength, fpIn);
+ fclose (fpIn);
+ DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) InputFileLength);
+
+ //
+ // Combine multi binary HII package files.
+ //
+ if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {
+ //
+ // Open output file handle.
+ //
+ fpOut = fopen (LongFilePath (OutImageName), "wb");
+ if (!fpOut) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ //
+ // Get hii package list length
+ //
+ HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ for (Index = 0; Index < InputFileNum; Index ++) {
+ fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");
+ if (fpIn == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);
+ goto Finish;
+ }
+ FileLength = _filelength (fileno (fpIn));
+ fread (&HiiPackageHeader, 1, sizeof (HiiPackageHeader), fpIn);
+ if (HiiPackageHeader.Type == EFI_HII_PACKAGE_FORM) {
+ if (HiiPackageHeader.Length != FileLength) {
+ Error (NULL, 0, 3000, "Invalid", "The wrong package size is in HII package file %s", InputFileName [Index]);
+ fclose (fpIn);
+ goto Finish;
+ }
+ if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {
+ fread (&IfrFormSet, 1, sizeof (IfrFormSet), fpIn);
+ memcpy (&HiiPackageListGuid, &IfrFormSet.Guid, sizeof (EFI_GUID));
+ }
+ NumberOfFormPackage ++;
+ }
+ HiiPackageListHeader.PackageLength += FileLength;
+ fclose (fpIn);
+ }
+ HiiPackageListHeader.PackageLength += sizeof (EndPackage);
+ //
+ // Check whether hii packages are valid
+ //
+ if (NumberOfFormPackage > 1) {
+ Error (NULL, 0, 3000, "Invalid", "The input hii packages contains more than one hii form package");
+ goto Finish;
+ }
+ if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {
+ Error (NULL, 0, 3000, "Invalid", "HII package list guid is not specified!");
+ goto Finish;
+ }
+ memcpy (&HiiPackageListHeader.PackageListGuid, &HiiPackageListGuid, sizeof (EFI_GUID));
+ //
+ // read hii packages
+ //
+ HiiPackageListBuffer = malloc (HiiPackageListHeader.PackageLength);
+ if (HiiPackageListBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+ memcpy (HiiPackageListBuffer, &HiiPackageListHeader, sizeof (HiiPackageListHeader));
+ HiiPackageDataPointer = HiiPackageListBuffer + sizeof (HiiPackageListHeader);
+ for (Index = 0; Index < InputFileNum; Index ++) {
+ fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");
+ if (fpIn == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);
+ free (HiiPackageListBuffer);
+ goto Finish;
+ }
+
+ FileLength = _filelength (fileno (fpIn));
+ fread (HiiPackageDataPointer, 1, FileLength, fpIn);
+ fclose (fpIn);
+ HiiPackageDataPointer = HiiPackageDataPointer + FileLength;
+ }
+ memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));
+
+ //
+ // write the hii package into the binary package list file with the resource section header
+ //
+ if (mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {
+ //
+ // Create the resource section header
+ //
+ HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength);
+ if (HiiSectionHeader == NULL) {
+ free (HiiPackageListBuffer);
+ goto Finish;
+ }
+ //
+ // Wrtie section header and HiiData into File.
+ //
+ fwrite (HiiSectionHeader, 1, HiiSectionHeaderSize, fpOut);
+ fwrite (HiiPackageListBuffer, 1, HiiPackageListHeader.PackageLength, fpOut);
+ //
+ // Free allocated resources.
+ //
+ free (HiiSectionHeader);
+ free (HiiPackageListBuffer);
+ //
+ // Done successfully
+ //
+ goto Finish;
+ }
+
+ //
+ // write the hii package into the text package list rc file.
+ //
+ if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {
+ for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {
+ fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);
+ }
+ fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);
+
+ HiiPackageDataPointer = HiiPackageListBuffer;
+ for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {
+ if (Index % 16 == 0) {
+ fprintf (fpOut, "\n ");
+ }
+ fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);
+ HiiPackageDataPointer += 2;
+ }
+
+ if (Index % 16 == 0) {
+ fprintf (fpOut, "\n ");
+ }
+ if ((Index + 2) == HiiPackageListHeader.PackageLength) {
+ fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);
+ }
+ if ((Index + 1) == HiiPackageListHeader.PackageLength) {
+ fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);
+ }
+ free (HiiPackageListBuffer);
+ //
+ // Done successfully
+ //
+ goto Finish;
+ }
+ }
+
+ //
+ // Combine MciBinary files to one file
+ //
+ if (mOutImageType == FW_MERGE_IMAGE) {
+ //
+ // Open output file handle.
+ //
+ fpOut = fopen (LongFilePath (OutImageName), "wb");
+ if (!fpOut) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ for (Index = 0; Index < InputFileNum; Index ++) {
+ fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");
+ if (!fpIn) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);
+ goto Finish;
+ }
+
+ FileLength = _filelength (fileno (fpIn));
+ FileBuffer = malloc (FileLength);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ fclose (fpIn);
+ goto Finish;
+ }
+
+ fread (FileBuffer, 1, FileLength, fpIn);
+ fclose (fpIn);
+ //
+ // write input file to out file
+ //
+ fwrite (FileBuffer, 1, FileLength, fpOut);
+ //
+ // write pad value to out file.
+ //
+ while (FileLength ++ % MciAlignment != 0) {
+ fwrite (&MciPadValue, 1, 1, fpOut);
+ }
+ //
+ // free allocated memory space
+ //
+ free (FileBuffer);
+ FileBuffer = NULL;
+ }
+ //
+ // Done successfully
+ //
+ goto Finish;
+ }
+
+ //
+ // Convert MicroCode.txt file to MicroCode.bin file
+ //
+ if (mOutImageType == FW_MCI_IMAGE) {
+ fpIn = fopen (LongFilePath (mInImageName), "r");
+ if (fpIn == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+
+ //
+ // The first pass is to determine
+ // how much data is in the file so we can allocate a working buffer.
+ //
+ FileLength = 0;
+ do {
+ Status = MicrocodeReadData (fpIn, &Data);
+ if (Status == STATUS_SUCCESS) {
+ FileLength += sizeof (Data);
+ }
+ if (Status == STATUS_IGNORE) {
+ Status = STATUS_SUCCESS;
+ }
+ } while (Status == STATUS_SUCCESS);
+ //
+ // Error if no data.
+ //
+ if (FileLength == 0) {
+ Error (NULL, 0, 3000, "Invalid", "no parseable data found in file %s", mInImageName);
+ goto Finish;
+ }
+ if (FileLength < sizeof (MICROCODE_IMAGE_HEADER)) {
+ Error (NULL, 0, 3000, "Invalid", "amount of parseable data in %s is insufficient to contain a microcode header", mInImageName);
+ goto Finish;
+ }
+
+ //
+ // Allocate a buffer for the data
+ //
+ FileBuffer = malloc (FileLength);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+ //
+ // Re-read the file, storing the data into our buffer
+ //
+ fseek (fpIn, 0, SEEK_SET);
+ DataPointer = (UINT32 *) FileBuffer;
+ OldDataPointer = DataPointer;
+ do {
+ OldDataPointer = DataPointer;
+ Status = MicrocodeReadData (fpIn, DataPointer++);
+ if (Status == STATUS_IGNORE) {
+ DataPointer = OldDataPointer;
+ Status = STATUS_SUCCESS;
+ }
+ } while (Status == STATUS_SUCCESS);
+ //
+ // close input file after read data
+ //
+ fclose (fpIn);
+
+ //
+ // Can't do much checking on the header because, per the spec, the
+ // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,
+ // and the TotalSize field is invalid (actually missing). Thus we can't
+ // even verify the Reserved fields are 0.
+ //
+ MciHeader = (MICROCODE_IMAGE_HEADER *) FileBuffer;
+ if (MciHeader->DataSize == 0) {
+ Index = 2048;
+ } else {
+ Index = MciHeader->TotalSize;
+ }
+
+ if (Index != FileLength) {
+ Error (NULL, 0, 3000, "Invalid", "file length of %s (0x%x) does not equal expected TotalSize: 0x%04X.", mInImageName, (unsigned) FileLength, (unsigned) Index);
+ goto Finish;
+ }
+
+ //
+ // Checksum the contents
+ //
+ DataPointer = (UINT32 *) FileBuffer;
+ CheckSum = 0;
+ Index = 0;
+ while (Index < FileLength) {
+ CheckSum += *DataPointer;
+ DataPointer ++;
+ Index += sizeof (*DataPointer);
+ }
+ if (CheckSum != 0) {
+ Error (NULL, 0, 3000, "Invalid", "checksum (0x%x) failed on file %s.", (unsigned) CheckSum, mInImageName);
+ goto Finish;
+ }
+ //
+ // Open the output file and write the buffer contents
+ //
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ goto WriteFile;
+ }
+
+ //
+ // Open input file and read file data into file buffer.
+ //
+ FileLength = InputFileLength;
+ FileBuffer = malloc (FileLength);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+ memcpy (FileBuffer, InputFileBuffer, InputFileLength);
+
+ //
+ // Dump TeImage Header into output file.
+ //
+ if (mOutImageType == DUMP_TE_HEADER) {
+ memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader));
+ if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "TE header signature of file %s is not correct.", mInImageName);
+ goto Finish;
+ }
+ //
+ // Open the output file handle.
+ //
+ if (ReplaceFlag) {
+ fpInOut = fopen (LongFilePath (mInImageName), "wb");
+ if (fpInOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+ } else {
+ if (OutImageName != NULL) {
+ fpOut = fopen (LongFilePath (OutImageName), "wb");
+ } else {
+ fpOut = stdout;
+ }
+ if (fpOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ }
+ if (fpInOut != NULL) {
+ fprintf (fpInOut, "Dump of file %s\n\n", mInImageName);
+ fprintf (fpInOut, "TE IMAGE HEADER VALUES\n");
+ fprintf (fpInOut, "%17X machine\n", TEImageHeader.Machine);
+ fprintf (fpInOut, "%17X number of sections\n", TEImageHeader.NumberOfSections);
+ fprintf (fpInOut, "%17X subsystems\n", TEImageHeader.Subsystem);
+ fprintf (fpInOut, "%17X stripped size\n", TEImageHeader.StrippedSize);
+ fprintf (fpInOut, "%17X entry point\n", (unsigned) TEImageHeader.AddressOfEntryPoint);
+ fprintf (fpInOut, "%17X base of code\n", (unsigned) TEImageHeader.BaseOfCode);
+ fprintf (fpInOut, "%17llX image base\n", (unsigned long long)TEImageHeader.ImageBase);
+ fprintf (fpInOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);
+ fprintf (fpInOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);
+ }
+ if (fpOut != NULL) {
+ fprintf (fpOut, "Dump of file %s\n\n", mInImageName);
+ fprintf (fpOut, "TE IMAGE HEADER VALUES\n");
+ fprintf (fpOut, "%17X machine\n", TEImageHeader.Machine);
+ fprintf (fpOut, "%17X number of sections\n", TEImageHeader.NumberOfSections);
+ fprintf (fpOut, "%17X subsystems\n", TEImageHeader.Subsystem);
+ fprintf (fpOut, "%17X stripped size\n", TEImageHeader.StrippedSize);
+ fprintf (fpOut, "%17X entry point\n", (unsigned) TEImageHeader.AddressOfEntryPoint);
+ fprintf (fpOut, "%17X base of code\n", (unsigned) TEImageHeader.BaseOfCode);
+ fprintf (fpOut, "%17llX image base\n", (unsigned long long)TEImageHeader.ImageBase);
+ fprintf (fpOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);
+ fprintf (fpOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);
+ }
+ goto Finish;
+ }
+
+ //
+ // Following code to convert dll to efi image or te image.
+ // Get new image type
+ //
+ if ((mOutImageType == FW_EFI_IMAGE) || (mOutImageType == FW_TE_IMAGE)) {
+ if (ModuleType == NULL) {
+ if (mOutImageType == FW_EFI_IMAGE) {
+ Error (NULL, 0, 1001, "Missing option", "EFI_FILETYPE");
+ goto Finish;
+ } else if (mOutImageType == FW_TE_IMAGE) {
+ //
+ // Default TE Image Type is Boot service driver
+ //
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi boot service driver.");
+ }
+ } else {
+ if (stricmp (ModuleType, "BASE") == 0 ||
+ stricmp (ModuleType, "SEC") == 0 ||
+ stricmp (ModuleType, "SECURITY_CORE") == 0 ||
+ stricmp (ModuleType, "PEI_CORE") == 0 ||
+ stricmp (ModuleType, "PEIM") == 0 ||
+ stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 ||
+ stricmp (ModuleType, "PIC_PEIM") == 0 ||
+ stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 ||
+ stricmp (ModuleType, "DXE_CORE") == 0 ||
+ stricmp (ModuleType, "BS_DRIVER") == 0 ||
+ stricmp (ModuleType, "DXE_DRIVER") == 0 ||
+ stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||
+ stricmp (ModuleType, "UEFI_DRIVER") == 0 ||
+ stricmp (ModuleType, "SMM_CORE") == 0 ||
+ stricmp (ModuleType, "MM_STANDALONE") == 0 ||
+ stricmp (ModuleType, "MM_CORE_STANDALONE") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi boot service driver.");
+
+ } else if (stricmp (ModuleType, "UEFI_APPLICATION") == 0 ||
+ stricmp (ModuleType, "APPLICATION") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
+ VerboseMsg ("Efi Image subsystem type is efi application.");
+
+ } else if (stricmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0 ||
+ stricmp (ModuleType, "RT_DRIVER") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi runtime driver.");
+
+ } else if (stricmp (ModuleType, "DXE_SAL_DRIVER") == 0 ||
+ stricmp (ModuleType, "SAL_RT_DRIVER") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");
+
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "EFI_FILETYPE = %s", ModuleType);
+ goto Finish;
+ }
+ }
+ }
+
+ //
+ // Convert ELF image to PeImage
+ //
+ if (IsElfHeader(FileBuffer)) {
+ VerboseMsg ("Convert %s from ELF to PE/COFF.", mInImageName);
+ if (!ConvertElf(&FileBuffer, &FileLength)) {
+ Error (NULL, 0, 3000, "Invalid", "Unable to convert %s from ELF to PE/COFF.", mInImageName);
+ goto Finish;
+ }
+ }
+
+ //
+ // Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP
+ // XIP == eXecute In Place
+ //
+ PeCoffConvertImageToXip (&FileBuffer, &FileLength);
+
+ //
+ // Remove reloc section from PE or TE image
+ //
+ if (mOutImageType == FW_RELOC_STRIPEED_IMAGE) {
+ //
+ // Check TeImage
+ //
+ TeHdr = (EFI_TE_IMAGE_HEADER *) FileBuffer;
+ if (TeHdr->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TeHdr + 1);
+ for (Index = 0; Index < TeHdr->NumberOfSections; Index ++, SectionHeader ++) {
+ if (strcmp ((char *)SectionHeader->Name, ".reloc") == 0) {
+ //
+ // Check the reloc section is in the end of image.
+ //
+ if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) ==
+ (FileLength + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER))) {
+ //
+ // Remove .reloc section and update TeImage Header
+ //
+ FileLength = FileLength - SectionHeader->SizeOfRawData;
+ SectionHeader->SizeOfRawData = 0;
+ SectionHeader->Misc.VirtualSize = 0;
+ TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;
+ TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;
+ break;
+ }
+ }
+ }
+ } else {
+ //
+ // Check PE Image
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer;
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer);
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "TE and DOS header signatures were not found in %s image.", mInImageName);
+ goto Finish;
+ }
+ DosHdr = NULL;
+ } else {
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + DosHdr->e_lfanew);
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "PE header signature was not found in %s image.", mInImageName);
+ goto Finish;
+ }
+ }
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ if (strcmp ((char *)SectionHeader->Name, ".reloc") == 0) {
+ //
+ // Check the reloc section is in the end of image.
+ //
+ if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) == FileLength) {
+ //
+ // Remove .reloc section and update PeImage Header
+ //
+ FileLength = FileLength - SectionHeader->SizeOfRawData;
+
+ PeHdr->Pe32.FileHeader.Characteristics |= EFI_IMAGE_FILE_RELOCS_STRIPPED;
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;
+ Optional32->SizeOfImage -= SectionHeader->SizeOfRawData;
+ Optional32->SizeOfInitializedData -= SectionHeader->SizeOfRawData;
+ if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;
+ }
+ }
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;
+ Optional64->SizeOfImage -= SectionHeader->SizeOfRawData;
+ Optional64->SizeOfInitializedData -= SectionHeader->SizeOfRawData;
+ if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;
+ }
+ }
+ SectionHeader->Misc.VirtualSize = 0;
+ SectionHeader->SizeOfRawData = 0;
+ break;
+ }
+ }
+ }
+ }
+ //
+ // Write file
+ //
+ goto WriteFile;
+ }
+ //
+ // Read the dos & pe hdrs of the image
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ // NO DOS header, check for PE/COFF header
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer);
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "DOS header signature was not found in %s image.", mInImageName);
+ goto Finish;
+ }
+ DosHdr = NULL;
+ } else {
+
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + DosHdr->e_lfanew);
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ Error (NULL, 0, 3000, "Invalid", "PE header signature was not found in %s image.", mInImageName);
+ goto Finish;
+ }
+ }
+
+ if (PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARM) {
+ // Some tools kick out IMAGE_FILE_MACHINE_ARM (0x1c0) vs IMAGE_FILE_MACHINE_ARMT (0x1c2)
+ // so patch back to the official UEFI value.
+ PeHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMT;
+ }
+
+ //
+ // Set new base address into image
+ //
+ if (mOutImageType == FW_REBASE_IMAGE || mOutImageType == FW_SET_ADDRESS_IMAGE) {
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ if (NewBaseAddress >= 0x100000000ULL) {
+ Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image");
+ goto Finish;
+ }
+ }
+
+ if (NegativeAddr) {
+ //
+ // Set Base Address to a negative value.
+ //
+ NewBaseAddress = (UINT64) (0 - NewBaseAddress);
+ }
+ if (mOutImageType == FW_REBASE_IMAGE) {
+ Status = RebaseImage (mInImageName, FileBuffer, NewBaseAddress);
+ } else {
+ Status = SetAddressToSectionHeader (mInImageName, FileBuffer, NewBaseAddress);
+ }
+ if (EFI_ERROR (Status)) {
+ if (NegativeAddr) {
+ Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address -0x%llx can't success", mInImageName, 0 - NewBaseAddress);
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address 0x%llx can't success", mInImageName, NewBaseAddress);
+ }
+ goto Finish;
+ }
+
+ //
+ // Write file
+ //
+ goto WriteFile;
+ }
+
+ //
+ // Extract bin data from Pe image.
+ //
+ if (mOutImageType == FW_BIN_IMAGE) {
+ if (FileLength < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {
+ Error (NULL, 0, 3000, "Invalid", "FileSize of %s is not a legal size.", mInImageName);
+ goto Finish;
+ }
+ //
+ // Output bin data from exe file
+ //
+ FileLength = FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders;
+ memmove (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ goto WriteFile;
+ }
+
+ //
+ // Zero Debug Information of Pe Image
+ //
+ if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {
+ Status = ZeroDebugData (FileBuffer, TRUE);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Zero DebugData Error status is 0x%x", (int) Status);
+ goto Finish;
+ }
+
+ //
+ // Write the updated Image
+ //
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ goto WriteFile;
+ }
+
+ //
+ // Set Time Stamp of Pe Image
+ //
+ if (mOutImageType == FW_SET_STAMP_IMAGE) {
+ Status = SetStamp (FileBuffer, TimeStamp);
+ if (EFI_ERROR (Status)) {
+ goto Finish;
+ }
+
+ //
+ // Write the updated Image
+ //
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ goto WriteFile;
+ }
+
+ //
+ // Extract acpi data from pe image.
+ //
+ if (mOutImageType == FW_ACPI_IMAGE) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ if (strcmp ((char *)SectionHeader->Name, ".data") == 0 || strcmp ((char *)SectionHeader->Name, ".sdata") == 0) {
+ //
+ // Check Acpi Table
+ //
+ if (SectionHeader->Misc.VirtualSize < SectionHeader->SizeOfRawData) {
+ FileLength = SectionHeader->Misc.VirtualSize;
+ } else {
+ FileLength = SectionHeader->SizeOfRawData;
+ }
+
+ if (CheckAcpiTable (FileBuffer + SectionHeader->PointerToRawData, FileLength) != STATUS_SUCCESS) {
+ Error (NULL, 0, 3000, "Invalid", "ACPI table check failed in %s.", mInImageName);
+ goto Finish;
+ }
+
+ //
+ // Output Apci data to file
+ //
+ memmove (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ goto WriteFile;
+ }
+ }
+ Error (NULL, 0, 3000, "Invalid", "failed to get ACPI table from %s.", mInImageName);
+ goto Finish;
+ }
+ //
+ // Zero all unused fields of the DOS header
+ //
+ if (DosHdr != NULL) {
+ memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER));
+ memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));
+ DosHdr->e_magic = BackupDosHdr.e_magic;
+ DosHdr->e_lfanew = BackupDosHdr.e_lfanew;
+
+ for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (UINT32 ) DosHdr->e_lfanew; Index++) {
+ FileBuffer[Index] = (UINT8) DosHdr->e_cp;
+ }
+ }
+
+ //
+ // Initialize TeImage Header
+ //
+ memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER));
+ TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE;
+ TEImageHeader.Machine = PeHdr->Pe32.FileHeader.Machine;
+ TEImageHeader.NumberOfSections = (UINT8) PeHdr->Pe32.FileHeader.NumberOfSections;
+ TEImageHeader.StrippedSize = (UINT16) ((UINTN) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader) - (UINTN) FileBuffer);
+ TEImageHeader.Subsystem = (UINT8) Type;
+
+ //
+ // Patch the PE header
+ //
+ PeHdr->Pe32.OptionalHeader.Subsystem = (UINT16) Type;
+
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;
+ if (!KeepOptionalHeaderFlag) {
+ Optional32->MajorOperatingSystemVersion = 0;
+ Optional32->MinorOperatingSystemVersion = 0;
+ Optional32->MajorImageVersion = 0;
+ Optional32->MinorImageVersion = 0;
+ Optional32->MajorSubsystemVersion = 0;
+ Optional32->MinorSubsystemVersion = 0;
+ Optional32->Win32VersionValue = 0;
+ Optional32->CheckSum = 0;
+ Optional32->SizeOfStackReserve = 0;
+ Optional32->SizeOfStackCommit = 0;
+ Optional32->SizeOfHeapReserve = 0;
+ Optional32->SizeOfHeapCommit = 0;
+ }
+ TEImageHeader.AddressOfEntryPoint = Optional32->AddressOfEntryPoint;
+ TEImageHeader.BaseOfCode = Optional32->BaseOfCode;
+ TEImageHeader.ImageBase = (UINT64) (Optional32->ImageBase);
+
+ if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ }
+
+ if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ }
+
+ //
+ // Zero .pdata section data.
+ //
+ if (!KeepExceptionTableFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
+ if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
+ //
+ // Zero .pdata Section data
+ //
+ memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData);
+ //
+ // Zero .pdata Section header name
+ //
+ memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));
+ //
+ // Zero Exception Table
+ //
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
+ DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL);
+ break;
+ }
+ }
+ }
+
+ //
+ // Strip zero padding at the end of the .reloc section
+ //
+ if (!KeepZeroPendingFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ if (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
+ //
+ // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory
+ //
+ if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
+ SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ AllignedRelocSize = (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1));
+ //
+ // Check to see if there is zero padding at the end of the base relocations
+ //
+ if (AllignedRelocSize < SectionHeader->SizeOfRawData) {
+ //
+ // Check to see if the base relocations are at the end of the file
+ //
+ if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) {
+ //
+ // All the required conditions are met to strip the zero padding of the end of the base relocations section
+ //
+ Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);
+ Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);
+ SectionHeader->SizeOfRawData = AllignedRelocSize;
+ FileLength = Optional32->SizeOfImage;
+ DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize));
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;
+ if (!KeepOptionalHeaderFlag) {
+ Optional64->MajorOperatingSystemVersion = 0;
+ Optional64->MinorOperatingSystemVersion = 0;
+ Optional64->MajorImageVersion = 0;
+ Optional64->MinorImageVersion = 0;
+ Optional64->MajorSubsystemVersion = 0;
+ Optional64->MinorSubsystemVersion = 0;
+ Optional64->Win32VersionValue = 0;
+ Optional64->CheckSum = 0;
+ Optional64->SizeOfStackReserve = 0;
+ Optional64->SizeOfStackCommit = 0;
+ Optional64->SizeOfHeapReserve = 0;
+ Optional64->SizeOfHeapCommit = 0;
+ }
+ TEImageHeader.AddressOfEntryPoint = Optional64->AddressOfEntryPoint;
+ TEImageHeader.BaseOfCode = Optional64->BaseOfCode;
+ TEImageHeader.ImageBase = (UINT64) (Optional64->ImageBase);
+
+ if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ }
+
+ if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ }
+
+ //
+ // Zero the .pdata section for X64 machine and don't check the Debug Directory is empty
+ // For Itaninum and X64 Image, remove .pdata section.
+ //
+ if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64)) {
+ if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
+ if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
+ //
+ // Zero .pdata Section header name
+ //
+ memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));
+
+ RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);
+ for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {
+ if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {
+ UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));
+ if (UnwindInfo->Version == 1) {
+ memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));
+ memset (UnwindInfo, 0, sizeof (UNWIND_INFO));
+ }
+ break;
+ }
+ }
+ memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));
+ }
+ //
+ // Zero Exception Table
+ //
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
+ DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL);
+ break;
+ }
+ }
+ }
+ }
+
+ //
+ // Strip zero padding at the end of the .reloc section
+ //
+ if (!KeepZeroPendingFlag && Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ if (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
+ //
+ // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory
+ //
+ if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
+ SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ AllignedRelocSize = (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1));
+ //
+ // Check to see if there is zero padding at the end of the base relocations
+ //
+ if (AllignedRelocSize < SectionHeader->SizeOfRawData) {
+ //
+ // Check to see if the base relocations are at the end of the file
+ //
+ if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) {
+ //
+ // All the required conditions are met to strip the zero padding of the end of the base relocations section
+ //
+ Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);
+ Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);
+ SectionHeader->SizeOfRawData = AllignedRelocSize;
+ FileLength = Optional64->SizeOfImage;
+ DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize));
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Magic 0x%x of PeImage %s is unknown.", PeHdr->Pe32.OptionalHeader.Magic, mInImageName);
+ goto Finish;
+ }
+
+ if (((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) == 0) && \
+ (TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0) && \
+ (TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)) {
+ //
+ // PeImage can be loaded into memory, but it has no relocation section.
+ // Fix TeImage Header to set VA of relocation data directory to not zero, the size is still zero.
+ //
+ if (Optional32 != NULL) {
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);
+ } else if (Optional64 != NULL) {
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);
+ }
+ }
+
+ //
+ // Fill HII section data
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {
+ if (stricmp ((char *)SectionHeader[Index].Name, ".hii") == 0) {
+ //
+ // Update resource section header offset
+ //
+ SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress);
+ //
+ // Update resource section name
+ //
+ strcpy((char *) SectionHeader[Index].Name, ".rsrc");
+ //
+ // Update resource data directory.
+ //
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;
+ } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;
+ }
+ break;
+ }
+ }
+
+ //
+ // Zero ExceptionTable Xdata
+ //
+ if (!KeepExceptionTableFlag) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {
+ if (stricmp ((char *)SectionHeader[Index].Name, ".xdata") == 0) {
+ //
+ // zero .xdata section
+ //
+ memset (FileBuffer + SectionHeader[Index].PointerToRawData, 0, SectionHeader[Index].SizeOfRawData);
+ DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[Index].PointerToRawData, (unsigned) SectionHeader[Index].SizeOfRawData);
+ break;
+ }
+ }
+ }
+
+ //
+ // Zero Time/Data field
+ //
+ ZeroDebugData (FileBuffer, ZeroDebugFlag);
+
+ if (mOutImageType == FW_TE_IMAGE) {
+ if ((PeHdr->Pe32.FileHeader.NumberOfSections &~0xFF) || (Type &~0xFF)) {
+ //
+ // Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both.
+ //
+ Error (NULL, 0, 3000, "Invalid", "Image's subsystem or NumberOfSections of PeImage %s cannot be packed into 1 byte.", mInImageName);
+ goto Finish;
+ }
+
+ if ((PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment)) {
+ //
+ // TeImage has the same section alignment and file alignment.
+ //
+ Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment of PeImage %s do not match, they must be equal for a TeImage.", mInImageName);
+ goto Finish;
+ }
+
+ DebugMsg (NULL, 0, 9, "TeImage Header Info", "Machine type is %X, Number of sections is %X, Stripped size is %X, EntryPoint is %X, BaseOfCode is %X, ImageBase is %llX",
+ TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase);
+ //
+ // Update Image to TeImage
+ //
+ FileLength = FileLength - TEImageHeader.StrippedSize;
+ memmove (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);
+ FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER);
+ memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER));
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength));
+ } else {
+
+ //
+ // Following codes are to fix the objcopy's issue:
+ // objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section
+ // It cause issue for EFI image which has no ".reloc" sections.
+ // Following codes will be removed when objcopy in binutil fix this problem for PE image.
+ //
+ if ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;
+ if (Optional32->ImageBase == 0) {
+ PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;
+ }
+ } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;
+ if (Optional64->ImageBase == 0) {
+ PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;
+ }
+ }
+ }
+ }
+
+WriteFile:
+ //
+ // Update Image to EfiImage or TE image
+ //
+ if (ReplaceFlag) {
+ if ((FileLength != InputFileLength) || (memcmp (FileBuffer, InputFileBuffer, FileLength) != 0)) {
+ //
+ // Update File when File is changed.
+ //
+ fpInOut = fopen (LongFilePath (mInImageName), "wb");
+ if (fpInOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+ fwrite (FileBuffer, 1, FileLength, fpInOut);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ }
+ } else {
+ if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {
+ //
+ // Update File when File is changed or File is old.
+ //
+ fpOut = fopen (LongFilePath (OutImageName), "wb");
+ if (fpOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ fwrite (FileBuffer, 1, FileLength, fpOut);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ }
+ }
+ mImageSize = FileLength;
+
+Finish:
+ if (fpInOut != NULL) {
+ if (GetUtilityStatus () != STATUS_SUCCESS) {
+ //
+ // when file updates failed, original file is still recovered.
+ //
+ fwrite (InputFileBuffer, 1, InputFileLength, fpInOut);
+ }
+ //
+ // Write converted data into fpInOut file and close input file.
+ //
+ fclose (fpInOut);
+ }
+
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+
+ if (InputFileName != NULL) {
+ free (InputFileName);
+ }
+
+ if (fpOut != NULL) {
+ //
+ // Write converted data into fpOut file and close output file.
+ //
+ fclose (fpOut);
+ if (GetUtilityStatus () != STATUS_SUCCESS) {
+ if (OutputFileBuffer == NULL) {
+ remove (OutImageName);
+ } else {
+ fpOut = fopen (LongFilePath (OutImageName), "wb");
+ fwrite (OutputFileBuffer, 1, OutputFileLength, fpOut);
+ fclose (fpOut);
+ }
+ }
+ }
+
+ if (InputFileBuffer != NULL) {
+ free (InputFileBuffer);
+ }
+
+ if (OutputFileBuffer != NULL) {
+ free (OutputFileBuffer);
+ }
+
+ //
+ // Write module size and time stamp to report file.
+ //
+ if (OutImageName != NULL) {
+ FileLen = strlen (OutImageName);
+ }
+ if (FileLen >= 4 && strcmp (OutImageName + (FileLen - 4), ".efi") == 0) {
+ ReportFileName = (CHAR8 *) malloc (FileLen + 1);
+ if (ReportFileName != NULL) {
+ strcpy (ReportFileName, OutImageName);
+ strcpy (ReportFileName + (FileLen - 4), ".txt");
+ ReportFile = fopen (LongFilePath (ReportFileName), "w+");
+ if (ReportFile != NULL) {
+ fprintf (ReportFile, "MODULE_SIZE = %u\n", (unsigned) mImageSize);
+ fprintf (ReportFile, "TIME_STAMP = %u\n", (unsigned) mImageTimeStamp);
+ fclose(ReportFile);
+ }
+ free (ReportFileName);
+ }
+ }
+ VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
+
+ return GetUtilityStatus ();
+}
+
+STATIC
+EFI_STATUS
+ZeroDebugData (
+ IN OUT UINT8 *FileBuffer,
+ BOOLEAN ZeroDebugFlag
+ )
+/*++
+
+Routine Description:
+
+ Zero debug information in PeImage.
+
+Arguments:
+
+ FileBuffer - Pointer to PeImage.
+ ZeroDebugFlag - TRUE to zero Debug information, FALSE to only zero time/stamp
+
+Returns:
+
+ EFI_ABORTED - PeImage is invalid.
+ EFI_SUCCESS - Zero debug data successfully.
+
+--*/
+{
+ UINT32 Index;
+ UINT32 DebugDirectoryEntryRva;
+ UINT32 DebugDirectoryEntrySize;
+ UINT32 DebugDirectoryEntryFileOffset;
+ UINT32 ExportDirectoryEntryRva;
+ UINT32 ExportDirectoryEntryFileOffset;
+ UINT32 ResourceDirectoryEntryRva;
+ UINT32 ResourceDirectoryEntryFileOffset;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_FILE_HEADER *FileHdr;
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr;
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *RsdsEntry;
+ UINT32 *NewTimeStamp;
+
+ //
+ // Init variable.
+ //
+ DebugDirectoryEntryRva = 0;
+ DebugDirectoryEntrySize = 0;
+ ExportDirectoryEntryRva = 0;
+ ResourceDirectoryEntryRva = 0;
+ DebugDirectoryEntryFileOffset = 0;
+ ExportDirectoryEntryFileOffset = 0;
+ ResourceDirectoryEntryFileOffset = 0;
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer;
+ FileHdr = (EFI_IMAGE_FILE_HEADER *) (FileBuffer + DosHdr->e_lfanew + sizeof (UINT32));
+
+
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ // NO DOS header, must start with PE/COFF header
+ FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32));
+ } else {
+ FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof (UINT32));
+ }
+
+ //
+ // Get Debug, Export and Resource EntryTable RVA address.
+ // Resource Directory entry need to review.
+ //
+ Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
+ Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
+ if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
+ ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ }
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {
+ ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
+ }
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {
+ DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ DebugDirectoryEntrySize = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ if (ZeroDebugFlag) {
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;
+ }
+ }
+ } else {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
+ ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ }
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {
+ ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
+ }
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {
+ DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ DebugDirectoryEntrySize = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ if (ZeroDebugFlag) {
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;
+ }
+ }
+ }
+
+ //
+ // Get DirectoryEntryTable file offset.
+ //
+ for (Index = 0; Index < FileHdr->NumberOfSections; Index ++, SectionHeader ++) {
+ if (DebugDirectoryEntryRva >= SectionHeader->VirtualAddress &&
+ DebugDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {
+ DebugDirectoryEntryFileOffset =
+ DebugDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
+ }
+ if (ExportDirectoryEntryRva >= SectionHeader->VirtualAddress &&
+ ExportDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {
+ ExportDirectoryEntryFileOffset =
+ ExportDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
+ }
+ if (ResourceDirectoryEntryRva >= SectionHeader->VirtualAddress &&
+ ResourceDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {
+ ResourceDirectoryEntryFileOffset =
+ ResourceDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
+ }
+ }
+
+ //
+ //Zero Debug Data and TimeStamp
+ //
+ FileHdr->TimeDateStamp = 0;
+ mImageTimeStamp = 0;
+ if (ExportDirectoryEntryFileOffset != 0) {
+ NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));
+ *NewTimeStamp = 0;
+ }
+
+ if (ResourceDirectoryEntryFileOffset != 0) {
+ NewTimeStamp = (UINT32 *) (FileBuffer + ResourceDirectoryEntryFileOffset + sizeof (UINT32));
+ *NewTimeStamp = 0;
+ }
+
+ if (DebugDirectoryEntryFileOffset != 0) {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + DebugDirectoryEntryFileOffset);
+ Index = 0;
+ for (Index=0; Index < DebugDirectoryEntrySize / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); Index ++, DebugEntry ++) {
+ DebugEntry->TimeDateStamp = 0;
+ if (mIsConvertXip) {
+ DebugEntry->FileOffset = DebugEntry->RVA;
+ }
+ if (ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);
+ memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
+ }
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ RsdsEntry = (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *) (FileBuffer + DebugEntry->FileOffset);
+ if (RsdsEntry->Signature == CODEVIEW_SIGNATURE_MTOC) {
+ // MTOC sets DebugDirectoryEntrySize to size of the .debug section, so fix it.
+ if (!ZeroDebugFlag) {
+ if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ } else {
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SetStamp (
+ IN OUT UINT8 *FileBuffer,
+ IN CHAR8 *TimeStamp
+ )
+/*++
+
+Routine Description:
+
+ Set new time stamp into PeImage FileHdr and Directory table:
+ Debug, Export and Resource.
+
+Arguments:
+
+ FileBuffer - Pointer to PeImage.
+ TimeStamp - Time stamp string.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - TimeStamp format is not recognized.
+ EFI_SUCCESS - Set new time stamp in this image successfully.
+
+--*/
+{
+ struct tm stime;
+ struct tm *ptime;
+ time_t newtime;
+ UINT32 Index;
+ UINT32 DebugDirectoryEntryRva;
+ UINT32 DebugDirectoryEntryFileOffset;
+ UINT32 ExportDirectoryEntryRva;
+ UINT32 ExportDirectoryEntryFileOffset;
+ UINT32 ResourceDirectoryEntryRva;
+ UINT32 ResourceDirectoryEntryFileOffset;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_FILE_HEADER *FileHdr;
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr;
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ UINT32 *NewTimeStamp;
+
+ //
+ // Init variable.
+ //
+ DebugDirectoryEntryRva = 0;
+ DebugDirectoryEntryFileOffset = 0;
+ ExportDirectoryEntryRva = 0;
+ ExportDirectoryEntryFileOffset = 0;
+ ResourceDirectoryEntryRva = 0;
+ ResourceDirectoryEntryFileOffset = 0;
+ //
+ // Get time and date that will be set.
+ //
+ if (TimeStamp == NULL) {
+ Error (NULL, 0, 3000, "Invalid", "TimeStamp cannot be NULL.");
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // compare the value with "NOW", if yes, current system time is set.
+ //
+ if (stricmp (TimeStamp, "NOW") == 0) {
+ //
+ // get system current time and date
+ //
+ time (&newtime);
+ } else {
+ //
+ // Check Time Format strictly yyyy-mm-dd 00:00:00
+ //
+ for (Index = 0; TimeStamp[Index] != '\0' && Index < 20; Index ++) {
+ if (Index == 4 || Index == 7) {
+ if (TimeStamp[Index] == '-') {
+ continue;
+ }
+ } else if (Index == 13 || Index == 16) {
+ if (TimeStamp[Index] == ':') {
+ continue;
+ }
+ } else if (Index == 10 && TimeStamp[Index] == ' ') {
+ continue;
+ } else if ((TimeStamp[Index] < '0') || (TimeStamp[Index] > '9')) {
+ break;
+ }
+ }
+
+ if (Index < 19 || TimeStamp[19] != '\0') {
+ Error (NULL, 0, 1003, "Invalid option value", "Incorrect Time \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // get the date and time from TimeStamp
+ //
+ if (sscanf (TimeStamp, "%d-%d-%d %d:%d:%d",
+ &stime.tm_year,
+ &stime.tm_mon,
+ &stime.tm_mday,
+ &stime.tm_hour,
+ &stime.tm_min,
+ &stime.tm_sec
+ ) != 6) {
+ Error (NULL, 0, 1003, "Invalid option value", "Incorrect Tiem \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // in struct, Month (0 - 11; Jan = 0). So decrease 1 from it
+ //
+ if (stime.tm_mon <= 0 || stime.tm_mday <=0) {
+ Error (NULL, 0, 3000, "Invalid", "%s Invalid date!", TimeStamp);
+ return EFI_INVALID_PARAMETER;
+ }
+ stime.tm_mon -= 1;
+
+ //
+ // in struct, Year (current year minus 1900)
+ // and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038
+ //
+ //
+ // convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038)
+ //
+ if (stime.tm_year >= 1970 && stime.tm_year <= 2038) {
+ //
+ // convert 1970 -> 70, 2000 -> 100, ...
+ //
+ stime.tm_year -= 1900;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "%s Invalid or unsupported datetime!", TimeStamp);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // convert the date and time to time_t format
+ //
+ newtime = mktime (&stime);
+ if (newtime == (time_t) - 1) {
+ Error (NULL, 0, 3000, "Invalid", "%s Invalid or unsupported datetime!", TimeStamp);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ ptime = localtime (&newtime);
+ if (ptime != NULL) {
+ DebugMsg (NULL, 0, 9, "New Image Time Stamp", "%04d-%02d-%02d %02d:%02d:%02d",
+ ptime->tm_year + 1900, ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);
+ }
+ //
+ // Set new time and data into PeImage.
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ // NO DOS header, must start with PE/COFF header
+ FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32));
+ } else {
+ FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof (UINT32));
+ }
+
+ //
+ // Get Debug, Export and Resource EntryTable RVA address.
+ // Resource Directory entry need to review.
+ //
+ if (FileHdr->Machine == EFI_IMAGE_MACHINE_IA32) {
+ Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
+ ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ }
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {
+ ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
+ }
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {
+ DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ }
+ } else {
+ Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
+ ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ }
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {
+ ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
+ }
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {
+ DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ }
+ }
+
+ //
+ // Get DirectoryEntryTable file offset.
+ //
+ for (Index = 0; Index < FileHdr->NumberOfSections; Index ++, SectionHeader ++) {
+ if (DebugDirectoryEntryRva >= SectionHeader->VirtualAddress &&
+ DebugDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {
+ DebugDirectoryEntryFileOffset =
+ DebugDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
+ }
+ if (ExportDirectoryEntryRva >= SectionHeader->VirtualAddress &&
+ ExportDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {
+ ExportDirectoryEntryFileOffset =
+ ExportDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
+ }
+ if (ResourceDirectoryEntryRva >= SectionHeader->VirtualAddress &&
+ ResourceDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {
+ ResourceDirectoryEntryFileOffset =
+ ResourceDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;
+ }
+ }
+
+ //
+ // Set new stamp
+ //
+ FileHdr->TimeDateStamp = (UINT32) newtime;
+ mImageTimeStamp = (UINT32) newtime;
+ if (ExportDirectoryEntryRva != 0) {
+ NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));
+ *NewTimeStamp = (UINT32) newtime;
+ }
+
+ if (ResourceDirectoryEntryRva != 0) {
+ NewTimeStamp = (UINT32 *) (FileBuffer + ResourceDirectoryEntryFileOffset + sizeof (UINT32));
+ *NewTimeStamp = (UINT32) newtime;
+ }
+
+ if (DebugDirectoryEntryRva != 0) {
+ NewTimeStamp = (UINT32 *) (FileBuffer + DebugDirectoryEntryFileOffset + sizeof (UINT32));
+ *NewTimeStamp = (UINT32) newtime;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+STATUS
+MicrocodeReadData (
+ FILE *InFptr,
+ UINT32 *Data
+ )
+/*++
+
+Routine Description:
+ Read a 32-bit microcode data value from a text file and convert to raw binary form.
+
+Arguments:
+ InFptr - file pointer to input text file
+ Data - pointer to where to return the data parsed
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings, Data contains valid information
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ CHAR8 Line[MAX_LINE_LEN];
+ CHAR8 *cptr;
+ int ScannedData = 0;
+
+ Line[MAX_LINE_LEN - 1] = 0;
+ while (1) {
+ if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {
+ return STATUS_ERROR;
+ }
+ //
+ // If it was a binary file, then it may have overwritten our null terminator
+ //
+ if (Line[MAX_LINE_LEN - 1] != 0) {
+ return STATUS_ERROR;
+ }
+
+ //
+ // strip space
+ //
+ for (cptr = Line; *cptr && isspace((int)*cptr); cptr++) {
+ }
+
+ // Skip Blank Lines and Comment Lines
+ if ((strlen(cptr) != 0) && (*cptr != ';')) {
+ break;
+ }
+ }
+
+ // Look for
+ // dd 000000001h ; comment
+ // dd XXXXXXXX
+ // DD XXXXXXXXX
+ // DD XXXXXXXXX
+ //
+ if ((tolower((int)cptr[0]) == 'd') && (tolower((int)cptr[1]) == 'd') && isspace ((int)cptr[2])) {
+ //
+ // Skip blanks and look for a hex digit
+ //
+ cptr += 3;
+ for (; *cptr && isspace((int)*cptr); cptr++) {
+ }
+ if (isxdigit ((int)*cptr)) {
+ if (sscanf (cptr, "%X", &ScannedData) != 1) {
+ return STATUS_ERROR;
+ }
+ }
+ *Data = (UINT32) ScannedData;
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_ERROR;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.h
new file mode 100644
index 00000000..ff206497
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/GenFw.h
@@ -0,0 +1,50 @@
+/** @file
+Header file for GenFw
+
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GEN_FW_H_
+#define _GEN_FW_H_
+
+//
+// Action for this tool.
+//
+#define FW_DUMMY_IMAGE 0
+#define FW_EFI_IMAGE 1
+#define FW_TE_IMAGE 2
+#define FW_ACPI_IMAGE 3
+#define FW_BIN_IMAGE 4
+#define FW_ZERO_DEBUG_IMAGE 5
+#define FW_SET_STAMP_IMAGE 6
+#define FW_MCI_IMAGE 7
+#define FW_MERGE_IMAGE 8
+#define FW_RELOC_STRIPEED_IMAGE 9
+#define FW_HII_PACKAGE_LIST_RCIMAGE 10
+#define FW_HII_PACKAGE_LIST_BINIMAGE 11
+#define FW_REBASE_IMAGE 12
+#define FW_SET_ADDRESS_IMAGE 13
+
+#define DUMP_TE_HEADER 0x11
+
+VOID
+SetHiiResourceHeader (
+ UINT8 *HiiBinData,
+ UINT32 OffsetToFile
+ );
+
+INTN
+IsElfHeader (
+ UINT8 *FileBuffer
+ );
+
+BOOLEAN
+ConvertElf (
+ UINT8 **FileBuffer,
+ UINT32 *FileLength
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile
new file mode 100644
index 00000000..193bf3dc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile
@@ -0,0 +1,18 @@
+## @file
+# Windows makefile for 'GenFw' module build.
+#
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenFw
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = GenFw.obj ElfConvert.obj Elf32Convert.obj Elf64Convert.obj
+
+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile.kmk
new file mode 100644
index 00000000..5beae65a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/Makefile.kmk
@@ -0,0 +1,49 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI GenFw build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += GenFw
+GenFw_TEMPLATE = VBoxEfiBldProg
+GenFw_SOURCES = \
+ GenFw.c \
+ ElfConvert.c \
+ Elf32Convert.c \
+ Elf64Convert.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf32.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf32.h
new file mode 100644
index 00000000..8795fab4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf32.h
@@ -0,0 +1,252 @@
+/** @file
+Ported ELF include files from FreeBSD
+
+Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+/*-
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.2 2007/12/03 21:30:36 marius Exp $
+ */
+
+#ifndef _SYS_ELF32_H_
+#define _SYS_ELF32_H_ 1
+
+
+/*
+ * ELF definitions common to all 32-bit architectures.
+ */
+
+typedef UINT32 Elf32_Addr;
+typedef UINT16 Elf32_Half;
+typedef UINT32 Elf32_Off;
+typedef INT32 Elf32_Sword;
+typedef UINT32 Elf32_Word;
+typedef UINT64 Elf32_Lword;
+
+typedef Elf32_Word Elf32_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf32_Word Elf32_Size;
+typedef Elf32_Sword Elf32_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf32_Half e_type; /* File type. */
+ Elf32_Half e_machine; /* Machine architecture. */
+ Elf32_Word e_version; /* ELF format version. */
+ Elf32_Addr e_entry; /* Entry point. */
+ Elf32_Off e_phoff; /* Program header file offset. */
+ Elf32_Off e_shoff; /* Section header file offset. */
+ Elf32_Word e_flags; /* Architecture-specific flags. */
+ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf32_Half e_phentsize; /* Size of program header entry. */
+ Elf32_Half e_phnum; /* Number of program header entries. */
+ Elf32_Half e_shentsize; /* Size of section header entry. */
+ Elf32_Half e_shnum; /* Number of section header entries. */
+ Elf32_Half e_shstrndx; /* Section name strings section. */
+} Elf32_Ehdr;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf32_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf32_Word sh_type; /* Section type. */
+ Elf32_Word sh_flags; /* Section flags. */
+ Elf32_Addr sh_addr; /* Address in memory image. */
+ Elf32_Off sh_offset; /* Offset in file. */
+ Elf32_Word sh_size; /* Size in bytes. */
+ Elf32_Word sh_link; /* Index of a related section. */
+ Elf32_Word sh_info; /* Depends on section type. */
+ Elf32_Word sh_addralign; /* Alignment in bytes. */
+ Elf32_Word sh_entsize; /* Size of each entry in section. */
+} Elf32_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf32_Word p_type; /* Entry type. */
+ Elf32_Off p_offset; /* File offset of contents. */
+ Elf32_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf32_Addr p_paddr; /* Physical address (not used). */
+ Elf32_Word p_filesz; /* Size of contents in file. */
+ Elf32_Word p_memsz; /* Size of contents in memory. */
+ Elf32_Word p_flags; /* Access permission flags. */
+ Elf32_Word p_align; /* Alignment in memory and file. */
+} Elf32_Phdr;
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf32_Sword d_tag; /* Entry type. */
+ union {
+ Elf32_Word d_val; /* Integer value. */
+ Elf32_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf32_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf32_Addr r_offset; /* Location to be relocated. */
+ Elf32_Word r_info; /* Relocation type and symbol index. */
+} Elf32_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf32_Addr r_offset; /* Location to be relocated. */
+ Elf32_Word r_info; /* Relocation type and symbol index. */
+ Elf32_Sword r_addend; /* Addend. */
+} Elf32_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF32_R_SYM(info) ((info) >> 8)
+#define ELF32_R_TYPE(info) ((unsigned char)(info))
+
+/* Macro for constructing r_info from field values. */
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
+
+/*
+ * Note entry header
+ */
+typedef Elf_Note Elf32_Nhdr;
+
+/*
+ * Move entry
+ */
+typedef struct {
+ Elf32_Lword m_value; /* symbol value */
+ Elf32_Word m_info; /* size + index */
+ Elf32_Word m_poffset; /* symbol offset */
+ Elf32_Half m_repeat; /* repeat count */
+ Elf32_Half m_stride; /* stride info */
+} Elf32_Move;
+
+/*
+ * The macros compose and decompose values for Move.r_info
+ *
+ * sym = ELF32_M_SYM(M.m_info)
+ * size = ELF32_M_SIZE(M.m_info)
+ * M.m_info = ELF32_M_INFO(sym, size)
+ */
+#define ELF32_M_SYM(info) ((info)>>8)
+#define ELF32_M_SIZE(info) ((unsigned char)(info))
+#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ * Hardware/Software capabilities entry
+ */
+typedef struct {
+ Elf32_Word c_tag; /* how to interpret value */
+ union {
+ Elf32_Word c_val;
+ Elf32_Addr c_ptr;
+ } c_un;
+} Elf32_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf32_Word st_name; /* String table index of name. */
+ Elf32_Addr st_value; /* Symbol value. */
+ Elf32_Word st_size; /* Size of associated object. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf32_Half st_shndx; /* Section index of symbol. */
+} Elf32_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF32_ST_BIND(info) ((info) >> 4)
+#define ELF32_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3)
+
+/* Structures used by Sun & GNU symbol versioning. */
+typedef struct
+{
+ Elf32_Half vd_version;
+ Elf32_Half vd_flags;
+ Elf32_Half vd_ndx;
+ Elf32_Half vd_cnt;
+ Elf32_Word vd_hash;
+ Elf32_Word vd_aux;
+ Elf32_Word vd_next;
+} Elf32_Verdef;
+
+typedef struct
+{
+ Elf32_Word vda_name;
+ Elf32_Word vda_next;
+} Elf32_Verdaux;
+
+typedef struct
+{
+ Elf32_Half vn_version;
+ Elf32_Half vn_cnt;
+ Elf32_Word vn_file;
+ Elf32_Word vn_aux;
+ Elf32_Word vn_next;
+} Elf32_Verneed;
+
+typedef struct
+{
+ Elf32_Word vna_hash;
+ Elf32_Half vna_flags;
+ Elf32_Half vna_other;
+ Elf32_Word vna_name;
+ Elf32_Word vna_next;
+} Elf32_Vernaux;
+
+typedef Elf32_Half Elf32_Versym;
+
+typedef struct {
+ Elf32_Half si_boundto; /* direct bindings - symbol bound to */
+ Elf32_Half si_flags; /* per symbol flags */
+} Elf32_Syminfo;
+
+#endif /* !_SYS_ELF32_H_ */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf64.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf64.h
new file mode 100644
index 00000000..8dc10f6b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf64.h
@@ -0,0 +1,254 @@
+/** @file
+Ported ELF include files from FreeBSD
+
+Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+/*-
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.2 2007/12/03 21:30:36 marius Exp $
+ */
+
+#ifndef _SYS_ELF64_H_
+#define _SYS_ELF64_H_ 1
+
+
+/*
+ * ELF definitions common to all 64-bit architectures.
+ */
+
+typedef UINT64 Elf64_Addr;
+typedef UINT16 Elf64_Half;
+typedef UINT64 Elf64_Off;
+typedef INT32 Elf64_Sword;
+typedef INT64 Elf64_Sxword;
+typedef UINT32 Elf64_Word;
+typedef UINT64 Elf64_Lword;
+typedef UINT64 Elf64_Xword;
+
+/*
+ * Types of dynamic symbol hash table bucket and chain elements.
+ *
+ * This is inconsistent among 64 bit architectures, so a machine dependent
+ * typedef is required.
+ */
+
+typedef Elf64_Word Elf64_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf64_Xword Elf64_Size;
+typedef Elf64_Sxword Elf64_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf64_Half e_type; /* File type. */
+ Elf64_Half e_machine; /* Machine architecture. */
+ Elf64_Word e_version; /* ELF format version. */
+ Elf64_Addr e_entry; /* Entry point. */
+ Elf64_Off e_phoff; /* Program header file offset. */
+ Elf64_Off e_shoff; /* Section header file offset. */
+ Elf64_Word e_flags; /* Architecture-specific flags. */
+ Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf64_Half e_phentsize; /* Size of program header entry. */
+ Elf64_Half e_phnum; /* Number of program header entries. */
+ Elf64_Half e_shentsize; /* Size of section header entry. */
+ Elf64_Half e_shnum; /* Number of section header entries. */
+ Elf64_Half e_shstrndx; /* Section name strings section. */
+} Elf64_Ehdr;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf64_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf64_Word sh_type; /* Section type. */
+ Elf64_Xword sh_flags; /* Section flags. */
+ Elf64_Addr sh_addr; /* Address in memory image. */
+ Elf64_Off sh_offset; /* Offset in file. */
+ Elf64_Xword sh_size; /* Size in bytes. */
+ Elf64_Word sh_link; /* Index of a related section. */
+ Elf64_Word sh_info; /* Depends on section type. */
+ Elf64_Xword sh_addralign; /* Alignment in bytes. */
+ Elf64_Xword sh_entsize; /* Size of each entry in section. */
+} Elf64_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf64_Word p_type; /* Entry type. */
+ Elf64_Word p_flags; /* Access permission flags. */
+ Elf64_Off p_offset; /* File offset of contents. */
+ Elf64_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf64_Addr p_paddr; /* Physical address (not used). */
+ Elf64_Xword p_filesz; /* Size of contents in file. */
+ Elf64_Xword p_memsz; /* Size of contents in memory. */
+ Elf64_Xword p_align; /* Alignment in memory and file. */
+} Elf64_Phdr;
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf64_Sxword d_tag; /* Entry type. */
+ union {
+ Elf64_Xword d_val; /* Integer value. */
+ Elf64_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf64_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Xword r_info; /* Relocation type and symbol index. */
+} Elf64_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Xword r_info; /* Relocation type and symbol index. */
+ Elf64_Sxword r_addend; /* Addend. */
+} Elf64_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF64_R_SYM(info) ((info) >> 32)
+#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
+
+/* Macro for constructing r_info from field values. */
+#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
+
+#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
+#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
+#define ELF64_R_TYPE_INFO(data, type) \
+ (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
+
+/*
+ * Note entry header
+ */
+typedef Elf_Note Elf64_Nhdr;
+
+/*
+ * Move entry
+ */
+typedef struct {
+ Elf64_Lword m_value; /* symbol value */
+ Elf64_Xword m_info; /* size + index */
+ Elf64_Xword m_poffset; /* symbol offset */
+ Elf64_Half m_repeat; /* repeat count */
+ Elf64_Half m_stride; /* stride info */
+} Elf64_Move;
+
+#define ELF64_M_SYM(info) ((info)>>8)
+#define ELF64_M_SIZE(info) ((unsigned char)(info))
+#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ * Hardware/Software capabilities entry
+ */
+typedef struct {
+ Elf64_Xword c_tag; /* how to interpret value */
+ union {
+ Elf64_Xword c_val;
+ Elf64_Addr c_ptr;
+ } c_un;
+} Elf64_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf64_Word st_name; /* String table index of name. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf64_Half st_shndx; /* Section index of symbol. */
+ Elf64_Addr st_value; /* Symbol value. */
+ Elf64_Xword st_size; /* Size of associated object. */
+} Elf64_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF64_ST_BIND(info) ((info) >> 4)
+#define ELF64_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
+
+/* Structures used by Sun & GNU-style symbol versioning. */
+typedef struct {
+ Elf64_Half vd_version;
+ Elf64_Half vd_flags;
+ Elf64_Half vd_ndx;
+ Elf64_Half vd_cnt;
+ Elf64_Word vd_hash;
+ Elf64_Word vd_aux;
+ Elf64_Word vd_next;
+} Elf64_Verdef;
+
+typedef struct {
+ Elf64_Word vda_name;
+ Elf64_Word vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+ Elf64_Half vn_version;
+ Elf64_Half vn_cnt;
+ Elf64_Word vn_file;
+ Elf64_Word vn_aux;
+ Elf64_Word vn_next;
+} Elf64_Verneed;
+
+typedef struct {
+ Elf64_Word vna_hash;
+ Elf64_Half vna_flags;
+ Elf64_Half vna_other;
+ Elf64_Word vna_name;
+ Elf64_Word vna_next;
+} Elf64_Vernaux;
+
+typedef Elf64_Half Elf64_Versym;
+
+typedef struct {
+ Elf64_Half si_boundto; /* direct bindings - symbol bound to */
+ Elf64_Half si_flags; /* per symbol flags */
+} Elf64_Syminfo;
+
+#endif /* !_SYS_ELF64_H_ */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf_common.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf_common.h
new file mode 100644
index 00000000..8bbf7596
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenFw/elf_common.h
@@ -0,0 +1,1045 @@
+/** @file
+Ported ELF include files from FreeBSD
+
+Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+/*-
+ * Copyright (c) 1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.2 2007/12/03 21:30:36 marius Exp $
+ */
+
+#ifndef _SYS_ELF_COMMON_H_
+#define _SYS_ELF_COMMON_H_ 1
+
+/*
+ * ELF definitions that are independent of architecture or word size.
+ */
+
+/*
+ * Note header. The ".note" section contains an array of notes. Each
+ * begins with this header, aligned to a word boundary. Immediately
+ * following the note header is n_namesz bytes of name, padded to the
+ * next word boundary. Then comes n_descsz bytes of descriptor, again
+ * padded to a word boundary. The values of n_namesz and n_descsz do
+ * not include the padding.
+ */
+
+typedef struct {
+ UINT32 n_namesz; /* Length of name. */
+ UINT32 n_descsz; /* Length of descriptor. */
+ UINT32 n_type; /* Type of this note. */
+} Elf_Note;
+
+/* Indexes into the e_ident array. Keep synced with
+ http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EI_MAG0 0 /* Magic number, byte 0. */
+#define EI_MAG1 1 /* Magic number, byte 1. */
+#define EI_MAG2 2 /* Magic number, byte 2. */
+#define EI_MAG3 3 /* Magic number, byte 3. */
+#define EI_CLASS 4 /* Class of machine. */
+#define EI_DATA 5 /* Data format. */
+#define EI_VERSION 6 /* ELF format version. */
+#define EI_OSABI 7 /* Operating system / ABI identification */
+#define EI_ABIVERSION 8 /* ABI version */
+#define OLD_EI_BRAND 8 /* Start of architecture identification. */
+#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
+#define EI_NIDENT 16 /* Size of e_ident array. */
+
+/* Values for the magic number bytes. */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF" /* magic string */
+#define SELFMAG 4 /* magic string size */
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define EV_NONE 0
+#define EV_CURRENT 1
+
+/* Values for e_ident[EI_CLASS]. */
+#define ELFCLASSNONE 0 /* Unknown class. */
+#define ELFCLASS32 1 /* 32-bit architecture. */
+#define ELFCLASS64 2 /* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define ELFDATANONE 0 /* Unknown data format. */
+#define ELFDATA2LSB 1 /* 2's complement little-endian. */
+#define ELFDATA2MSB 2 /* 2's complement big-endian. */
+
+/* Values for e_ident[EI_OSABI]. */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX 1 /* HP-UX operating system */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* GNU/Linux */
+#define ELFOSABI_HURD 4 /* GNU/Hurd */
+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS 6 /* Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
+#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define ET_NONE 0 /* Unknown type. */
+#define ET_REL 1 /* Relocatable. */
+#define ET_EXEC 2 /* Executable. */
+#define ET_DYN 3 /* Shared object. */
+#define ET_CORE 4 /* Core file. */
+#define ET_LOOS 0xfe00 /* First operating system specific. */
+#define ET_HIOS 0xfeff /* Last operating system-specific. */
+#define ET_LOPROC 0xff00 /* First processor-specific. */
+#define ET_HIPROC 0xffff /* Last processor-specific. */
+
+/* Values for e_machine. */
+#define EM_NONE 0 /* Unknown machine. */
+#define EM_M32 1 /* AT&T WE32100. */
+#define EM_SPARC 2 /* Sun SPARC. */
+#define EM_386 3 /* Intel i386. */
+#define EM_68K 4 /* Motorola 68000. */
+#define EM_88K 5 /* Motorola 88000. */
+#define EM_860 7 /* Intel i860. */
+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
+#define EM_S370 9 /* IBM System/370. */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
+#define EM_PARISC 15 /* HP PA-RISC. */
+#define EM_VPP500 17 /* Fujitsu VPP500. */
+#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
+#define EM_960 19 /* Intel 80960. */
+#define EM_PPC 20 /* PowerPC 32-bit. */
+#define EM_PPC64 21 /* PowerPC 64-bit. */
+#define EM_S390 22 /* IBM System/390. */
+#define EM_V800 36 /* NEC V800. */
+#define EM_FR20 37 /* Fujitsu FR20. */
+#define EM_RH32 38 /* TRW RH-32. */
+#define EM_RCE 39 /* Motorola RCE. */
+#define EM_ARM 40 /* ARM. */
+#define EM_SH 42 /* Hitachi SH. */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
+#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
+#define EM_ARC 45 /* Argonaut RISC Core. */
+#define EM_H8_300 46 /* Hitachi H8/300. */
+#define EM_H8_300H 47 /* Hitachi H8/300H. */
+#define EM_H8S 48 /* Hitachi H8S. */
+#define EM_H8_500 49 /* Hitachi H8/500. */
+#define EM_MIPS_X 51 /* Stanford MIPS-X. */
+#define EM_COLDFIRE 52 /* Motorola ColdFire. */
+#define EM_68HC12 53 /* Motorola M68HC12. */
+#define EM_MMA 54 /* Fujitsu MMA. */
+#define EM_PCP 55 /* Siemens PCP. */
+#define EM_NCPU 56 /* Sony nCPU. */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
+#define EM_STARCORE 58 /* Motorola Star*Core processor. */
+#define EM_ME16 59 /* Toyota ME16 processor. */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
+#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
+#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
+#define EM_AARCH64 183 /* ARM 64bit Architecture */
+#define EM_RISCV64 243 /* 64bit RISC-V Architecture */
+#define EM_RISCV 244 /* 32bit RISC-V Architecture */
+
+/* Non-standard or deprecated. */
+#define EM_486 6 /* Intel i486. */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
+#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
+#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
+
+/* Special section indexes. */
+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE 0xff00 /* First of reserved range. */
+#define SHN_LOPROC 0xff00 /* First processor-specific. */
+#define SHN_HIPROC 0xff1f /* Last processor-specific. */
+#define SHN_LOOS 0xff20 /* First operating system-specific. */
+#define SHN_HIOS 0xff3f /* Last operating system-specific. */
+#define SHN_ABS 0xfff1 /* Absolute values. */
+#define SHN_COMMON 0xfff2 /* Common data. */
+#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
+
+/* sh_type */
+#define SHT_NULL 0 /* inactive */
+#define SHT_PROGBITS 1 /* program defined information */
+#define SHT_SYMTAB 2 /* symbol table section */
+#define SHT_STRTAB 3 /* string table section */
+#define SHT_RELA 4 /* relocation section with addends */
+#define SHT_HASH 5 /* symbol hash table section */
+#define SHT_DYNAMIC 6 /* dynamic section */
+#define SHT_NOTE 7 /* note section */
+#define SHT_NOBITS 8 /* no space section */
+#define SHT_REL 9 /* relocation section - no addends */
+#define SHT_SHLIB 10 /* reserved - purpose unknown */
+#define SHT_DYNSYM 11 /* dynamic symbol table section */
+#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
+#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
+#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
+#define SHT_GROUP 17 /* Section group. */
+#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
+#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
+#define SHT_LOSUNW 0x6ffffff4
+#define SHT_SUNW_dof 0x6ffffff4
+#define SHT_SUNW_cap 0x6ffffff5
+#define SHT_SUNW_SIGNATURE 0x6ffffff6
+#define SHT_SUNW_ANNOTATE 0x6ffffff7
+#define SHT_SUNW_DEBUGSTR 0x6ffffff8
+#define SHT_SUNW_DEBUG 0x6ffffff9
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef 0x6ffffffd
+#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
+#define SHT_SUNW_verneed 0x6ffffffe
+#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
+#define SHT_SUNW_versym 0x6fffffff
+#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
+#define SHT_LOPROC 0x70000000 /* reserved range for processor */
+#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
+#define SHT_HIPROC 0x7fffffff /* specific section header types */
+#define SHT_LOUSER 0x80000000 /* reserved range for application */
+#define SHT_HIUSER 0xffffffff /* specific indexes */
+
+/* Flags for sh_flags. */
+#define SHF_WRITE 0x1 /* Section contains writable data. */
+#define SHF_ALLOC 0x2 /* Section occupies memory. */
+#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
+#define SHF_MERGE 0x10 /* Section may be merged. */
+#define SHF_STRINGS 0x20 /* Section contains strings. */
+#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
+#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
+#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
+#define SHF_GROUP 0x200 /* Member of section group. */
+#define SHF_TLS 0x400 /* Section contains TLS data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
+
+/* Values for p_type. */
+#define PT_NULL 0 /* Unused entry. */
+#define PT_LOAD 1 /* Loadable segment. */
+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
+#define PT_INTERP 3 /* Pathname of interpreter. */
+#define PT_NOTE 4 /* Auxiliary information. */
+#define PT_SHLIB 5 /* Reserved (not used). */
+#define PT_PHDR 6 /* Location of program header itself. */
+#define PT_TLS 7 /* Thread local storage segment */
+#define PT_LOOS 0x60000000 /* First OS-specific. */
+#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
+#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
+#define PT_SUNWDTRACE 0x6ffffffc /* private */
+#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* Last OS-specific. */
+#define PT_LOPROC 0x70000000 /* First processor-specific type. */
+#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+/* Values for p_flags. */
+#define PF_X 0x1 /* Executable. */
+#define PF_W 0x2 /* Writable. */
+#define PF_R 0x4 /* Readable. */
+#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
+
+/* Extended program header index. */
+#define PN_XNUM 0xffff
+
+/* Values for d_tag. */
+#define DT_NULL 0 /* Terminating entry. */
+#define DT_NEEDED 1 /* String table offset of a needed shared
+ library. */
+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT 3 /* Processor-dependent address. */
+#define DT_HASH 4 /* Address of symbol hash table. */
+#define DT_STRTAB 5 /* Address of string table. */
+#define DT_SYMTAB 6 /* Address of symbol table. */
+#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
+#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
+#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
+#define DT_STRSZ 10 /* Size of string table. */
+#define DT_SYMENT 11 /* Size of each symbol table entry. */
+#define DT_INIT 12 /* Address of initialization function. */
+#define DT_FINI 13 /* Address of finalization function. */
+#define DT_SONAME 14 /* String table offset of shared object
+ name. */
+#define DT_RPATH 15 /* String table offset of library path. [sup] */
+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
+#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
+#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
+#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
+#define DT_PLTREL 20 /* Type of relocation used for PLT. */
+#define DT_DEBUG 21 /* Reserved (not used). */
+#define DT_TEXTREL 22 /* Indicates there may be relocations in
+ non-writable segments. [sup] */
+#define DT_JMPREL 23 /* Address of PLT relocations. */
+#define DT_BIND_NOW 24 /* [sup] */
+#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
+ initialization functions */
+#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
+ termination functions */
+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
+ initialization functions. */
+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
+ terminationfunctions. */
+#define DT_RUNPATH 29 /* String table offset of a null-terminated
+ library search path string. */
+#define DT_FLAGS 30 /* Object specific flag values. */
+#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
+ and less than DT_LOOS follow the rules for
+ the interpretation of the d_un union
+ as follows: even == 'd_ptr', even == 'd_val'
+ or none */
+#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
+ pre-initialization functions. */
+#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
+ pre-initialization functions. */
+#define DT_MAXPOSTAGS 34 /* number of positive tags */
+#define DT_LOOS 0x6000000d /* First OS-specific */
+#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */
+#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */
+#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */
+#define DT_SUNW_CAP 0x60000010 /* hardware/software */
+#define DT_HIOS 0x6ffff000 /* Last OS-specific */
+
+/*
+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ * Dyn.d_un.d_val field of the Elf*_Dyn structure.
+ */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */
+#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */
+#define DT_MOVEENT 0x6ffffdfa /* move table entry size */
+#define DT_MOVESZ 0x6ffffdfb /* move table size */
+#define DT_FEATURE_1 0x6ffffdfc /* feature holder */
+#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */
+ /* the following DT_* entry. */
+ /* See DF_P1_* definitions */
+#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */
+#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */
+#define DT_VALRNGHI 0x6ffffdff
+
+/*
+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+ *
+ * If any adjustment is made to the ELF object after it has been
+ * built, these entries will need to be adjusted.
+ */
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_CONFIG 0x6ffffefa /* configuration information */
+#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */
+#define DT_AUDIT 0x6ffffefc /* object auditing */
+#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */
+#define DT_MOVETAB 0x6ffffefe /* move table */
+#define DT_SYMINFO 0x6ffffeff /* syminfo table */
+#define DT_ADDRRNGHI 0x6ffffeff
+
+#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */
+#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */
+#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */
+#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */
+#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */
+#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */
+#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */
+#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */
+
+#define DT_LOPROC 0x70000000 /* First processor-specific type. */
+#define DT_DEPRECATED_SPARC_REGISTER 0x7000001
+#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
+#define DT_USED 0x7ffffffe /* ignored - same as needed */
+#define DT_FILTER 0x7fffffff /* shared library filter name */
+#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+/* Values for DT_FLAGS */
+#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
+ make reference to the $ORIGIN substitution
+ string */
+#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
+#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
+ non-writable segments. */
+#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
+ process all relocations for the object
+ containing this entry before transferring
+ control to the program. */
+#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
+ executable contains code using a static
+ thread-local storage scheme. */
+
+/* Values for n_type. Used in core files. */
+#define NT_PRSTATUS 1 /* Process status. */
+#define NT_FPREGSET 2 /* Floating point registers. */
+#define NT_PRPSINFO 3 /* Process state info. */
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* like global - lower precedence */
+#define STB_LOOS 10 /* Reserved range for operating system */
+#define STB_HIOS 12 /* specific semantics. */
+#define STB_LOPROC 13 /* reserved range for processor */
+#define STB_HIPROC 15 /* specific semantics. */
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+#define STT_NOTYPE 0 /* Unspecified type. */
+#define STT_OBJECT 1 /* Data object. */
+#define STT_FUNC 2 /* Function. */
+#define STT_SECTION 3 /* Section. */
+#define STT_FILE 4 /* Source file. */
+#define STT_COMMON 5 /* Uninitialized common block. */
+#define STT_TLS 6 /* TLS object. */
+#define STT_NUM 7
+#define STT_LOOS 10 /* Reserved range for operating system */
+#define STT_HIOS 12 /* specific semantics. */
+#define STT_LOPROC 13 /* reserved range for processor */
+#define STT_HIPROC 15 /* specific semantics. */
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
+#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
+#define STV_HIDDEN 0x2 /* Not visible. */
+#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
+
+/* Special symbol table indexes. */
+#define STN_UNDEF 0 /* Undefined symbol index. */
+
+/* Symbol versioning flags. */
+#define VER_DEF_CURRENT 1
+#define VER_DEF_IDX(x) VER_NDX(x)
+
+#define VER_FLG_BASE 0x01
+#define VER_FLG_WEAK 0x02
+
+#define VER_NEED_CURRENT 1
+#define VER_NEED_WEAK (1u << 15)
+#define VER_NEED_HIDDEN VER_NDX_HIDDEN
+#define VER_NEED_IDX(x) VER_NDX(x)
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+#define VER_NDX_GIVEN 2
+
+#define VER_NDX_HIDDEN (1u << 15)
+#define VER_NDX(x) ((x) & ~(1u << 15))
+
+#define CA_SUNW_NULL 0
+#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
+#define CA_SUNW_SF_1 2 /* first software capabilities entry */
+
+/*
+ * Syminfo flag values
+ */
+#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */
+ /* to object containing defn. */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */
+#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */
+ /* lazily-loaded */
+#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */
+ /* object containing defn. */
+#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */
+ /* directly bind to this symbol */
+#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */
+#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */
+
+/*
+ * Syminfo.si_boundto values.
+ */
+#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
+#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */
+#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */
+
+/*
+ * Syminfo version values.
+ */
+#define SYMINFO_NONE 0 /* Syminfo version */
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+/*
+ * Relocation types.
+ *
+ * All machine architectures are defined here to allow tools on one to
+ * handle others.
+ */
+
+#define R_386_NONE 0 /* No relocation. */
+#define R_386_32 1 /* Add symbol value. */
+#define R_386_PC32 2 /* Add PC-relative symbol value. */
+#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
+#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
+#define R_386_COPY 5 /* Copy data from shared object. */
+#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_386_RELATIVE 8 /* Add load address of shared object. */
+#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
+#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
+#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */
+#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */
+#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */
+#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */
+#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */
+#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */
+#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */
+#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */
+#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */
+#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */
+#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
+
+/* Null relocation */
+#define R_AARCH64_NONE 256 /* No relocation */
+/* Static AArch64 relocations */
+ /* Static data relocations */
+#define R_AARCH64_ABS64 257 /* S + A */
+#define R_AARCH64_ABS32 258 /* S + A */
+#define R_AARCH64_ABS16 259 /* S + A */
+#define R_AARCH64_PREL64 260 /* S + A - P */
+#define R_AARCH64_PREL32 261 /* S + A - P */
+#define R_AARCH64_PREL16 262 /* S + A - P */
+ /* Group relocations to create a 16, 32, 48, or 64 bit unsigned data value or address inline */
+#define R_AARCH64_MOVW_UABS_G0 263 /* S + A */
+#define R_AARCH64_MOVW_UABS_G0_NC 264 /* S + A */
+#define R_AARCH64_MOVW_UABS_G1 265 /* S + A */
+#define R_AARCH64_MOVW_UABS_G1_NC 266 /* S + A */
+#define R_AARCH64_MOVW_UABS_G2 267 /* S + A */
+#define R_AARCH64_MOVW_UABS_G2_NC 268 /* S + A */
+#define R_AARCH64_MOVW_UABS_G3 269 /* S + A */
+ /* Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */
+#define R_AARCH64_MOVW_SABS_G0 270 /* S + A */
+#define R_AARCH64_MOVW_SABS_G1 271 /* S + A */
+#define R_AARCH64_MOVW_SABS_G2 272 /* S + A */
+ /* Relocations to generate 19, 21 and 33 bit PC-relative addresses */
+#define R_AARCH64_LD_PREL_LO19 273 /* S + A - P */
+#define R_AARCH64_ADR_PREL_LO21 274 /* S + A - P */
+#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page(S+A) - Page(P) */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Page(S+A) - Page(P) */
+#define R_AARCH64_ADD_ABS_LO12_NC 277 /* S + A */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* S + A */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* S + A */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* S + A */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* S + A */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* S + A */
+ /* Relocations for control-flow instructions - all offsets are a multiple of 4 */
+#define R_AARCH64_TSTBR14 279 /* S+A-P */
+#define R_AARCH64_CONDBR19 280 /* S+A-P */
+#define R_AARCH64_JUMP26 282 /* S+A-P */
+#define R_AARCH64_CALL26 283 /* S+A-P */
+ /* Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */
+#define R_AARCH64_MOVW_PREL_G0 287 /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G0_NC 288 /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G1 289 /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G1_NC 290 /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G2 291 /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G2_NC 292 /* S+A-P */
+#define R_AARCH64_MOVW_PREL_G3 293 /* S+A-P */
+ /* Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */
+#define R_AARCH64_MOVW_GOTOFF_G0 300 /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G1 302 /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G2 304 /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* G(S)-GOT */
+#define R_AARCH64_MOVW_GOTOFF_G3 306 /* G(S)-GOT */
+ /* GOT-relative data relocations */
+#define R_AARCH64_GOTREL64 307 /* S+A-GOT */
+#define R_AARCH64_GOTREL32 308 /* S+A-GOT */
+ /* GOT-relative instruction relocations */
+#define R_AARCH64_GOT_LD_PREL19 309 /* G(S)-P */
+#define R_AARCH64_LD64_GOTOFF_LO15 310 /* G(S)-GOT */
+#define R_AARCH64_ADR_GOT_PAGE 311 /* Page(G(S))-Page(P) */
+#define R_AARCH64_LD64_GOT_LO12_NC 312 /* G(S) */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* G(S)-Page(GOT) */
+/* Relocations for thread-local storage */
+ /* General Dynamic TLS relocations */
+#define R_AARCH64_TLSGD_ADR_PREL21 512 /* G(TLSIDX(S+A)) - P */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* Page(G(TLSIDX(S+A))) - Page(P) */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* G(TLSIDX(S+A)) */
+#define R_AARCH64_TLSGD_MOVW_G1 515 /* G(TLSIDX(S+A)) - GOT */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* G(TLSIDX(S+A)) - GOT */
+ /* Local Dynamic TLS relocations */
+#define R_AARCH64_TLSLD_ADR_PREL21 517 /* G(LDM(S))) - P */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Page(G(LDM(S)))-Page(P) */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* G(LDM(S)) */
+#define R_AARCH64_TLSLD_MOVW_G1 520 /* G(LDM(S)) - GOT */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* G(LDM(S)) - GOT */
+#define R_AARCH64_TLSLD_LD_PREL19 522 /* G(LDM(S)) - P */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTPREL(S+A) */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* DTPREL(S+A) */
+ /* Initial Exec TLS relocations */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* G(TPREL(S+A)) - GOT */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* G(TPREL(S+A)) - GOT */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page(G(TPREL(S+A))) - Page(P) */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* G(TPREL(S+A)) */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* G(TPREL(S+A)) - P */
+ /* Local Exec TLS relocations */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TPREL(S+A) */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* TPREL(S+A) */
+/* Dynamic relocations */
+ /* Dynamic relocations */
+#define R_AARCH64_COPY 1024
+#define R_AARCH64_GLOB_DAT 1025 /* S + A */
+#define R_AARCH64_JUMP_SLOT 1026 /* S + A */
+#define R_AARCH64_RELATIVE 1027 /* Delta(S) + A , Delta(P) + A */
+#define R_AARCH64_TLS_DTPREL64 1028 /* DTPREL(S+A) */
+#define R_AARCH64_TLS_DTPMOD64 1029 /* LDM(S) */
+#define R_AARCH64_TLS_TPREL64 1030 /* TPREL(S+A) */
+#define R_AARCH64_TLS_DTPREL32 1031 /* DTPREL(S+A) */
+#define R_AARCH64_TLS_DTPMOD32 1032 /* LDM(S) */
+#define R_AARCH64_TLS_TPREL32 1033 /* DTPREL(S+A) */
+
+#define R_ALPHA_NONE 0 /* No reloc */
+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH 12 /* OP stack push */
+#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */
+#define R_ALPHA_GPVALUE 16
+#define R_ALPHA_GPRELHIGH 17
+#define R_ALPHA_GPRELLOW 18
+#define R_ALPHA_IMMED_GP_16 19
+#define R_ALPHA_IMMED_GP_HI32 20
+#define R_ALPHA_IMMED_SCN_HI32 21
+#define R_ALPHA_IMMED_BR_HI32 22
+#define R_ALPHA_IMMED_LO32 23
+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
+
+#define R_ARM_NONE 0 /* No relocation. */
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_REL32 3
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5
+#define R_ARM_ABS12 6
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_SWI24 13
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+#define R_ARM_COPY 20 /* Copy data from shared object. */
+#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */
+#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */
+#define R_ARM_RELATIVE 23 /* Add load address of shared object. */
+#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */
+#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */
+#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */
+#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */
+#define R_ARM_CALL 28
+#define R_ARM_JMP24 29
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS 48
+
+// Block of PC-relative relocations added to work around gcc putting
+// object relocations in static executables.
+#define R_ARM_THM_JUMP24 30
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_PREL_NC 45
+#define R_ARM_MOVT_PREL 46
+#define R_ARM_THM_MOVW_PREL_NC 49
+#define R_ARM_THM_MOVT_PREL 50
+#define R_ARM_THM_JMP6 52
+#define R_ARM_THM_ALU_PREL_11_0 53
+#define R_ARM_THM_PC12 54
+#define R_ARM_REL32_NOI 56
+#define R_ARM_ALU_PC_G0_NC 57
+#define R_ARM_ALU_PC_G0 58
+#define R_ARM_ALU_PC_G1_NC 59
+#define R_ARM_ALU_PC_G1 60
+#define R_ARM_ALU_PC_G2 61
+#define R_ARM_LDR_PC_G1 62
+#define R_ARM_LDR_PC_G2 63
+#define R_ARM_LDRS_PC_G0 64
+#define R_ARM_LDRS_PC_G1 65
+#define R_ARM_LDRS_PC_G2 66
+#define R_ARM_LDC_PC_G0 67
+#define R_ARM_LDC_PC_G1 68
+#define R_ARM_LDC_PC_G2 69
+#define R_ARM_GOT_PREL 96
+#define R_ARM_THM_JUMP11 102
+#define R_ARM_THM_JUMP8 103
+#define R_ARM_TLS_GD32 104
+#define R_ARM_TLS_LDM32 105
+#define R_ARM_TLS_IE32 107
+
+#define R_ARM_THM_JUMP19 51
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS32 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+
+#define R_PPC_NONE 0 /* No relocation. */
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+/*
+ * TLS relocations
+ */
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+
+/*
+ * The remaining relocs are from the Embedded ELF ABI, and are not in the
+ * SVR4 ELF ABI.
+ */
+
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+
+#define R_X86_64_NONE 0 /* No relocation. */
+#define R_X86_64_64 1 /* Add 64 bit symbol value. */
+#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */
+#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */
+#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */
+#define R_X86_64_COPY 5 /* Copy data from shared object. */
+#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */
+#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */
+#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */
+#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */
+#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */
+#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */
+#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */
+#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */
+#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */
+#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */
+#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */
+#define R_X86_64_PC64 24 /* PC relative 64 bit */
+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
+#define R_X86_64_GOTPC3 26 /* 32 bit signed pc relative offset to GOT */
+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset to GOT entry */
+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset to PLT entry */
+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS descriptor. */
+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
+#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. */
+#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. */
+
+/*
+ * RISC-V relocation types
+ */
+
+/* Relocation types used by the dynamic linker */
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11
+
+/* Relocation types not used by the dynamic linker */
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+#define R_RISCV_RVC_LUI 46
+#define R_RISCV_GPREL_I 47
+#define R_RISCV_GPREL_S 48
+#define R_RISCV_TPREL_I 49
+#define R_RISCV_TPREL_S 50
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6 52
+#define R_RISCV_SET6 53
+#define R_RISCV_SET8 54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
+#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GNUmakefile
new file mode 100644
index 00000000..869dabb1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GNUmakefile
@@ -0,0 +1,23 @@
+## @file
+# GNU/Linux makefile for 'GenSec' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = GenSec
+
+OBJECTS = GenSec.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+ifeq ($(CYGWIN), CYGWIN)
+ LIBS += -L/lib/e2fsprogs -luuid
+endif
+
+ifeq ($(LINUX), Linux)
+ LIBS += -luuid
+endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GenSec.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GenSec.c
new file mode 100644
index 00000000..01719a7c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/GenSec.c
@@ -0,0 +1,1818 @@
+/** @file
+Creates output file that is a properly formed section per the PI spec.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef __GNUC__
+# ifdef VBOX
+# include <iprt/win/windows.h>
+# else
+#include <windows.h>
+# endif
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <Common/UefiBaseTypes.h>
+#include <Common/PiFirmwareFile.h>
+#include <Protocol/GuidedSectionExtraction.h>
+#if defined(VBOX) && defined(RT_OS_WINDOWS)
+# define _SKIP_DEFINE_RUNTIME_FUNCTION 1
+#endif
+#include <IndustryStandard/PeImage.h>
+
+#include "CommonLib.h"
+#include "Compress.h"
+#include "Crc32.h"
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include "FvLib.h"
+#include "PeCoffLib.h"
+
+//
+// GenSec Tool Information
+//
+#define UTILITY_NAME "GenSec"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+STATIC CHAR8 *mSectionTypeName[] = {
+ NULL, // 0x00 - reserved
+ "EFI_SECTION_COMPRESSION", // 0x01
+ "EFI_SECTION_GUID_DEFINED", // 0x02
+ NULL, // 0x03 - reserved
+ NULL, // 0x04 - reserved
+ NULL, // 0x05 - reserved
+ NULL, // 0x06 - reserved
+ NULL, // 0x07 - reserved
+ NULL, // 0x08 - reserved
+ NULL, // 0x09 - reserved
+ NULL, // 0x0A - reserved
+ NULL, // 0x0B - reserved
+ NULL, // 0x0C - reserved
+ NULL, // 0x0D - reserved
+ NULL, // 0x0E - reserved
+ NULL, // 0x0F - reserved
+ "EFI_SECTION_PE32", // 0x10
+ "EFI_SECTION_PIC", // 0x11
+ "EFI_SECTION_TE", // 0x12
+ "EFI_SECTION_DXE_DEPEX", // 0x13
+ "EFI_SECTION_VERSION", // 0x14
+ "EFI_SECTION_USER_INTERFACE", // 0x15
+ "EFI_SECTION_COMPATIBILITY16", // 0x16
+ "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17
+ "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18
+ "EFI_SECTION_RAW", // 0x19
+ NULL, // 0x1A
+ "EFI_SECTION_PEI_DEPEX", // 0x1B
+ "EFI_SECTION_SMM_DEPEX" // 0x1C
+};
+
+STATIC CHAR8 *mCompressionTypeName[] = { "PI_NONE", "PI_STD" };
+
+#define EFI_GUIDED_SECTION_NONE 0x80
+STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};
+
+STATIC CHAR8 *mAlignName[] = {
+ "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
+ "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",
+ "512K", "1M", "2M", "4M", "8M", "16M"
+};
+
+//
+// Crc32 GUID section related definitions.
+//
+typedef struct {
+ EFI_GUID_DEFINED_SECTION GuidSectionHeader;
+ UINT32 CRC32Checksum;
+} CRC32_SECTION_HEADER;
+
+typedef struct {
+ EFI_GUID_DEFINED_SECTION2 GuidSectionHeader;
+ UINT32 CRC32Checksum;
+} CRC32_SECTION_HEADER2;
+
+STATIC EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+STATIC EFI_GUID mEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
+
+STATIC
+VOID
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print out version information for this utility.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Print Help message.
+
+Arguments:
+
+ VOID
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " -o FileName, --outputfile FileName\n\
+ File is the SectionFile to be created.\n");
+ fprintf (stdout, " -s [SectionType], --sectiontype [SectionType]\n\
+ SectionType defined in PI spec is one type of\n\
+ EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\
+ EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\
+ EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\
+ EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,\n\
+ EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\
+ if -s option is not given, \n\
+ EFI_SECTION_ALL is default section type.\n");
+ fprintf (stdout, " -c [Type], --compress [Type]\n\
+ Compress method type can be PI_NONE or PI_STD.\n\
+ if -c option is not given, PI_STD is default type.\n");
+ fprintf (stdout, " -g GuidValue, --vendor GuidValue\n\
+ GuidValue is one specific vendor guid value.\n\
+ Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
+ fprintf (stdout, " -l GuidHeaderLength, --HeaderLength GuidHeaderLength\n\
+ GuidHeaderLength is the size of header of guided data\n");
+ fprintf (stdout, " -r GuidAttr, --attributes GuidAttr\n\
+ GuidAttr is guid section attributes, which may be\n\
+ PROCESSING_REQUIRED, AUTH_STATUS_VALID and NONE. \n\
+ if -r option is not given, default PROCESSING_REQUIRED\n");
+ fprintf (stdout, " -n String, --name String\n\
+ String is a NULL terminated string used in Ui section.\n");
+ fprintf (stdout, " -j Number, --buildnumber Number\n\
+ Number is an integer value between 0 and 65535\n\
+ used in Ver section.\n");
+ fprintf (stdout, " --sectionalign SectionAlign\n\
+ SectionAlign points to section alignment, which support\n\
+ the alignment scope 0~16M. If SectionAlign is specified\n\
+ as 0, tool get alignment value from SectionFile. It is\n\
+ specified in same order that the section file is input.\n");
+ fprintf (stdout, " --dummy dummyfile\n\
+ compare dummpyfile with input_file to decide whether\n\
+ need to set PROCESSING_REQUIRED attribute.\n");
+ fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
+ fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
+ fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
+ fprintf (stdout, " --version Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help Show this help message and exit.\n");
+}
+
+VOID
+Ascii2UnicodeString (
+ CHAR8 *String,
+ CHAR16 *UniString
+ )
+/*++
+
+Routine Description:
+
+ Write ascii string as unicode string format to FILE
+
+Arguments:
+
+ String - Pointer to string that is written to FILE.
+ UniString - Pointer to unicode string
+
+Returns:
+
+ NULL
+
+--*/
+{
+ while (*String != '\0') {
+ *(UniString++) = (CHAR16) *(String++);
+ }
+ //
+ // End the UniString with a NULL.
+ //
+ *UniString = '\0';
+}
+
+STATUS
+GenSectionCommonLeafSection (
+ CHAR8 **InputFileName,
+ UINT32 InputFileNum,
+ UINT8 SectionType,
+ UINT8 **OutFileBuffer
+ )
+/*++
+
+Routine Description:
+
+ Generate a leaf section of type other than EFI_SECTION_VERSION
+ and EFI_SECTION_USER_INTERFACE. Input file must be well formed.
+ The function won't validate the input file's contents. For
+ common leaf sections, the input file may be a binary file.
+ The utility will add section header to the file.
+
+Arguments:
+
+ InputFileName - Name of the input file.
+
+ InputFileNum - Number of input files. Should be 1 for leaf section.
+
+ SectionType - A valid section type string
+
+ OutFileBuffer - Buffer pointer to Output file contents
+
+Returns:
+
+ STATUS_ERROR - can't continue
+ STATUS_SUCCESS - successful return
+
+--*/
+{
+ UINT32 InputFileLength;
+ FILE *InFile;
+ UINT8 *Buffer;
+ UINT32 TotalLength;
+ UINT32 HeaderLength;
+ EFI_COMMON_SECTION_HEADER *CommonSect;
+ STATUS Status;
+
+ if (InputFileNum > 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "more than one input file specified");
+ return STATUS_ERROR;
+ } else if (InputFileNum < 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "no input file specified");
+ return STATUS_ERROR;
+ }
+ //
+ // Open the input file
+ //
+ InFile = fopen (LongFilePath (InputFileName[0]), "rb");
+ if (InFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);
+ return STATUS_ERROR;
+ }
+
+ Status = STATUS_ERROR;
+ Buffer = NULL;
+ //
+ // Seek to the end of the input file so we can determine its size
+ //
+ fseek (InFile, 0, SEEK_END);
+ InputFileLength = ftell (InFile);
+ fseek (InFile, 0, SEEK_SET);
+ DebugMsg (NULL, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName[0], (unsigned) InputFileLength);
+ TotalLength = sizeof (EFI_COMMON_SECTION_HEADER) + InputFileLength;
+ //
+ // Size must fit in 3 bytes
+ //
+ //if (TotalLength >= MAX_SECTION_SIZE) {
+ // Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);
+ // goto Done;
+ //}
+ HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER);
+ if (TotalLength >= MAX_SECTION_SIZE) {
+ TotalLength = sizeof (EFI_COMMON_SECTION_HEADER2) + InputFileLength;
+ HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER2);
+ }
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);
+ //
+ // Fill in the fields in the local section header structure
+ //
+ Buffer = (UINT8 *) malloc ((size_t) TotalLength);
+ if (Buffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Done;
+ }
+ CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;
+ CommonSect->Type = SectionType;
+ if (TotalLength < MAX_SECTION_SIZE) {
+ CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);
+ CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ } else {
+ memset(CommonSect->Size, 0xff, sizeof(UINT8) * 3);
+ ((EFI_COMMON_SECTION_HEADER2 *)CommonSect)->ExtendedSize = TotalLength;
+ }
+
+ //
+ // read data from the input file.
+ //
+ if (InputFileLength != 0) {
+ if (fread (Buffer + HeaderLength, (size_t) InputFileLength, 1, InFile) != 1) {
+ Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);
+ goto Done;
+ }
+ }
+
+ //
+ // Set OutFileBuffer
+ //
+ *OutFileBuffer = Buffer;
+ Status = STATUS_SUCCESS;
+
+Done:
+ fclose (InFile);
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+StringtoAlignment (
+ IN CHAR8 *AlignBuffer,
+ OUT UINT32 *AlignNumber
+ )
+/*++
+
+Routine Description:
+
+ Converts Align String to align value (1~16M).
+
+Arguments:
+
+ AlignBuffer - Pointer to Align string.
+ AlignNumber - Pointer to Align value.
+
+Returns:
+
+ EFI_SUCCESS Successfully convert align string to align value.
+ EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.
+
+--*/
+{
+ UINT32 Index = 0;
+ //
+ // Check AlignBuffer
+ //
+ if (AlignBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {
+ if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {
+ *AlignNumber = 1 << Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+GetSectionContents (
+ CHAR8 **InputFileName,
+ UINT32 *InputFileAlign,
+ UINT32 InputFileNum,
+ UINT8 *FileBuffer,
+ UINT32 *BufferLength
+ )
+/*++
+
+Routine Description:
+
+ Get the contents of all section files specified in InputFileName
+ into FileBuffer.
+
+Arguments:
+
+ InputFileName - Name of the input file.
+
+ InputFileAlign - Alignment required by the input file data.
+
+ InputFileNum - Number of input files. Should be at least 1.
+
+ FileBuffer - Output buffer to contain data
+
+ BufferLength - On input, this is size of the FileBuffer.
+ On output, this is the actual length of the data.
+
+Returns:
+
+ EFI_SUCCESS on successful return
+ EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
+ EFI_ABORTED if unable to open input file.
+ EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
+--*/
+{
+ UINT32 Size;
+ UINT32 Offset;
+ UINT32 FileSize;
+ UINT32 Index;
+ FILE *InFile;
+ EFI_COMMON_SECTION_HEADER *SectHeader;
+ EFI_COMMON_SECTION_HEADER2 TempSectHeader;
+ EFI_TE_IMAGE_HEADER TeHeader;
+ UINT32 TeOffset;
+ EFI_GUID_DEFINED_SECTION GuidSectHeader;
+ EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
+ UINT32 HeaderSize;
+
+ if (InputFileNum < 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "must specify at least one input file");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferLength == NULL) {
+ Error (NULL, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Size = 0;
+ Offset = 0;
+ TeOffset = 0;
+ //
+ // Go through our array of file names and copy their contents
+ // to the output buffer.
+ //
+ for (Index = 0; Index < InputFileNum; Index++) {
+ //
+ // make sure section ends on a DWORD boundary
+ //
+ while ((Size & 0x03) != 0) {
+ if (FileBuffer != NULL && Size < *BufferLength) {
+ FileBuffer[Size] = 0;
+ }
+ Size++;
+ }
+
+ //
+ // Open file and read contents
+ //
+ InFile = fopen (LongFilePath (InputFileName[Index]), "rb");
+ if (InFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);
+ return EFI_ABORTED;
+ }
+
+ fseek (InFile, 0, SEEK_END);
+ FileSize = ftell (InFile);
+ fseek (InFile, 0, SEEK_SET);
+ DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize);
+ //
+ // Adjust section buffer when section alignment is required.
+ //
+ if (InputFileAlign != NULL) {
+ //
+ // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
+ //
+ TeOffset = 0;
+ //
+ // The section might be EFI_COMMON_SECTION_HEADER2
+ // But only Type needs to be checked
+ //
+ if (FileSize >= MAX_SECTION_SIZE) {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+ fread (&TempSectHeader, 1, HeaderSize, InFile);
+ if (TempSectHeader.Type == EFI_SECTION_TE) {
+ fread (&TeHeader, 1, sizeof (TeHeader), InFile);
+ if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);
+ }
+ } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {
+ fseek (InFile, 0, SEEK_SET);
+ if (FileSize >= MAX_SECTION_SIZE) {
+ fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);
+ if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader2.DataOffset;
+ }
+ } else {
+ fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
+ if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader.DataOffset;
+ }
+ }
+ }
+
+ fseek (InFile, 0, SEEK_SET);
+
+ //
+ // Revert TeOffset to the converse value relative to Alignment
+ // This is to assure the original PeImage Header at Alignment.
+ //
+ if (TeOffset != 0) {
+ TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);
+ TeOffset = TeOffset % InputFileAlign [Index];
+ }
+
+ //
+ // make sure section data meet its alignment requirement by adding one raw pad section.
+ //
+ if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {
+ Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);
+ Offset = Offset - Size - HeaderSize - TeOffset;
+
+ if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {
+ //
+ // The maximal alignment is 64K, the raw section size must be less than 0xffffff
+ //
+ memset (FileBuffer + Size, 0, Offset);
+ SectHeader = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);
+ SectHeader->Type = EFI_SECTION_RAW;
+ SectHeader->Size[0] = (UINT8) (Offset & 0xff);
+ SectHeader->Size[1] = (UINT8) ((Offset & 0xff00) >> 8);
+ SectHeader->Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);
+ }
+ DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset);
+
+ Size = Size + Offset;
+ }
+ }
+
+ //
+ // Now read the contents of the file into the buffer
+ // Buffer must be enough to contain the file content.
+ //
+ if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {
+ if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {
+ Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);
+ fclose (InFile);
+ return EFI_ABORTED;
+ }
+ }
+
+ fclose (InFile);
+ Size += FileSize;
+ }
+
+ //
+ // Set the real required buffer size.
+ //
+ if (Size > *BufferLength) {
+ *BufferLength = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ *BufferLength = Size;
+ return EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+GenSectionCompressionSection (
+ CHAR8 **InputFileName,
+ UINT32 *InputFileAlign,
+ UINT32 InputFileNum,
+ UINT8 SectCompSubType,
+ UINT8 **OutFileBuffer
+ )
+/*++
+
+Routine Description:
+
+ Generate an encapsulating section of type EFI_SECTION_COMPRESSION
+ Input file must be already sectioned. The function won't validate
+ the input files' contents. Caller should hand in files already
+ with section header.
+
+Arguments:
+
+ InputFileName - Name of the input file.
+
+ InputFileAlign - Alignment required by the input file data.
+
+ InputFileNum - Number of input files. Should be at least 1.
+
+ SectCompSubType - Specify the compression algorithm requested.
+
+ OutFileBuffer - Buffer pointer to Output file contents
+
+Returns:
+
+ EFI_SUCCESS on successful return
+ EFI_INVALID_PARAMETER if InputFileNum is less than 1
+ EFI_ABORTED if unable to open input file.
+ EFI_OUT_OF_RESOURCES No resource to complete the operation.
+--*/
+{
+ UINT32 TotalLength;
+ UINT32 InputLength;
+ UINT32 CompressedLength;
+ UINT32 HeaderLength;
+ UINT8 *FileBuffer;
+ UINT8 *OutputBuffer;
+ EFI_STATUS Status;
+ EFI_COMPRESSION_SECTION *CompressionSect;
+ EFI_COMPRESSION_SECTION2 *CompressionSect2;
+ COMPRESS_FUNCTION CompressFunction;
+
+ InputLength = 0;
+ FileBuffer = NULL;
+ OutputBuffer = NULL;
+ CompressedLength = 0;
+ TotalLength = 0;
+ //
+ // read all input file contents into a buffer
+ // first get the size of all file contents
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ FileBuffer,
+ &InputLength
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FileBuffer = (UINT8 *) malloc (InputLength);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // read all input file contents into a buffer
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ FileBuffer,
+ &InputLength
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+ return Status;
+ }
+
+ if (FileBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CompressFunction = NULL;
+
+ //
+ // Now data is in FileBuffer, compress the data
+ //
+ switch (SectCompSubType) {
+ case EFI_NOT_COMPRESSED:
+ CompressedLength = InputLength;
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION);
+ if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);
+ }
+ TotalLength = CompressedLength + HeaderLength;
+ //
+ // Copy file buffer to the none compressed data.
+ //
+ OutputBuffer = malloc (TotalLength);
+ if (OutputBuffer == NULL) {
+ free (FileBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memcpy (OutputBuffer + HeaderLength, FileBuffer, CompressedLength);
+ free (FileBuffer);
+ FileBuffer = OutputBuffer;
+ break;
+
+ case EFI_STANDARD_COMPRESSION:
+ CompressFunction = (COMPRESS_FUNCTION) EfiCompress;
+ break;
+
+ default:
+ Error (NULL, 0, 2000, "Invalid parameter", "unknown compression type");
+ free (FileBuffer);
+ return EFI_ABORTED;
+ }
+
+ if (CompressFunction != NULL) {
+
+ Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION);
+ if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);
+ }
+ TotalLength = CompressedLength + HeaderLength;
+ OutputBuffer = malloc (TotalLength);
+ if (!OutputBuffer) {
+ free (FileBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + HeaderLength, &CompressedLength);
+ }
+
+ free (FileBuffer);
+ FileBuffer = OutputBuffer;
+
+ if (EFI_ERROR (Status)) {
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+
+ return Status;
+ }
+
+ if (FileBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ DebugMsg (NULL, 0, 9, "comprss file size",
+ "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);
+
+ //if (TotalLength >= MAX_SECTION_SIZE) {
+ // Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
+ // if (FileBuffer != NULL) {
+ // free (FileBuffer);
+ // }
+ // if (OutputBuffer != NULL) {
+ // free (OutputBuffer);
+ // }
+ // return STATUS_ERROR;
+ //}
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);
+
+ //
+ // Add the section header for the compressed data
+ //
+ if (TotalLength >= MAX_SECTION_SIZE) {
+ CompressionSect2 = (EFI_COMPRESSION_SECTION2 *)FileBuffer;
+
+ memset(CompressionSect2->CommonHeader.Size, 0xff, sizeof(UINT8) * 3);
+ CompressionSect2->CommonHeader.Type = EFI_SECTION_COMPRESSION;
+ CompressionSect2->CommonHeader.ExtendedSize = TotalLength;
+ CompressionSect2->CompressionType = SectCompSubType;
+ CompressionSect2->UncompressedLength = InputLength;
+ } else {
+ CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;
+
+ CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;
+ CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
+ CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ CompressionSect->CompressionType = SectCompSubType;
+ CompressionSect->UncompressedLength = InputLength;
+ }
+
+ //
+ // Set OutFileBuffer
+ //
+ *OutFileBuffer = FileBuffer;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GenSectionGuidDefinedSection (
+ CHAR8 **InputFileName,
+ UINT32 *InputFileAlign,
+ UINT32 InputFileNum,
+ EFI_GUID *VendorGuid,
+ UINT16 DataAttribute,
+ UINT32 DataHeaderSize,
+ UINT8 **OutFileBuffer
+ )
+/*++
+
+Routine Description:
+
+ Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED
+ Input file must be already sectioned. The function won't validate
+ the input files' contents. Caller should hand in files already
+ with section header.
+
+Arguments:
+
+ InputFileName - Name of the input file.
+
+ InputFileAlign - Alignment required by the input file data.
+
+ InputFileNum - Number of input files. Should be at least 1.
+
+ VendorGuid - Specify vendor guid value.
+
+ DataAttribute - Specify attribute for the vendor guid data.
+
+ DataHeaderSize- Guided Data Header Size
+
+ OutFileBuffer - Buffer pointer to Output file contents
+
+Returns:
+
+ EFI_SUCCESS on successful return
+ EFI_INVALID_PARAMETER if InputFileNum is less than 1
+ EFI_ABORTED if unable to open input file.
+ EFI_OUT_OF_RESOURCES No resource to complete the operation.
+
+--*/
+{
+ UINT32 TotalLength;
+ UINT32 InputLength;
+ UINT32 Offset;
+ UINT8 *FileBuffer;
+ UINT32 Crc32Checksum;
+ EFI_STATUS Status;
+ CRC32_SECTION_HEADER *Crc32GuidSect;
+ CRC32_SECTION_HEADER2 *Crc32GuidSect2;
+ EFI_GUID_DEFINED_SECTION *VendorGuidSect;
+ EFI_GUID_DEFINED_SECTION2 *VendorGuidSect2;
+
+ InputLength = 0;
+ Offset = 0;
+ FileBuffer = NULL;
+ TotalLength = 0;
+
+ //
+ // read all input file contents into a buffer
+ // first get the size of all file contents
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ FileBuffer,
+ &InputLength
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {
+ Offset = sizeof (CRC32_SECTION_HEADER);
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {
+ Offset = sizeof (CRC32_SECTION_HEADER2);
+ }
+ } else {
+ Offset = sizeof (EFI_GUID_DEFINED_SECTION);
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {
+ Offset = sizeof (EFI_GUID_DEFINED_SECTION2);
+ }
+ }
+ TotalLength = InputLength + Offset;
+
+ FileBuffer = (UINT8 *) malloc (InputLength + Offset);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // read all input file contents into a buffer
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ FileBuffer + Offset,
+ &InputLength
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+ Error (NULL, 0, 0001, "Error opening file for reading", InputFileName[0]);
+ return Status;
+ }
+
+ if (InputLength == 0) {
+ if (FileBuffer != NULL) {
+ free (FileBuffer);
+ }
+ Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // InputLength != 0, but FileBuffer == NULL means out of resources.
+ //
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Now data is in FileBuffer + Offset
+ //
+ if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {
+ //
+ // Default Guid section is CRC32.
+ //
+ Crc32Checksum = 0;
+ CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);
+
+ if (TotalLength >= MAX_SECTION_SIZE) {
+ Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) 0xff;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) 0xff;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) 0xff;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.ExtendedSize = TotalLength;
+ memcpy (&(Crc32GuidSect2->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));
+ Crc32GuidSect2->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
+ Crc32GuidSect2->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER2);
+ Crc32GuidSect2->CRC32Checksum = Crc32Checksum;
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2->GuidSectionHeader.DataOffset);
+ } else {
+ Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));
+ Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
+ Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);
+ Crc32GuidSect->CRC32Checksum = Crc32Checksum;
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);
+ }
+ } else {
+ if (TotalLength >= MAX_SECTION_SIZE) {
+ VendorGuidSect2 = (EFI_GUID_DEFINED_SECTION2 *) FileBuffer;
+ VendorGuidSect2->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ VendorGuidSect2->CommonHeader.Size[0] = (UINT8) 0xff;
+ VendorGuidSect2->CommonHeader.Size[1] = (UINT8) 0xff;
+ VendorGuidSect2->CommonHeader.Size[2] = (UINT8) 0xff;
+ VendorGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_GUID_DEFINED_SECTION2);
+ memcpy (&(VendorGuidSect2->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));
+ VendorGuidSect2->Attributes = DataAttribute;
+ VendorGuidSect2->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION2) + DataHeaderSize);
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2->DataOffset);
+ } else {
+ VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;
+ VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
+ VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));
+ VendorGuidSect->Attributes = DataAttribute;
+ VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);
+ }
+ }
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);
+
+ //
+ // Set OutFileBuffer
+ //
+ *OutFileBuffer = FileBuffer;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FfsRebaseImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINT32 *ReadSize,
+ OUT VOID *Buffer
+ )
+ /*++
+
+ Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+ Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+
+ FileOffset - The offset, in bytes, into the file to read
+
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+
+ Buffer - A pointer to the buffer to read the data into.
+
+ Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+ --*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINT32 Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
+ /*
+ InFile is input file for getting alignment
+ return the alignment
+ */
+{
+ FILE *InFileHandle;
+ UINT8 *PeFileBuffer;
+ UINTN PeFileSize;
+ UINT32 CurSecHdrSize;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_COMMON_SECTION_HEADER *CommonHeader;
+ EFI_STATUS Status;
+
+ InFileHandle = NULL;
+ PeFileBuffer = NULL;
+ *Alignment = 0;
+
+ memset (&ImageContext, 0, sizeof (ImageContext));
+
+ InFileHandle = fopen(LongFilePath(InFile), "rb");
+ if (InFileHandle == NULL){
+ Error (NULL, 0, 0001, "Error opening file", InFile);
+ return EFI_ABORTED;
+ }
+ PeFileSize = _filelength (fileno(InFileHandle));
+ PeFileBuffer = (UINT8 *) malloc (PeFileSize);
+ if (PeFileBuffer == NULL) {
+ fclose (InFileHandle);
+ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
+ fclose (InFileHandle);
+ CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;
+ CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
+ ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo(&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);
+ return Status;
+ }
+ *Alignment = ImageContext.SectionAlignment;
+ // Free the allocated memory resource
+ if (PeFileBuffer != NULL) {
+ free (PeFileBuffer);
+ PeFileBuffer = NULL;
+ }
+ return EFI_SUCCESS;
+}
+
+int
+main (
+ int argc,
+ char *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main
+
+Arguments:
+
+ command line parameters
+
+Returns:
+
+ EFI_SUCCESS Section header successfully generated and section concatenated.
+ EFI_ABORTED Could not generate the section
+ EFI_OUT_OF_RESOURCES No resource to complete the operation.
+
+--*/
+{
+ UINT32 Index;
+ UINT32 InputFileNum;
+ FILE *OutFile;
+ CHAR8 **InputFileName;
+ CHAR8 *OutputFileName;
+ CHAR8 *SectionName;
+ CHAR8 *CompressionName;
+ CHAR8 *StringBuffer;
+ EFI_GUID VendorGuid = mZeroGuid;
+ int VersionNumber;
+ UINT8 SectType;
+ UINT8 SectCompSubType;
+ UINT16 SectGuidAttribute;
+ UINT64 SectGuidHeaderLength;
+ EFI_VERSION_SECTION *VersionSect;
+ EFI_USER_INTERFACE_SECTION *UiSect;
+ UINT32 InputLength;
+ UINT8 *OutFileBuffer;
+ EFI_STATUS Status;
+ UINT64 LogLevel;
+ UINT32 *InputFileAlign;
+ UINT32 InputFileAlignNum;
+ EFI_COMMON_SECTION_HEADER *SectionHeader;
+ CHAR8 *DummyFileName;
+ FILE *DummyFile;
+ UINTN DummyFileSize;
+ UINT8 *DummyFileBuffer;
+ FILE *InFile;
+ UINT8 *InFileBuffer;
+ UINTN InFileSize;
+
+ InputFileAlign = NULL;
+ InputFileAlignNum = 0;
+ InputFileName = NULL;
+ OutputFileName = NULL;
+ SectionName = NULL;
+ CompressionName = NULL;
+ StringBuffer = "";
+ OutFile = NULL;
+ VersionNumber = 0;
+ InputFileNum = 0;
+ SectType = EFI_SECTION_ALL;
+ SectCompSubType = 0;
+ SectGuidAttribute = EFI_GUIDED_SECTION_NONE;
+ OutFileBuffer = NULL;
+ InputLength = 0;
+ Status = STATUS_SUCCESS;
+ LogLevel = 0;
+ SectGuidHeaderLength = 0;
+ VersionSect = NULL;
+ UiSect = NULL;
+ DummyFileSize = 0;
+ DummyFileName = NULL;
+ DummyFile = NULL;
+ DummyFileBuffer = NULL;
+ InFile = NULL;
+ InFileSize = 0;
+ InFileBuffer = NULL;
+
+ SetUtilityName (UTILITY_NAME);
+
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No options input");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ //
+ // Parse command line
+ //
+ argc --;
+ argv ++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Version ();
+ Usage ();
+ return STATUS_SUCCESS;
+ }
+
+ if (stricmp (argv[0], "--version") == 0) {
+ Version ();
+ return STATUS_SUCCESS;
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--SectionType") == 0)) {
+ SectionName = argv[1];
+ if (SectionName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Section Type can't be NULL");
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
+ OutputFileName = argv[1];
+ if (OutputFileName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Output file can't be NULL");
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {
+ CompressionName = argv[1];
+ if (CompressionName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Compression Type can't be NULL");
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--vendor") == 0)) {
+ Status = StringToGuid (argv[1], &VendorGuid);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ if (stricmp (argv[0], "--dummy") == 0) {
+ DummyFileName = argv[1];
+ if (DummyFileName == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");
+ goto Finish;
+ }
+ if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {
+ SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
+ } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {
+ SectGuidAttribute |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
+ } else if (stricmp (argv[1], mGUIDedSectionAttribue[0]) == 0) {
+ //
+ // NONE attribute
+ //
+ SectGuidAttribute |= EFI_GUIDED_SECTION_NONE;
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--HeaderLength") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &SectGuidHeaderLength);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--name") == 0)) {
+ StringBuffer = argv[1];
+ if (StringBuffer == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Name can't be NULL");
+ goto Finish;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--buildnumber") == 0)) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "build number can't be NULL");
+ goto Finish;
+ }
+ //
+ // Verify string is a integrator number
+ //
+ for (Index = 0; Index < strlen (argv[1]); Index++) {
+ if ((argv[1][Index] != '-') && (isdigit ((int)argv[1][Index]) == 0)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ }
+
+ sscanf (argv[1], "%d", &VersionNumber);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
+ SetPrintLevel (VERBOSE_LOG_LEVEL);
+ VerboseMsg ("Verbose output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ SetPrintLevel (KEY_LOG_LEVEL);
+ KeyMsg ("Quiet output Mode Set!");
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ if (LogLevel > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0~9, current input level is %d", (int) LogLevel);
+ goto Finish;
+ }
+ SetPrintLevel (LogLevel);
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ //
+ // Section File alignment requirement
+ //
+ if (stricmp (argv[0], "--sectionalign") == 0) {
+ if (InputFileAlignNum == 0) {
+ InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
+ if (InputFileAlign == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+ memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
+ } else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {
+ InputFileAlign = (UINT32 *) realloc (
+ InputFileAlign,
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)
+ );
+
+ if (InputFileAlign == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ goto Finish;
+ }
+ memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));
+ }
+ if (stricmp(argv[1], "0") == 0) {
+ InputFileAlign[InputFileAlignNum] = 0;
+ } else {
+ Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ }
+ argc -= 2;
+ argv += 2;
+ InputFileAlignNum ++;
+ continue;
+ }
+
+ //
+ // Get Input file name
+ //
+ if ((InputFileNum == 0) && (InputFileName == NULL)) {
+ InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+ memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
+ } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
+ //
+ // InputFileName buffer too small, need to realloc
+ //
+ InputFileName = (CHAR8 **) realloc (
+ InputFileName,
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
+ );
+
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+ memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
+ }
+
+ InputFileName[InputFileNum++] = argv[0];
+ argc --;
+ argv ++;
+ }
+
+ if (InputFileAlignNum > 0 && InputFileAlignNum != InputFileNum) {
+ Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");
+ goto Finish;
+ }
+ for (Index = 0; Index < InputFileAlignNum; Index++)
+ {
+ if (InputFileAlign[Index] == 0) {
+ Status = GetAlignmentFromFile(InputFileName[Index], &(InputFileAlign[Index]));
+ if (EFI_ERROR(Status)) {
+ Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);
+ goto Finish;
+ }
+ }
+ }
+
+ VerboseMsg ("%s tool start.", UTILITY_NAME);
+
+ if (DummyFileName != NULL) {
+ //
+ // Open file and read contents
+ //
+ DummyFile = fopen (LongFilePath (DummyFileName), "rb");
+ if (DummyFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", DummyFileName);
+ goto Finish;
+ }
+
+ fseek (DummyFile, 0, SEEK_END);
+ DummyFileSize = ftell (DummyFile);
+ fseek (DummyFile, 0, SEEK_SET);
+ DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);
+ if (DummyFileBuffer == NULL) {
+ fclose(DummyFile);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+
+ fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);
+ fclose(DummyFile);
+ DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);
+
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+ InFile = fopen(LongFilePath(InputFileName[0]), "rb");
+ if (InFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);
+ goto Finish;
+ }
+
+ fseek (InFile, 0, SEEK_END);
+ InFileSize = ftell (InFile);
+ fseek (InFile, 0, SEEK_SET);
+ InFileBuffer = (UINT8 *) malloc (InFileSize);
+ if (InFileBuffer == NULL) {
+ fclose(InFile);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+
+ fread(InFileBuffer, 1, InFileSize, InFile);
+ fclose(InFile);
+ DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);
+ if (InFileSize > DummyFileSize){
+ if (stricmp((CHAR8 *)DummyFileBuffer, (CHAR8 *)(InFileBuffer + (InFileSize - DummyFileSize))) == 0){
+ SectGuidHeaderLength = InFileSize - DummyFileSize;
+ }
+ }
+ if (SectGuidHeaderLength == 0) {
+ SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
+ }
+ if (DummyFileBuffer != NULL) {
+ free (DummyFileBuffer);
+ DummyFileBuffer = NULL;
+ }
+ if (InFileBuffer != NULL) {
+ free (InFileBuffer);
+ }
+ }
+
+ //
+ // Parse all command line parameters to get the corresponding section type.
+ //
+ VerboseMsg ("Section type is %s", SectionName);
+ if (SectionName == NULL) {
+ //
+ // No specified Section type, default is SECTION_ALL.
+ //
+ SectType = EFI_SECTION_ALL;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {
+ SectType = EFI_SECTION_COMPRESSION;
+ if (CompressionName == NULL) {
+ //
+ // Default is PI_STD compression algorithm.
+ //
+ SectCompSubType = EFI_STANDARD_COMPRESSION;
+ } else if (stricmp (CompressionName, mCompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {
+ SectCompSubType = EFI_NOT_COMPRESSED;
+ } else if (stricmp (CompressionName, mCompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {
+ SectCompSubType = EFI_STANDARD_COMPRESSION;
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "--compress = %s", CompressionName);
+ goto Finish;
+ }
+ VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {
+ SectType = EFI_SECTION_GUID_DEFINED;
+
+ if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {
+ //
+ // NONE attribute, clear attribute value.
+ //
+ SectGuidAttribute = SectGuidAttribute & ~EFI_GUIDED_SECTION_NONE;
+ }
+ VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ (unsigned) VendorGuid.Data1,
+ VendorGuid.Data2,
+ VendorGuid.Data3,
+ VendorGuid.Data4[0],
+ VendorGuid.Data4[1],
+ VendorGuid.Data4[2],
+ VendorGuid.Data4[3],
+ VendorGuid.Data4[4],
+ VendorGuid.Data4[5],
+ VendorGuid.Data4[6],
+ VendorGuid.Data4[7]);
+ if ((SectGuidAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
+ VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]);
+ }
+ if ((SectGuidAttribute & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {
+ VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]);
+ }
+ if (SectGuidHeaderLength != 0) {
+ VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength);
+ }
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PE32]) == 0) {
+ SectType = EFI_SECTION_PE32;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PIC]) == 0) {
+ SectType = EFI_SECTION_PIC;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_TE]) == 0) {
+ SectType = EFI_SECTION_TE;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {
+ SectType = EFI_SECTION_DXE_DEPEX;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_SMM_DEPEX]) == 0) {
+ SectType = EFI_SECTION_SMM_DEPEX;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {
+ SectType = EFI_SECTION_VERSION;
+ if (VersionNumber < 0 || VersionNumber > 65535) {
+ Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber);
+ goto Finish;
+ }
+ VerboseMsg ("Version section number is %d", VersionNumber);
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {
+ SectType = EFI_SECTION_USER_INTERFACE;
+ if (StringBuffer[0] == '\0') {
+ Error (NULL, 0, 1001, "Missing option", "user interface string");
+ goto Finish;
+ }
+ VerboseMsg ("UI section string name is %s", StringBuffer);
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {
+ SectType = EFI_SECTION_COMPATIBILITY16;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {
+ SectType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {
+ SectType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_RAW]) == 0) {
+ SectType = EFI_SECTION_RAW;
+ } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {
+ SectType = EFI_SECTION_PEI_DEPEX;
+ } else {
+ Error (NULL, 0, 1003, "Invalid option value", "SectionType = %s", SectionName);
+ goto Finish;
+ }
+
+ //
+ // GuidValue is only required by Guided section.
+ //
+ if ((SectType != EFI_SECTION_GUID_DEFINED) &&
+ (SectionName != NULL) &&
+ (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {
+ fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);
+ }
+
+ //
+ // Check whether there is input file
+ //
+ if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {
+ //
+ // The input file are required for other section type.
+ //
+ if (InputFileNum == 0) {
+ Error (NULL, 0, 1001, "Missing options", "Input files");
+ goto Finish;
+ }
+ }
+ //
+ // Check whether there is output file
+ //
+ for (Index = 0; Index < InputFileNum; Index ++) {
+ VerboseMsg ("the %uth input file name is %s", (unsigned) Index, InputFileName[Index]);
+ }
+ if (OutputFileName == NULL) {
+ Error (NULL, 0, 1001, "Missing options", "Output file");
+ goto Finish;
+ // OutFile = stdout;
+ }
+ VerboseMsg ("Output file name is %s", OutputFileName);
+
+ //
+ // At this point, we've fully validated the command line, and opened appropriate
+ // files, so let's go and do what we've been asked to do...
+ //
+ //
+ // Within this switch, build and write out the section header including any
+ // section type specific pieces. If there's an input file, it's tacked on later
+ //
+ switch (SectType) {
+ case EFI_SECTION_COMPRESSION:
+ if (InputFileAlign != NULL) {
+ free (InputFileAlign);
+ InputFileAlign = NULL;
+ }
+ Status = GenSectionCompressionSection (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ SectCompSubType,
+ &OutFileBuffer
+ );
+ break;
+
+ case EFI_SECTION_GUID_DEFINED:
+ if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {
+ //
+ // Only process alignment for the default known CRC32 guided section.
+ // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.
+ //
+ free (InputFileAlign);
+ InputFileAlign = NULL;
+ }
+ Status = GenSectionGuidDefinedSection (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ &VendorGuid,
+ SectGuidAttribute,
+ (UINT32) SectGuidHeaderLength,
+ &OutFileBuffer
+ );
+ break;
+
+ case EFI_SECTION_VERSION:
+ Index = sizeof (EFI_COMMON_SECTION_HEADER);
+ //
+ // 2 bytes for the build number UINT16
+ //
+ Index += 2;
+ //
+ // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
+ //
+ Index += (strlen (StringBuffer) * 2) + 2;
+ OutFileBuffer = (UINT8 *) malloc (Index);
+ if (OutFileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+ VersionSect = (EFI_VERSION_SECTION *) OutFileBuffer;
+ VersionSect->CommonHeader.Type = SectType;
+ VersionSect->CommonHeader.Size[0] = (UINT8) (Index & 0xff);
+ VersionSect->CommonHeader.Size[1] = (UINT8) ((Index & 0xff00) >> 8);
+ VersionSect->CommonHeader.Size[2] = (UINT8) ((Index & 0xff0000) >> 16);
+ VersionSect->BuildNumber = (UINT16) VersionNumber;
+ Ascii2UnicodeString (StringBuffer, VersionSect->VersionString);
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);
+ break;
+
+ case EFI_SECTION_USER_INTERFACE:
+ Index = sizeof (EFI_COMMON_SECTION_HEADER);
+ //
+ // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.
+ //
+ Index += (strlen (StringBuffer) * 2) + 2;
+ OutFileBuffer = (UINT8 *) malloc (Index);
+ if (OutFileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+ UiSect = (EFI_USER_INTERFACE_SECTION *) OutFileBuffer;
+ UiSect->CommonHeader.Type = SectType;
+ UiSect->CommonHeader.Size[0] = (UINT8) (Index & 0xff);
+ UiSect->CommonHeader.Size[1] = (UINT8) ((Index & 0xff00) >> 8);
+ UiSect->CommonHeader.Size[2] = (UINT8) ((Index & 0xff0000) >> 16);
+ Ascii2UnicodeString (StringBuffer, UiSect->FileNameString);
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);
+ break;
+
+ case EFI_SECTION_ALL:
+ //
+ // read all input file contents into a buffer
+ // first get the size of all file contents
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ OutFileBuffer,
+ &InputLength
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ OutFileBuffer = (UINT8 *) malloc (InputLength);
+ if (OutFileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");
+ goto Finish;
+ }
+ //
+ // read all input file contents into a buffer
+ //
+ Status = GetSectionContents (
+ InputFileName,
+ InputFileAlign,
+ InputFileNum,
+ OutFileBuffer,
+ &InputLength
+ );
+ }
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength);
+ break;
+ default:
+ //
+ // All other section types are caught by default (they're all the same)
+ //
+ Status = GenSectionCommonLeafSection (
+ InputFileName,
+ InputFileNum,
+ SectType,
+ &OutFileBuffer
+ );
+ break;
+ }
+
+ if (Status != EFI_SUCCESS || OutFileBuffer == NULL) {
+ Error (NULL, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status);
+ goto Finish;
+ }
+
+ //
+ // Get output file length
+ //
+ if (SectType != EFI_SECTION_ALL) {
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *)OutFileBuffer;
+ InputLength = *(UINT32 *)SectionHeader->Size & 0x00ffffff;
+ if (InputLength == 0xffffff) {
+ InputLength = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
+ }
+ }
+
+ //
+ // Write the output file
+ //
+ OutFile = fopen (LongFilePath (OutputFileName), "wb");
+ if (OutFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);
+ goto Finish;
+ }
+
+ fwrite (OutFileBuffer, InputLength, 1, OutFile);
+
+Finish:
+ if (InputFileName != NULL) {
+ free (InputFileName);
+ }
+
+ if (InputFileAlign != NULL) {
+ free (InputFileAlign);
+ }
+
+ if (OutFileBuffer != NULL) {
+ free (OutFileBuffer);
+ }
+
+ if (OutFile != NULL) {
+ fclose (OutFile);
+ }
+
+ if (DummyFileBuffer != NULL) {
+ free (DummyFileBuffer);
+ }
+
+ VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
+
+ return GetUtilityStatus ();
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile
new file mode 100644
index 00000000..8b9d4841
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile
@@ -0,0 +1,18 @@
+## @file
+# Windows makefile for 'GenSec' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenSec
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = GenSec.obj
+
+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile.kmk
new file mode 100644
index 00000000..d294db44
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/GenSec/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI GenSec build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += GenSec
+GenSec_TEMPLATE = VBoxEfiBldProg
+GenSec_SOURCES = GenSec.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/AArch64/ProcessorBind.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/AArch64/ProcessorBind.h
new file mode 100644
index 00000000..93d656f5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/AArch64/ProcessorBind.h
@@ -0,0 +1,148 @@
+/** @file
+ Processor or Compiler specific defines and types for AArch64.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+///
+/// Define the processor type so other code can make processor based choices
+///
+#define MDE_CPU_AARCH64
+
+//
+// Make sure we are using the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+#if _MSC_EXTENSIONS
+ //
+ // use Microsoft* C compiler dependent integer width types
+ //
+ typedef unsigned __int64 UINT64;
+ typedef __int64 INT64;
+ typedef unsigned __int32 UINT32;
+ typedef __int32 INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef signed char INT8;
+#else
+ //
+ // Use ANSI C 2000 stdint.h integer width declarations
+ //
+ #include <stdint.h>
+ typedef uint8_t BOOLEAN;
+ typedef int8_t INT8;
+ typedef uint8_t UINT8;
+ typedef int16_t INT16;
+ typedef uint16_t UINT16;
+ typedef int32_t INT32;
+ typedef uint32_t UINT32;
+ typedef int64_t INT64;
+ typedef uint64_t UINT64;
+ typedef char CHAR8;
+ typedef uint16_t CHAR16;
+
+#endif
+
+///
+/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
+/// 8 bytes on supported 64-bit processor instructions)
+///
+typedef UINT64 UINTN;
+
+///
+/// Signed value of native width. (4 bytes on supported 32-bit processor instructions,
+/// 8 bytes on supported 64-bit processor instructions)
+///
+typedef INT64 INTN;
+
+//
+// Processor specific defines
+//
+
+///
+/// A value of native width with the highest bit set.
+///
+#define MAX_BIT 0x8000000000000000
+
+///
+/// A value of native width with the two highest bits set.
+///
+#define MAX_2_BITS 0xC000000000000000
+
+///
+/// The stack alignment required for AARCH64
+///
+#define CPU_STACK_ALIGNMENT 16
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#define EFIAPI
+
+#if defined(__GNUC__)
+ ///
+ /// For GNU assembly code, .global or .globl can declare global symbols.
+ /// Define this macro to unify the usage.
+ ///
+ #define ASM_GLOBAL .globl
+
+ #if !defined(__APPLE__)
+ ///
+ /// ARM EABI defines that the linker should not manipulate call relocations
+ /// (do bl/blx conversion) unless the target symbol has function type.
+ /// CodeSourcery 2010.09 started requiring the .type to function properly
+ ///
+ #define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function
+
+ #define GCC_ASM_EXPORT(func__) \
+ .global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
+ .type ASM_PFX(func__), %function
+
+ #define GCC_ASM_IMPORT(func__) \
+ .extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
+
+ #else
+ //
+ // .type not supported by Apple Xcode tools
+ //
+ #define INTERWORK_FUNC(func__)
+
+ #define GCC_ASM_EXPORT(func__) \
+ .globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \
+
+ #define GCC_ASM_IMPORT(name)
+
+ #endif
+#endif
+
+/**
+ Return the pointer to the first instruction of a function given a function pointer.
+ On ARM CPU architectures, these two pointer values are the same,
+ so the implementation of this macro is very simple.
+
+ @param FunctionPointer A pointer to a function.
+
+ @return The pointer to the first instruction of a function given a function pointer.
+
+**/
+#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
+
+#endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Arm/ProcessorBind.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Arm/ProcessorBind.h
new file mode 100644
index 00000000..de5c5a0a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Arm/ProcessorBind.h
@@ -0,0 +1,147 @@
+/** @file
+ Processor or Compiler specific defines and types for ARM.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+///
+/// Define the processor type so other code can make processor based choices
+///
+#define MDE_CPU_ARM
+
+//
+// Make sure we are using the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+#if _MSC_EXTENSIONS
+ //
+ // use Microsoft* C compiler dependent integer width types
+ //
+ typedef unsigned __int64 UINT64;
+ typedef __int64 INT64;
+ typedef unsigned __int32 UINT32;
+ typedef __int32 INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef signed char INT8;
+#else
+ //
+ // Assume standard ARM alignment.
+ //
+ typedef unsigned long long UINT64;
+ typedef long long INT64;
+ typedef unsigned int UINT32;
+ typedef int INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef signed char INT8;
+
+ #define UINT8_MAX 0xff
+#endif
+
+///
+/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
+/// 8 bytes on supported 64-bit processor instructions)
+///
+typedef UINT32 UINTN;
+
+///
+/// Signed value of native width. (4 bytes on supported 32-bit processor instructions,
+/// 8 bytes on supported 64-bit processor instructions)
+///
+typedef INT32 INTN;
+
+//
+// Processor specific defines
+//
+
+///
+/// A value of native width with the highest bit set.
+///
+#define MAX_BIT 0x80000000
+
+///
+/// A value of native width with the two highest bits set.
+///
+#define MAX_2_BITS 0xC0000000
+
+///
+/// The stack alignment required for ARM
+///
+#define CPU_STACK_ALIGNMENT sizeof(UINT64)
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#define EFIAPI
+
+#if defined(__GNUC__)
+ ///
+ /// For GNU assembly code, .global or .globl can declare global symbols.
+ /// Define this macro to unify the usage.
+ ///
+ #define ASM_GLOBAL .globl
+
+ #if !defined(__APPLE__)
+ ///
+ /// ARM EABI defines that the linker should not manipulate call relocations
+ /// (do bl/blx conversion) unless the target symbol has function type.
+ /// CodeSourcery 2010.09 started requiring the .type to function properly
+ ///
+ #define INTERWORK_FUNC(func__) .type ASM_PFX(func__), %function
+
+ #define GCC_ASM_EXPORT(func__) \
+ .global _CONCATENATE (__USER_LABEL_PREFIX__, func__) ;\
+ .type ASM_PFX(func__), %function
+
+ #define GCC_ASM_IMPORT(func__) \
+ .extern _CONCATENATE (__USER_LABEL_PREFIX__, func__)
+
+ #else
+ //
+ // .type not supported by Apple Xcode tools
+ //
+ #define INTERWORK_FUNC(func__)
+
+ #define GCC_ASM_EXPORT(func__) \
+ .globl _CONCATENATE (__USER_LABEL_PREFIX__, func__) \
+
+ #define GCC_ASM_IMPORT(name)
+
+ #endif
+#endif
+
+/**
+ Return the pointer to the first instruction of a function given a function pointer.
+ On ARM CPU architectures, these two pointer values are the same,
+ so the implementation of this macro is very simple.
+
+ @param FunctionPointer A pointer to a function.
+
+ @return The pointer to the first instruction of a function given a function pointer.
+
+**/
+#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
+
+#endif
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BaseTypes.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BaseTypes.h
new file mode 100644
index 00000000..18d202e0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BaseTypes.h
@@ -0,0 +1,318 @@
+/** @file
+ Processor or Compiler specific defines for all supported processors.
+
+ This file is stand alone self consistent set of definitions.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __BASE_TYPES_H__
+#define __BASE_TYPES_H__
+
+//
+// Include processor specific binding
+//
+#include <ProcessorBind.h>
+#include <stdarg.h>
+
+//
+// Modifiers to abstract standard types to aid in debug of problems
+//
+#define CONST const
+#define STATIC static
+#define VOID void
+
+//
+// Modifiers for Data Types used to self document code.
+// This concept is borrowed for UEFI specification.
+//
+#ifndef IN
+//
+// Some other environments use this construct, so #ifndef to prevent
+// multiple definition.
+//
+#define IN
+#define OUT
+#define OPTIONAL
+#endif
+
+//
+// Constants. They may exist in other build structures, so #ifndef them.
+//
+#ifndef TRUE
+//
+// BugBug: UEFI specification claims 1 and 0. We are concerned about the
+// compiler portability so we did it this way.
+//
+#define TRUE ((BOOLEAN)(1==1))
+#endif
+
+#ifndef FALSE
+#define FALSE ((BOOLEAN)(0==1))
+#endif
+
+#ifndef NULL
+#define NULL ((VOID *) 0)
+#endif
+
+#ifdef __CC_ARM
+ //
+ // Older RVCT ARM compilers don't fully support #pragma pack and require __packed
+ // as a prefix for the structure.
+ //
+ #define PACKED __packed
+#else
+ #define PACKED
+#endif
+
+//
+// Support for variable length argument lists using the ANSI standard.
+//
+// Since we are using the ANSI standard we used the standard naming and
+// did not follow the coding convention
+//
+// VA_LIST - typedef for argument list.
+// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
+// VA_END (VA_LIST Marker) - Clear Marker
+// VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from
+// the ... list. You must know the size and pass it in this macro.
+//
+// example:
+//
+// UINTN
+// ExampleVarArg (
+// IN UINTN NumberOfArgs,
+// ...
+// )
+// {
+// VA_LIST Marker;
+// UINTN Index;
+// UINTN Result;
+//
+// //
+// // Initialize the Marker
+// //
+// VA_START (Marker, NumberOfArgs);
+// for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {
+// //
+// // The ... list is a series of UINTN values, so average them up.
+// //
+// Result += VA_ARG (Marker, UINTN);
+// }
+//
+// VA_END (Marker);
+// return Result
+// }
+//
+
+#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
+
+//
+// Also support coding convention rules for var arg macros
+//
+#ifndef VA_START
+
+// typedef CHAR8 *VA_LIST;
+// #define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v))
+// #define VA_ARG(ap, t) (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t)))
+// #define VA_END(ap) (ap = (VA_LIST) 0)
+// Use the native arguments for tools.
+#define VA_START va_start
+#define VA_ARG va_arg
+#define VA_END va_end
+#define VA_LIST va_list
+
+#endif
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+///
+/// 128 bit buffer containing a unique identifier value.
+/// Unless otherwise specified, aligned on a 64 bit boundary.
+///
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} GUID;
+#endif
+
+///
+/// 4-byte buffer. An IPv4 internet protocol address.
+///
+typedef struct {
+ UINT8 Addr[4];
+} IPv4_ADDRESS;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef struct {
+ UINT8 Addr[16];
+} IPv6_ADDRESS;
+
+//
+// Macro that returns the byte offset of a field in a data structure.
+//
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+
+///
+/// _CR - returns a pointer to the structure
+/// from one of its elements.
+///
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+///
+/// ALIGN_POINTER - aligns a pointer to the lowest boundary
+///
+#define ALIGN_POINTER(p, s) ((VOID *) ((UINTN)(p) + (((s) - ((UINTN) (p))) & ((s) - 1))))
+
+///
+/// ALIGN_VARIABLE - aligns a variable up to the next natural boundary for int size of a processor
+///
+#define ALIGN_VARIABLE(Value, Adjustment) \
+ Adjustment = 0U; \
+ if ((UINTN) (Value) % sizeof (UINTN)) { \
+ (Adjustment) = (UINTN)(sizeof (UINTN) - ((UINTN) (Value) % sizeof (UINTN))); \
+ } \
+ (Value) = (UINTN)((UINTN) (Value) + (UINTN) (Adjustment))
+
+//
+// Return the maximum of two operands.
+// This macro returns the maximum of two operand specified by a and b.
+// Both a and b must be the same numerical types, signed or unsigned.
+//
+#define MAX(a, b) \
+ (((a) > (b)) ? (a) : (b))
+
+
+//
+// Return the minimum of two operands.
+// This macro returns the minimal of two operand specified by a and b.
+// Both a and b must be the same numerical types, signed or unsigned.
+//
+#define MIN(a, b) \
+ (((a) < (b)) ? (a) : (b))
+
+
+//
+// EFI Error Codes common to all execution phases
+//
+
+typedef UINTN RETURN_STATUS;
+
+///
+/// Set the upper bit to indicate EFI Error.
+///
+#define ENCODE_ERROR(a) ((RETURN_STATUS)(MAX_BIT | (a)))
+
+#define ENCODE_WARNING(a) ((RETURN_STATUS)(a))
+#define RETURN_ERROR(a) (((INTN)(RETURN_STATUS)(a)) < 0)
+
+#define RETURN_SUCCESS 0
+#define RETURN_LOAD_ERROR ENCODE_ERROR (1)
+#define RETURN_INVALID_PARAMETER ENCODE_ERROR (2)
+#define RETURN_UNSUPPORTED ENCODE_ERROR (3)
+#define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR (4)
+#define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR (5)
+#define RETURN_NOT_READY ENCODE_ERROR (6)
+#define RETURN_DEVICE_ERROR ENCODE_ERROR (7)
+#define RETURN_WRITE_PROTECTED ENCODE_ERROR (8)
+#define RETURN_OUT_OF_RESOURCES ENCODE_ERROR (9)
+#define RETURN_VOLUME_CORRUPTED ENCODE_ERROR (10)
+#define RETURN_VOLUME_FULL ENCODE_ERROR (11)
+#define RETURN_NO_MEDIA ENCODE_ERROR (12)
+#define RETURN_MEDIA_CHANGED ENCODE_ERROR (13)
+#define RETURN_NOT_FOUND ENCODE_ERROR (14)
+#define RETURN_ACCESS_DENIED ENCODE_ERROR (15)
+#define RETURN_NO_RESPONSE ENCODE_ERROR (16)
+#define RETURN_NO_MAPPING ENCODE_ERROR (17)
+#define RETURN_TIMEOUT ENCODE_ERROR (18)
+#define RETURN_NOT_STARTED ENCODE_ERROR (19)
+#define RETURN_ALREADY_STARTED ENCODE_ERROR (20)
+#define RETURN_ABORTED ENCODE_ERROR (21)
+#define RETURN_ICMP_ERROR ENCODE_ERROR (22)
+#define RETURN_TFTP_ERROR ENCODE_ERROR (23)
+#define RETURN_PROTOCOL_ERROR ENCODE_ERROR (24)
+#define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR (25)
+#define RETURN_SECURITY_VIOLATION ENCODE_ERROR (26)
+#define RETURN_CRC_ERROR ENCODE_ERROR (27)
+#define RETURN_END_OF_MEDIA ENCODE_ERROR (28)
+#define RETURN_END_OF_FILE ENCODE_ERROR (31)
+
+#define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING (1)
+#define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING (2)
+#define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING (3)
+#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4)
+
+typedef UINT64 PHYSICAL_ADDRESS;
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+#define BIT32 0x0000000100000000ULL
+#define BIT33 0x0000000200000000ULL
+#define BIT34 0x0000000400000000ULL
+#define BIT35 0x0000000800000000ULL
+#define BIT36 0x0000001000000000ULL
+#define BIT37 0x0000002000000000ULL
+#define BIT38 0x0000004000000000ULL
+#define BIT39 0x0000008000000000ULL
+#define BIT40 0x0000010000000000ULL
+#define BIT41 0x0000020000000000ULL
+#define BIT42 0x0000040000000000ULL
+#define BIT43 0x0000080000000000ULL
+#define BIT44 0x0000100000000000ULL
+#define BIT45 0x0000200000000000ULL
+#define BIT46 0x0000400000000000ULL
+#define BIT47 0x0000800000000000ULL
+#define BIT48 0x0001000000000000ULL
+#define BIT49 0x0002000000000000ULL
+#define BIT50 0x0004000000000000ULL
+#define BIT51 0x0008000000000000ULL
+#define BIT52 0x0010000000000000ULL
+#define BIT53 0x0020000000000000ULL
+#define BIT54 0x0040000000000000ULL
+#define BIT55 0x0080000000000000ULL
+#define BIT56 0x0100000000000000ULL
+#define BIT57 0x0200000000000000ULL
+#define BIT58 0x0400000000000000ULL
+#define BIT59 0x0800000000000000ULL
+#define BIT60 0x1000000000000000ULL
+#define BIT61 0x2000000000000000ULL
+#define BIT62 0x4000000000000000ULL
+#define BIT63 0x8000000000000000ULL
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BuildVersion.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BuildVersion.h
new file mode 100644
index 00000000..de1cbde8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/BuildVersion.h
@@ -0,0 +1,9 @@
+/** @file
+This file is for build version number auto generation
+
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#define __BUILD_VERSION "Developer Build based on Revision: Unknown"
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/MdeModuleHii.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/MdeModuleHii.h
new file mode 100644
index 00000000..b52a6358
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/MdeModuleHii.h
@@ -0,0 +1,233 @@
+/** @file
+ EDK II specific HII relative definition.
+
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MDEMODULE_HII_H
+#define _MDEMODULE_HII_H
+
+#define NARROW_CHAR 0xFFF0
+#define WIDE_CHAR 0xFFF1
+#define NON_BREAKING_CHAR 0xFFF2
+
+///
+/// State defined for password statemachine .
+///
+#define BROWSER_STATE_VALIDATE_PASSWORD 0
+#define BROWSER_STATE_SET_PASSWORD 1
+
+///
+/// GUIDed opcodes defined for EDKII implementation.
+///
+#define EFI_IFR_TIANO_GUID \
+ { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce} }
+
+#pragma pack(1)
+
+///
+/// EDKII implementation extension opcodes, new extension can be added here later.
+///
+#define EFI_IFR_EXTEND_OP_LABEL 0x0
+#define EFI_IFR_EXTEND_OP_BANNER 0x1
+#define EFI_IFR_EXTEND_OP_TIMEOUT 0x2
+#define EFI_IFR_EXTEND_OP_CLASS 0x3
+#define EFI_IFR_EXTEND_OP_SUBCLASS 0x4
+
+///
+/// Label opcode.
+///
+typedef struct _EFI_IFR_GUID_LABEL {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_LABEL.
+ ///
+ UINT8 ExtendOpCode;
+ ///
+ /// Label Number.
+ ///
+ UINT16 Number;
+} EFI_IFR_GUID_LABEL;
+
+#define EFI_IFR_BANNER_ALIGN_LEFT 0
+#define EFI_IFR_BANNER_ALIGN_CENTER 1
+#define EFI_IFR_BANNER_ALIGN_RIGHT 2
+
+///
+/// Banner opcode.
+///
+typedef struct _EFI_IFR_GUID_BANNER {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_BANNER
+ ///
+ UINT8 ExtendOpCode;
+ EFI_STRING_ID Title; ///< The string token for the banner title.
+ UINT16 LineNumber; ///< 1-based line number.
+ UINT8 Alignment; ///< left, center, or right-aligned.
+} EFI_IFR_GUID_BANNER;
+
+///
+/// Timeout opcode.
+///
+typedef struct _EFI_IFR_GUID_TIMEOUT {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_TIMEOUT.
+ ///
+ UINT8 ExtendOpCode;
+ UINT16 TimeOut; ///< TimeOut Value.
+} EFI_IFR_GUID_TIMEOUT;
+
+#define EFI_NON_DEVICE_CLASS 0x00
+#define EFI_DISK_DEVICE_CLASS 0x01
+#define EFI_VIDEO_DEVICE_CLASS 0x02
+#define EFI_NETWORK_DEVICE_CLASS 0x04
+#define EFI_INPUT_DEVICE_CLASS 0x08
+#define EFI_ON_BOARD_DEVICE_CLASS 0x10
+#define EFI_OTHER_DEVICE_CLASS 0x20
+
+///
+/// Device Class opcode.
+///
+typedef struct _EFI_IFR_GUID_CLASS {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_CLASS.
+ ///
+ UINT8 ExtendOpCode;
+ UINT16 Class; ///< Device Class from the above.
+} EFI_IFR_GUID_CLASS;
+
+#define EFI_SETUP_APPLICATION_SUBCLASS 0x00
+#define EFI_GENERAL_APPLICATION_SUBCLASS 0x01
+#define EFI_FRONT_PAGE_SUBCLASS 0x02
+#define EFI_SINGLE_USE_SUBCLASS 0x03
+
+///
+/// SubClass opcode
+///
+typedef struct _EFI_IFR_GUID_SUBCLASS {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_SUBCLASS.
+ ///
+ UINT8 ExtendOpCode;
+ UINT16 SubClass; ///< Sub Class type from the above.
+} EFI_IFR_GUID_SUBCLASS;
+
+///
+/// GUIDed opcodes support for framework vfr.
+///
+#define EFI_IFR_FRAMEWORK_GUID \
+ { 0x31ca5d1a, 0xd511, 0x4931, { 0xb7, 0x82, 0xae, 0x6b, 0x2b, 0x17, 0x8c, 0xd7 } }
+
+///
+/// Two extended opcodes are added, and new extensions can be added here later.
+/// One is for framework OneOf question Option Key value;
+/// another is for framework vareqval.
+///
+#define EFI_IFR_EXTEND_OP_OPTIONKEY 0x0
+#define EFI_IFR_EXTEND_OP_VAREQNAME 0x1
+
+///
+/// Store the framework vfr option key value.
+///
+typedef struct _EFI_IFR_GUID_OPTIONKEY {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_FRAMEWORK_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_OPTIONKEY.
+ ///
+ UINT8 ExtendOpCode;
+ ///
+ /// OneOf Questiond ID binded by OneOf Option.
+ ///
+ EFI_QUESTION_ID QuestionId;
+ ///
+ /// The OneOf Option Value.
+ ///
+ EFI_IFR_TYPE_VALUE OptionValue;
+ ///
+ /// The Framework OneOf Option Key Value.
+ ///
+ UINT16 KeyValue;
+} EFI_IFR_GUID_OPTIONKEY;
+
+///
+/// Store the framework vfr vareqval name number.
+///
+typedef struct _EFI_IFR_GUID_VAREQNAME {
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_FRAMEWORK_GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_VAREQNAME.
+ ///
+ UINT8 ExtendOpCode;
+ ///
+ /// Question ID of the Numeric Opcode created.
+ ///
+ EFI_QUESTION_ID QuestionId;
+ ///
+ /// For vareqval (0x100), NameId is 0x100.
+ /// This value will convert to a Unicode String following this rule;
+ /// sprintf(StringBuffer, "%d", NameId) .
+ /// The Unicode String will be used as a EFI Variable Name.
+ ///
+ UINT16 NameId;
+} EFI_IFR_GUID_VAREQNAME;
+
+///
+/// EDKII implementation extension GUID, used to indicate there are bit fields in the varstore.
+///
+#define EDKII_IFR_BIT_VARSTORE_GUID \
+ { 0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60 ,0xA7, 0x1D}}
+
+///
+/// EDKII implementation extension flags, used to indicate the display style and bit width for bit filed storage.
+/// Two high bits for display style and the low six bits for bit width.
+///
+#define EDKII_IFR_DISPLAY_BIT 0xC0
+#define EDKII_IFR_DISPLAY_INT_DEC_BIT 0x00
+#define EDKII_IFR_DISPLAY_UINT_DEC_BIT 0x40
+#define EDKII_IFR_DISPLAY_UINT_HEX_BIT 0x80
+
+#define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F
+
+#pragma pack()
+
+extern EFI_GUID gEfiIfrTianoGuid;
+extern EFI_GUID gEfiIfrFrameworkGuid;
+extern EFI_GUID gEdkiiIfrBitVarStoreGuid;
+
+#endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareFile.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareFile.h
new file mode 100644
index 00000000..3919aa0b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareFile.h
@@ -0,0 +1,350 @@
+/** @file
+ The firmware file related definitions in PI.
+
+ @par Revision Reference:
+ Version 1.4.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PI_FIRMWARE_FILE_H__
+#define __PI_FIRMWARE_FILE_H__
+
+#pragma pack(1)
+//
+// Used to verify the integrity of the file.
+//
+typedef union {
+ struct {
+ UINT8 Header;
+ UINT8 File;
+ } Checksum;
+ UINT16 Checksum16;
+} EFI_FFS_INTEGRITY_CHECK;
+
+typedef UINT8 EFI_FV_FILETYPE;
+typedef UINT8 EFI_FFS_FILE_ATTRIBUTES;
+typedef UINT8 EFI_FFS_FILE_STATE;
+
+//
+// File Types Definitions
+//
+#define EFI_FV_FILETYPE_ALL 0x00
+#define EFI_FV_FILETYPE_RAW 0x01
+#define EFI_FV_FILETYPE_FREEFORM 0x02
+#define EFI_FV_FILETYPE_SECURITY_CORE 0x03
+#define EFI_FV_FILETYPE_PEI_CORE 0x04
+#define EFI_FV_FILETYPE_DXE_CORE 0x05
+#define EFI_FV_FILETYPE_PEIM 0x06
+#define EFI_FV_FILETYPE_DRIVER 0x07
+#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08
+#define EFI_FV_FILETYPE_APPLICATION 0x09
+#define EFI_FV_FILETYPE_SMM 0x0A
+#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B
+#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C
+#define EFI_FV_FILETYPE_SMM_CORE 0x0D
+#define EFI_FV_FILETYPE_MM_STANDALONE 0x0E
+#define EFI_FV_FILETYPE_MM_CORE_STANDALONE 0x0F
+#define EFI_FV_FILETYPE_OEM_MIN 0xc0
+#define EFI_FV_FILETYPE_OEM_MAX 0xdf
+#define EFI_FV_FILETYPE_DEBUG_MIN 0xe0
+#define EFI_FV_FILETYPE_DEBUG_MAX 0xef
+#define EFI_FV_FILETYPE_FFS_MIN 0xf0
+#define EFI_FV_FILETYPE_FFS_MAX 0xff
+#define EFI_FV_FILETYPE_FFS_PAD 0xf0
+//
+// FFS File Attributes.
+//
+#define FFS_ATTRIB_LARGE_FILE 0x01
+#define FFS_ATTRIB_DATA_ALIGNMENT2 0x02
+#define FFS_ATTRIB_FIXED 0x04
+#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
+#define FFS_ATTRIB_CHECKSUM 0x40
+//
+// FFS_FIXED_CHECKSUM is the checksum value used when the
+// FFS_ATTRIB_CHECKSUM attribute bit is clear
+//
+#define FFS_FIXED_CHECKSUM 0xAA
+
+//
+// FFS File State Bits.
+//
+#define EFI_FILE_HEADER_CONSTRUCTION 0x01
+#define EFI_FILE_HEADER_VALID 0x02
+#define EFI_FILE_DATA_VALID 0x04
+#define EFI_FILE_MARKED_FOR_UPDATE 0x08
+#define EFI_FILE_DELETED 0x10
+#define EFI_FILE_HEADER_INVALID 0x20
+
+#define EFI_FILE_ALL_STATE_BITS (EFI_FILE_HEADER_CONSTRUCTION | \
+ EFI_FILE_HEADER_VALID | \
+ EFI_FILE_DATA_VALID | \
+ EFI_FILE_MARKED_FOR_UPDATE | \
+ EFI_FILE_DELETED | \
+ EFI_FILE_HEADER_INVALID \
+ )
+
+//
+// Each file begins with the header that describe the
+// contents and state of the files.
+//
+typedef struct {
+ EFI_GUID Name;
+ EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
+ EFI_FV_FILETYPE Type;
+ EFI_FFS_FILE_ATTRIBUTES Attributes;
+ UINT8 Size[3];
+ EFI_FFS_FILE_STATE State;
+} EFI_FFS_FILE_HEADER;
+
+typedef struct {
+ EFI_GUID Name;
+ EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
+ EFI_FV_FILETYPE Type;
+ EFI_FFS_FILE_ATTRIBUTES Attributes;
+ UINT8 Size[3];
+ EFI_FFS_FILE_STATE State;
+ UINT64 ExtendedSize;
+} EFI_FFS_FILE_HEADER2;
+
+#define MAX_FFS_SIZE 0x1000000
+
+typedef UINT8 EFI_SECTION_TYPE;
+
+//
+// Pseudo type. It is
+// used as a wild card when retrieving sections. The section
+// type EFI_SECTION_ALL matches all section types.
+//
+#define EFI_SECTION_ALL 0x00
+
+//
+// Encapsulation section Type values
+//
+#define EFI_SECTION_COMPRESSION 0x01
+
+#define EFI_SECTION_GUID_DEFINED 0x02
+
+//
+// Leaf section Type values
+//
+#define EFI_SECTION_PE32 0x10
+#define EFI_SECTION_PIC 0x11
+#define EFI_SECTION_TE 0x12
+#define EFI_SECTION_DXE_DEPEX 0x13
+#define EFI_SECTION_VERSION 0x14
+#define EFI_SECTION_USER_INTERFACE 0x15
+#define EFI_SECTION_COMPATIBILITY16 0x16
+#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17
+#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18
+#define EFI_SECTION_RAW 0x19
+#define EFI_SECTION_PEI_DEPEX 0x1B
+#define EFI_SECTION_SMM_DEPEX 0x1C
+
+typedef struct {
+ UINT8 Size[3];
+ EFI_SECTION_TYPE Type;
+} EFI_COMMON_SECTION_HEADER;
+
+typedef struct {
+ UINT8 Size[3];
+ EFI_SECTION_TYPE Type;
+ UINT32 ExtendedSize;
+} EFI_COMMON_SECTION_HEADER2;
+
+#define MAX_SECTION_SIZE 0x1000000
+
+//
+// Leaf section type that contains an
+// IA-32 16-bit executable image.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
+
+//
+// CompressionType of EFI_COMPRESSION_SECTION.
+//
+#define EFI_NOT_COMPRESSED 0x00
+#define EFI_STANDARD_COMPRESSION 0x01
+//
+// An encapsulation section type in which the
+// section data is compressed.
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+ UINT32 UncompressedLength;
+ UINT8 CompressionType;
+} EFI_COMPRESSION_SECTION;
+
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ UINT32 UncompressedLength;
+ UINT8 CompressionType;
+} EFI_COMPRESSION_SECTION2;
+
+//
+// Leaf section which could be used to determine the dispatch order of DXEs.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
+
+//
+// Leaf section witch contains a PI FV.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
+
+//
+// Leaf section which contains a single GUID.
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+ EFI_GUID SubTypeGuid;
+} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
+
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ EFI_GUID SubTypeGuid;
+} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
+
+//
+// Attributes of EFI_GUID_DEFINED_SECTION
+//
+#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
+#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02
+//
+// Leaf section which is encapsulation defined by specific GUID
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+ EFI_GUID SectionDefinitionGuid;
+ UINT16 DataOffset;
+ UINT16 Attributes;
+} EFI_GUID_DEFINED_SECTION;
+
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ EFI_GUID SectionDefinitionGuid;
+ UINT16 DataOffset;
+ UINT16 Attributes;
+} EFI_GUID_DEFINED_SECTION2;
+
+//
+// Leaf section which contains PE32+ image.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
+
+//
+// Leaf section which contains PIC image.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
+
+//
+// Leaf section which used to determine the dispatch order of PEIMs.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
+
+//
+// Leaf section which constains the position-independent-code image.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
+
+//
+// Leaf section which contains an array of zero or more bytes.
+//
+typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
+
+//
+// Leaf section which contains a unicode string that
+// is human readable file name.
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+
+ //
+ // Array of unicode string.
+ //
+ CHAR16 FileNameString[1];
+} EFI_USER_INTERFACE_SECTION;
+
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+
+ //
+ // Array of unicode string.
+ //
+ CHAR16 FileNameString[1];
+} EFI_USER_INTERFACE_SECTION2;
+
+//
+// Leaf section which contains a numeric build number and
+// an optional unicode string that represent the file revision.
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+ UINT16 BuildNumber;
+ CHAR16 VersionString[1];
+} EFI_VERSION_SECTION;
+
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ UINT16 BuildNumber;
+ CHAR16 VersionString[1];
+} EFI_VERSION_SECTION2;
+
+//
+// The argument passed as the SectionHeaderPtr parameter to the SECTION_SIZE()
+// function-like macro below must not have side effects: SectionHeaderPtr is
+// evaluated multiple times.
+//
+#define SECTION_SIZE(SectionHeaderPtr) ((UINT32) ( \
+ (((EFI_COMMON_SECTION_HEADER *) (SectionHeaderPtr))->Size[0] ) | \
+ (((EFI_COMMON_SECTION_HEADER *) (SectionHeaderPtr))->Size[1] << 8) | \
+ (((EFI_COMMON_SECTION_HEADER *) (SectionHeaderPtr))->Size[2] << 16)))
+
+#pragma pack()
+
+typedef union {
+ EFI_COMMON_SECTION_HEADER *CommonHeader;
+ EFI_COMPRESSION_SECTION *CompressionSection;
+ EFI_GUID_DEFINED_SECTION *GuidDefinedSection;
+ EFI_PE32_SECTION *Pe32Section;
+ EFI_PIC_SECTION *PicSection;
+ EFI_TE_SECTION *TeSection;
+ EFI_PEI_DEPEX_SECTION *PeimHeaderSection;
+ EFI_DXE_DEPEX_SECTION *DependencySection;
+ EFI_VERSION_SECTION *VersionSection;
+ EFI_USER_INTERFACE_SECTION *UISection;
+ EFI_COMPATIBILITY16_SECTION *Code16Section;
+ EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FVImageSection;
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION *FreeformSubtypeSection;
+ EFI_RAW_SECTION *RawSection;
+ //
+ // For section whose size is equal or greater than 0x1000000
+ //
+ EFI_COMMON_SECTION_HEADER2 *CommonHeader2;
+ EFI_COMPRESSION_SECTION2 *CompressionSection2;
+ EFI_GUID_DEFINED_SECTION2 *GuidDefinedSection2;
+ EFI_PE32_SECTION2 *Pe32Section2;
+ EFI_PIC_SECTION2 *PicSection2;
+ EFI_TE_SECTION2 *TeSection2;
+ EFI_PEI_DEPEX_SECTION2 *PeimHeaderSection2;
+ EFI_DXE_DEPEX_SECTION2 *DependencySection2;
+ EFI_VERSION_SECTION2 *VersionSection2;
+ EFI_USER_INTERFACE_SECTION2 *UISection2;
+ EFI_COMPATIBILITY16_SECTION2 *Code16Section2;
+ EFI_FIRMWARE_VOLUME_IMAGE_SECTION2 *FVImageSection2;
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *FreeformSubtypeSection2;
+ EFI_RAW_SECTION2 *RawSection2;
+} EFI_FILE_SECTION_POINTER;
+
+#endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h
new file mode 100644
index 00000000..dec5a321
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h
@@ -0,0 +1,157 @@
+/** @file
+ The firmware volume related definitions in PI.
+
+ @par Revision Reference:
+ Version 1.2C
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PI_FIRMWAREVOLUME_H__
+#define __PI_FIRMWAREVOLUME_H__
+
+//
+// EFI_FV_FILE_ATTRIBUTES
+//
+typedef UINT32 EFI_FV_FILE_ATTRIBUTES;
+
+//
+// Value of EFI_FV_FILE_ATTRIBUTES.
+//
+#define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F
+#define EFI_FV_FILE_ATTRIB_FIXED 0x00000100
+#define EFI_FV_FILE_ATTRIB_MEMORY_MAPPED 0x00000200
+
+typedef UINT32 EFI_FVB_ATTRIBUTES_2;
+
+//
+// Attributes bit definitions
+//
+#define EFI_FVB2_READ_DISABLED_CAP 0x00000001
+#define EFI_FVB2_READ_ENABLED_CAP 0x00000002
+#define EFI_FVB2_READ_STATUS 0x00000004
+#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008
+#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010
+#define EFI_FVB2_WRITE_STATUS 0x00000020
+#define EFI_FVB2_LOCK_CAP 0x00000040
+#define EFI_FVB2_LOCK_STATUS 0x00000080
+#define EFI_FVB2_STICKY_WRITE 0x00000200
+#define EFI_FVB2_MEMORY_MAPPED 0x00000400
+#define EFI_FVB2_ERASE_POLARITY 0x00000800
+#define EFI_FVB2_READ_LOCK_CAP 0x00001000
+#define EFI_FVB2_READ_LOCK_STATUS 0x00002000
+#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000
+#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000
+#define EFI_FVB2_ALIGNMENT 0x001F0000
+#define EFI_FVB2_WEAK_ALIGNMENT 0x80000000
+#define EFI_FVB2_ALIGNMENT_1 0x00000000
+#define EFI_FVB2_ALIGNMENT_2 0x00010000
+#define EFI_FVB2_ALIGNMENT_4 0x00020000
+#define EFI_FVB2_ALIGNMENT_8 0x00030000
+#define EFI_FVB2_ALIGNMENT_16 0x00040000
+#define EFI_FVB2_ALIGNMENT_32 0x00050000
+#define EFI_FVB2_ALIGNMENT_64 0x00060000
+#define EFI_FVB2_ALIGNMENT_128 0x00070000
+#define EFI_FVB2_ALIGNMENT_256 0x00080000
+#define EFI_FVB2_ALIGNMENT_512 0x00090000
+#define EFI_FVB2_ALIGNMENT_1K 0x000A0000
+#define EFI_FVB2_ALIGNMENT_2K 0x000B0000
+#define EFI_FVB2_ALIGNMENT_4K 0x000C0000
+#define EFI_FVB2_ALIGNMENT_8K 0x000D0000
+#define EFI_FVB2_ALIGNMENT_16K 0x000E0000
+#define EFI_FVB2_ALIGNMENT_32K 0x000F0000
+#define EFI_FVB2_ALIGNMENT_64K 0x00100000
+#define EFI_FVB2_ALIGNMENT_128K 0x00110000
+#define EFI_FVB2_ALIGNMENT_256K 0x00120000
+#define EFI_FVB2_ALIGNMENT_512K 0x00130000
+#define EFI_FVB2_ALIGNMENT_1M 0x00140000
+#define EFI_FVB2_ALIGNMENT_2M 0x00150000
+#define EFI_FVB2_ALIGNMENT_4M 0x00160000
+#define EFI_FVB2_ALIGNMENT_8M 0x00170000
+#define EFI_FVB2_ALIGNMENT_16M 0x00180000
+#define EFI_FVB2_ALIGNMENT_32M 0x00190000
+#define EFI_FVB2_ALIGNMENT_64M 0x001A0000
+#define EFI_FVB2_ALIGNMENT_128M 0x001B0000
+#define EFI_FVB2_ALIGNMENT_256M 0x001C0000
+#define EFI_FVB2_ALIGNMENT_512M 0x001D0000
+#define EFI_FVB2_ALIGNMENT_1G 0x001E0000
+#define EFI_FVB2_ALIGNMENT_2G 0x001F0000
+
+
+typedef struct {
+ UINT32 NumBlocks;
+ UINT32 Length;
+} EFI_FV_BLOCK_MAP_ENTRY;
+
+//
+// Describes the features and layout of the firmware volume.
+//
+typedef struct {
+ UINT8 ZeroVector[16];
+ EFI_GUID FileSystemGuid;
+ UINT64 FvLength;
+ UINT32 Signature;
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINT16 HeaderLength;
+ UINT16 Checksum;
+ UINT16 ExtHeaderOffset;
+ UINT8 Reserved[1];
+ UINT8 Revision;
+ EFI_FV_BLOCK_MAP_ENTRY BlockMap[1];
+} EFI_FIRMWARE_VOLUME_HEADER;
+
+#define EFI_FVH_SIGNATURE SIGNATURE_32 ('_', 'F', 'V', 'H')
+
+///
+/// Firmware Volume Header Revision definition
+///
+#define EFI_FVH_REVISION 0x02
+
+//
+// Extension header pointed by ExtHeaderOffset of volume header.
+//
+typedef struct {
+ EFI_GUID FvName;
+ UINT32 ExtHeaderSize;
+} EFI_FIRMWARE_VOLUME_EXT_HEADER;
+
+typedef struct {
+ UINT16 ExtEntrySize;
+ UINT16 ExtEntryType;
+} EFI_FIRMWARE_VOLUME_EXT_ENTRY;
+
+#define EFI_FV_EXT_TYPE_OEM_TYPE 0x01
+typedef struct {
+ EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr;
+ UINT32 TypeMask;
+
+ //
+ // Array of GUIDs.
+ // Each GUID represents an OEM file type.
+ //
+ // EFI_GUID Types[1];
+ //
+} EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE;
+
+#define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002
+typedef struct {
+ EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr;
+ EFI_GUID FormatType;
+
+ //
+ // An array of bytes of length Length.
+ //
+ // UINT8 Data[1];
+ //
+} EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE;
+
+#define EFI_FV_EXT_TYPE_USED_SIZE_TYPE 0x03
+typedef struct {
+ EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr;
+ UINT32 UsedSize;
+} EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiBaseTypes.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiBaseTypes.h
new file mode 100644
index 00000000..8f0cdf60
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiBaseTypes.h
@@ -0,0 +1,168 @@
+/** @file
+ Defines data types and constants introduced in UEFI.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __UEFI_BASETYPE_H__
+#define __UEFI_BASETYPE_H__
+
+#include <Common/BaseTypes.h>
+
+//
+// Basical data type definitions introduced in UEFI.
+//
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} EFI_GUID;
+
+typedef RETURN_STATUS EFI_STATUS;
+typedef VOID *EFI_HANDLE;
+
+typedef VOID *EFI_EVENT;
+
+typedef UINTN EFI_TPL;
+
+
+typedef UINT64 EFI_LBA;
+
+
+typedef UINT16 STRING_REF;
+
+typedef UINT64 EFI_PHYSICAL_ADDRESS;
+typedef UINT64 EFI_VIRTUAL_ADDRESS;
+
+//
+// EFI Time Abstraction:
+// Year: 2000 - 20XX
+// Month: 1 - 12
+// Day: 1 - 31
+// Hour: 0 - 23
+// Minute: 0 - 59
+// Second: 0 - 59
+// Nanosecond: 0 - 999,999,999
+// TimeZone: -1440 to 1440 or 2047
+//
+typedef struct {
+ UINT16 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+ UINT8 Pad1;
+ UINT32 Nanosecond;
+ INT16 TimeZone;
+ UINT8 Daylight;
+ UINT8 Pad2;
+} EFI_TIME;
+
+
+//
+// Networking Definitions
+//
+typedef struct {
+ UINT8 Addr[4];
+} EFI_IPv4_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[16];
+} EFI_IPv6_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+typedef union {
+ UINT32 Addr[4];
+ EFI_IPv4_ADDRESS v4;
+ EFI_IPv6_ADDRESS v6;
+} EFI_IP_ADDRESS;
+
+
+//
+// Enumeration of EFI_STATUS.
+//
+#define EFI_SUCCESS RETURN_SUCCESS
+#define EFI_LOAD_ERROR RETURN_LOAD_ERROR
+#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER
+#define EFI_UNSUPPORTED RETURN_UNSUPPORTED
+#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE
+#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL
+#define EFI_NOT_READY RETURN_NOT_READY
+#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR
+#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED
+#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES
+#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED
+#define EFI_VOLUME_FULL RETURN_VOLUME_FULL
+#define EFI_NO_MEDIA RETURN_NO_MEDIA
+#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED
+#define EFI_NOT_FOUND RETURN_NOT_FOUND
+#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED
+#define EFI_NO_RESPONSE RETURN_NO_RESPONSE
+#define EFI_NO_MAPPING RETURN_NO_MAPPING
+#define EFI_TIMEOUT RETURN_TIMEOUT
+#define EFI_NOT_STARTED RETURN_NOT_STARTED
+#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED
+#define EFI_ABORTED RETURN_ABORTED
+#define EFI_ICMP_ERROR RETURN_ICMP_ERROR
+#define EFI_TFTP_ERROR RETURN_TFTP_ERROR
+#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR
+#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION
+#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION
+#define EFI_CRC_ERROR RETURN_CRC_ERROR
+#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA
+#define EFI_END_OF_FILE RETURN_END_OF_FILE
+
+#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH
+#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE
+#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE
+#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
+
+
+#define NULL_HANDLE ((VOID *) 0)
+
+//
+// Define macro to encode the status code.
+//
+#define EFIERR(_a) ENCODE_ERROR(_a)
+
+#define EFI_ERROR(A) RETURN_ERROR(A)
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
+#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+
+
+//
+// Returns the byte offset to a field within a structure
+//
+#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))
+
+//
+// The EFI memory allocation functions work in units of EFI_PAGEs that are
+// 4K. This should in no way be confused with the page size of the processor.
+// An EFI_PAGE is just the quanta of memory in EFI.
+//
+#define EFI_PAGE_SIZE 0x1000
+#define EFI_PAGE_MASK 0xFFF
+#define EFI_PAGE_SHIFT 12
+
+#define EFI_SIZE_TO_PAGES(a) (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0))
+
+#define EFI_PAGES_TO_SIZE(a) ( (a) << EFI_PAGE_SHIFT)
+
+
+#define EFI_MAX_BIT MAX_BIT
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiCapsule.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiCapsule.h
new file mode 100644
index 00000000..1ab539b3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiCapsule.h
@@ -0,0 +1,26 @@
+/** @file
+ Defines for the EFI Capsule functionality.
+ @par Revision Reference:
+ These definitions are from Uefi Spec.
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_CAPSULE_H_
+#define _EFI_CAPSULE_H_
+
+typedef struct {
+ EFI_GUID CapsuleGuid;
+ UINT32 HeaderSize;
+ UINT32 Flags;
+ UINT32 CapsuleImageSize;
+} EFI_CAPSULE_HEADER;
+
+#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
+#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
+#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000
+
+#endif // #ifndef _EFI_CAPSULE_H_
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h
new file mode 100644
index 00000000..22c99a1b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h
@@ -0,0 +1,1680 @@
+/** @file
+ This file defines the encoding for the VFR (Visual Form Representation) language.
+ IFR is primarily consumed by the EFI presentation engine, and produced by EFI
+ internal application and drivers as well as all add-in card option-ROM drivers
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ These definitions are from UEFI 2.6
+
+**/
+
+#ifndef __UEFI_INTERNAL_FORMREPRESENTATION_H__
+#define __UEFI_INTERNAL_FORMREPRESENTATION_H__
+
+
+#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \
+ { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } }
+
+//
+// The following types are currently defined:
+//
+typedef UINT32 RELOFST;
+
+typedef VOID* EFI_HII_HANDLE;
+typedef CHAR16* EFI_STRING;
+typedef UINT16 EFI_IMAGE_ID;
+typedef UINT16 EFI_QUESTION_ID;
+typedef UINT16 EFI_STRING_ID;
+typedef UINT16 EFI_FORM_ID;
+typedef UINT16 EFI_VARSTORE_ID;
+typedef UINT16 EFI_DEFAULT_ID;
+typedef UINT32 EFI_HII_FONT_STYLE;
+
+
+
+#pragma pack(1)
+
+
+//
+// HII package list
+//
+typedef struct {
+ EFI_GUID PackageListGuid;
+ UINT32 PackageLength;
+} EFI_HII_PACKAGE_LIST_HEADER;
+
+/**
+
+ Each package starts with a header, as defined above, which
+ indicates the size and type of the package. When added to a
+ pointer pointing to the start of the header, Length points at
+ the next package. The package lists form a package list when
+ concatenated together and terminated with an
+ EFI_HII_PACKAGE_HEADER with a Type of EFI_HII_PACKAGE_END. The
+ type EFI_HII_PACKAGE_TYPE_GUID is used for vendor-defined HII
+ packages, whose contents are determined by the Guid. The range
+ of package types starting with EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN
+ through EFI_HII_PACKAGE_TYPE_SYSTEM_END are reserved for system
+ firmware implementers.
+
+ @param Length The size of the package in bytes.
+
+ @param Type The package type. See EFI_HII_PACKAGE_TYPE_x,
+ below.
+
+ @param Data The package data, the format of which is
+ determined by Type.
+
+**/
+typedef struct {
+ UINT32 Length:24;
+ UINT32 Type:8;
+ // UINT8 Data[...];
+} EFI_HII_PACKAGE_HEADER;
+
+//
+// EFI_HII_PACKAGE_TYPE_x.
+//
+#define EFI_HII_PACKAGE_TYPE_ALL 0x00
+#define EFI_HII_PACKAGE_TYPE_GUID 0x01
+#define EFI_HII_PACKAGE_FORM 0x02
+#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x03
+#define EFI_HII_PACKAGE_STRINGS 0x04
+#define EFI_HII_PACKAGE_FONTS 0x05
+#define EFI_HII_PACKAGE_IMAGES 0x06
+#define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07
+#define EFI_HII_PACKAGE_DEVICE_PATH 0x08
+#define EFI_HII_PACKAGE_END 0xDF
+#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0
+#define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF
+
+//
+// Simplified Font Package
+//
+
+#define EFI_GLYPH_HEIGHT 19
+#define EFI_GLYPH_WIDTH 8
+//
+// Contents of EFI_NARROW_GLYPH.Attributes
+//
+#define EFI_GLYPH_NON_SPACING 0x01
+#define EFI_GLYPH_WIDE 0x02
+
+typedef struct {
+ CHAR16 UnicodeWeight;
+ UINT8 Attributes;
+ UINT8 GlyphCol1[EFI_GLYPH_HEIGHT];
+} EFI_NARROW_GLYPH;
+
+typedef struct {
+ CHAR16 UnicodeWeight;
+ UINT8 Attributes;
+ UINT8 GlyphCol1[EFI_GLYPH_HEIGHT];
+ UINT8 GlyphCol2[EFI_GLYPH_HEIGHT];
+ UINT8 Pad[3];
+} EFI_WIDE_GLYPH;
+
+
+typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT16 NumberOfNarrowGlyphs;
+ UINT16 NumberOfWideGlyphs;
+ // EFI_NARROW_GLYPH NarrowGlyphs[];
+ // EFI_WIDE_GLYPH WideGlyphs[];
+} EFI_HII_SIMPLE_FONT_PACKAGE_HDR;
+
+//
+// Font Package
+//
+
+#define EFI_HII_FONT_STYLE_BOLD 0x00000001
+#define EFI_HII_FONT_STYLE_ITALIC 0x00000002
+#define EFI_HII_FONT_STYLE_EMBOSS 0x00010000
+#define EFI_HII_FONT_STYLE_OUTLINE 0x00020000
+#define EFI_HII_FONT_STYLE_SHADOW 0x00040000
+#define EFI_HII_FONT_STYLE_UNDERLINE 0x00080000
+#define EFI_HII_FONT_STYLE_DBL_UNDER 0x00100000
+
+typedef struct _EFI_HII_GLYPH_INFO {
+ UINT16 Width;
+ UINT16 Height;
+ INT16 OffsetX;
+ INT16 OffsetY;
+ INT16 AdvanceX;
+} EFI_HII_GLYPH_INFO;
+
+typedef struct _EFI_HII_FONT_PACKAGE_HDR {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT32 HdrSize;
+ UINT32 GlyphBlockOffset;
+ EFI_HII_GLYPH_INFO Cell;
+ EFI_HII_FONT_STYLE FontStyle;
+ CHAR16 FontFamily[1];
+} EFI_HII_FONT_PACKAGE_HDR;
+
+#define EFI_HII_GIBT_END 0x00
+#define EFI_HII_GIBT_GLYPH 0x10
+#define EFI_HII_GIBT_GLYPHS 0x11
+#define EFI_HII_GIBT_GLYPH_DEFAULT 0x12
+#define EFI_HII_GIBT_GLYPHS_DEFAULT 0x13
+#define EFI_HII_GIBT_GLYPH_VARIABILITY 0x14
+#define EFI_HII_GIBT_DUPLICATE 0x20
+#define EFI_HII_GIBT_SKIP2 0x21
+#define EFI_HII_GIBT_SKIP1 0x22
+#define EFI_HII_GIBT_DEFAULTS 0x23
+#define EFI_HII_GIBT_EXT1 0x30
+#define EFI_HII_GIBT_EXT2 0x31
+#define EFI_HII_GIBT_EXT4 0x32
+
+typedef struct _EFI_HII_GLYPH_BLOCK {
+ UINT8 BlockType;
+} EFI_HII_GLYPH_BLOCK;
+
+typedef struct _EFI_HII_GIBT_DEFAULTS_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ EFI_HII_GLYPH_INFO Cell;
+} EFI_HII_GIBT_DEFAULTS_BLOCK;
+
+typedef struct _EFI_HII_GIBT_DUPLICATE_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ CHAR16 CharValue;
+} EFI_HII_GIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_GLYPH_GIBT_END_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+} EFI_GLYPH_GIBT_END_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT1_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT8 BlockType2;
+ UINT8 Length;
+} EFI_HII_GIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT2_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT8 BlockType2;
+ UINT16 Length;
+} EFI_HII_GIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT4_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT8 BlockType2;
+ UINT32 Length;
+} EFI_HII_GIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPH_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Cell.Width+7)/8)*Cell.Height
+} EFI_HII_GIBT_GLYPH_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPHS_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT16 Count;
+ UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Cell.Width+7)/8)*Cell.Height
+} EFI_HII_GIBT_GLYPHS_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Global.Cell.Width+7)/8)*Global.Cell.Height
+} EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT16 Count;
+ UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Global.Cell.Width+7)/8)*Global.Cell.Height
+} EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK;
+
+typedef struct _EFI_HII_GIBT_VARIABILITY_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 GlyphPackInBits;
+ UINT8 BitmapData [1];
+} EFI_HII_GIBT_VARIABILITY_BLOCK;
+
+typedef struct _EFI_HII_GIBT_SKIP1_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT8 SkipCount;
+} EFI_HII_GIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_GIBT_SKIP2_BLOCK {
+ EFI_HII_GLYPH_BLOCK Header;
+ UINT16 SkipCount;
+} EFI_HII_GIBT_SKIP2_BLOCK;
+
+//
+// Device Path Package
+//
+typedef struct _EFI_HII_DEVICE_PATH_PACKAGE {
+ EFI_HII_PACKAGE_HEADER Header;
+ // EFI_DEVICE_PATH_PROTOCOL DevicePath[];
+} EFI_HII_DEVICE_PATH_PACKAGE;
+
+//
+// GUID Package
+//
+typedef struct _EFI_HII_GUID_PACKAGE_HDR {
+ EFI_HII_PACKAGE_HEADER Header;
+ EFI_GUID Guid;
+ // Data per GUID definition may follow
+} EFI_HII_GUID_PACKAGE_HDR;
+
+//
+// String Package
+//
+
+#define UEFI_CONFIG_LANG "x-UEFI"
+#define UEFI_CONFIG_LANG2 "x-i-UEFI"
+
+typedef struct _EFI_HII_STRING_PACKAGE_HDR {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT32 HdrSize;
+ UINT32 StringInfoOffset;
+ CHAR16 LanguageWindow[16];
+ EFI_STRING_ID LanguageName;
+ CHAR8 Language[1];
+} EFI_HII_STRING_PACKAGE_HDR;
+
+typedef struct {
+ UINT8 BlockType;
+} EFI_HII_STRING_BLOCK;
+
+#define EFI_HII_SIBT_END 0x00
+#define EFI_HII_SIBT_STRING_SCSU 0x10
+#define EFI_HII_SIBT_STRING_SCSU_FONT 0x11
+#define EFI_HII_SIBT_STRINGS_SCSU 0x12
+#define EFI_HII_SIBT_STRINGS_SCSU_FONT 0x13
+#define EFI_HII_SIBT_STRING_UCS2 0x14
+#define EFI_HII_SIBT_STRING_UCS2_FONT 0x15
+#define EFI_HII_SIBT_STRINGS_UCS2 0x16
+#define EFI_HII_SIBT_STRINGS_UCS2_FONT 0x17
+#define EFI_HII_SIBT_DUPLICATE 0x20
+#define EFI_HII_SIBT_SKIP2 0x21
+#define EFI_HII_SIBT_SKIP1 0x22
+#define EFI_HII_SIBT_EXT1 0x30
+#define EFI_HII_SIBT_EXT2 0x31
+#define EFI_HII_SIBT_EXT4 0x32
+#define EFI_HII_SIBT_FONT 0x40
+
+typedef struct _EFI_HII_SIBT_DUPLICATE_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ EFI_STRING_ID StringId;
+} EFI_HII_SIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_HII_SIBT_END_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+} EFI_HII_SIBT_END_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT1_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 BlockType2;
+ UINT8 Length;
+} EFI_HII_SIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT2_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 BlockType2;
+ UINT16 Length;
+} EFI_HII_SIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT4_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 BlockType2;
+ UINT32 Length;
+} EFI_HII_SIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_SIBT_FONT_BLOCK {
+ EFI_HII_SIBT_EXT2_BLOCK Header;
+ UINT8 FontId;
+ UINT16 FontSize;
+ EFI_HII_FONT_STYLE FontStyle;
+ CHAR16 FontName[1];
+} EFI_HII_SIBT_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_SKIP1_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 SkipCount;
+} EFI_HII_SIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_SIBT_SKIP2_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT16 SkipCount;
+} EFI_HII_SIBT_SKIP2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_SCSU_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 StringText[1];
+} EFI_HII_SIBT_STRING_SCSU_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 FontIdentifier;
+ UINT8 StringText[1];
+} EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_SCSU_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT16 StringCount;
+ UINT8 StringText[1];
+} EFI_HII_SIBT_STRINGS_SCSU_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 FontIdentifier;
+ UINT16 StringCount;
+ UINT8 StringText[1];
+} EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_UCS2_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ CHAR16 StringText[1];
+} EFI_HII_SIBT_STRING_UCS2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 FontIdentifier;
+ CHAR16 StringText[1];
+} EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_UCS2_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT16 StringCount;
+ CHAR16 StringText[1];
+} EFI_HII_SIBT_STRINGS_UCS2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK {
+ EFI_HII_STRING_BLOCK Header;
+ UINT8 FontIdentifier;
+ UINT16 StringCount;
+ CHAR16 StringText[1];
+} EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK;
+
+//
+// Image Packages
+//
+
+typedef struct _EFI_HII_IMAGE_PACKAGE_HDR {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT32 ImageInfoOffset;
+ UINT32 PaletteInfoOffset;
+} EFI_HII_IMAGE_PACKAGE_HDR;
+
+typedef struct _EFI_HII_IMAGE_BLOCK {
+ UINT8 BlockType;
+} EFI_HII_IMAGE_BLOCK;
+
+#define EFI_HII_IIBT_END 0x00
+#define EFI_HII_IIBT_IMAGE_1BIT 0x10
+#define EFI_HII_IIBT_IMAGE_1BIT_TRANS 0x11
+#define EFI_HII_IIBT_IMAGE_4BIT 0x12
+#define EFI_HII_IIBT_IMAGE_4BIT_TRANS 0x13
+#define EFI_HII_IIBT_IMAGE_8BIT 0x14
+#define EFI_HII_IIBT_IMAGE_8BIT_TRANS 0x15
+#define EFI_HII_IIBT_IMAGE_24BIT 0x16
+#define EFI_HII_IIBT_IMAGE_24BIT_TRANS 0x17
+#define EFI_HII_IIBT_IMAGE_JPEG 0x18
+#define EFI_HII_IIBT_IMAGE_PNG 0x19
+#define EFI_HII_IIBT_DUPLICATE 0x20
+#define EFI_HII_IIBT_SKIP2 0x21
+#define EFI_HII_IIBT_SKIP1 0x22
+#define EFI_HII_IIBT_EXT1 0x30
+#define EFI_HII_IIBT_EXT2 0x31
+#define EFI_HII_IIBT_EXT4 0x32
+
+typedef struct _EFI_HII_IIBT_END_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+} EFI_HII_IIBT_END_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT1_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 BlockType2;
+ UINT8 Length;
+} EFI_HII_IIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT2_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 BlockType2;
+ UINT16 Length;
+} EFI_HII_IIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT4_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 BlockType2;
+ UINT32 Length;
+} EFI_HII_IIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BASE {
+ UINT16 Width;
+ UINT16 Height;
+ UINT8 Data[1];
+} EFI_HII_IIBT_IMAGE_1BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 PaletteIndex;
+ EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_1BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 PaletteIndex;
+ EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_RGB_PIXEL {
+ UINT8 b;
+ UINT8 g;
+ UINT8 r;
+} EFI_HII_RGB_PIXEL;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BASE {
+ UINT16 Width;
+ UINT16 Height;
+ EFI_HII_RGB_PIXEL Bitmap[1];
+} EFI_HII_IIBT_IMAGE_24BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_24BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BASE {
+ UINT16 Width;
+ UINT16 Height;
+ UINT8 Data[1];
+} EFI_HII_IIBT_IMAGE_4BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 PaletteIndex;
+ EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_4BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 PaletteIndex;
+ EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_BASE {
+ UINT16 Width;
+ UINT16 Height;
+ UINT8 Data[1];
+} EFI_HII_IIBT_IMAGE_8BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_PALETTE_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 PaletteIndex;
+ EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_8BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_TRANS_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 PaletteIndex;
+ EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_8BIT_TRAN_BLOCK;
+
+typedef struct _EFI_HII_IIBT_DUPLICATE_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ EFI_IMAGE_ID ImageId;
+} EFI_HII_IIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_HII_IIBT_JPEG_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT32 Size;
+ UINT8 Data[1];
+} EFI_HII_IIBT_JPEG_BLOCK;
+
+typedef struct _EFI_HII_IIBT_PNG_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT32 Size;
+ UINT8 Data[1];
+} EFI_HII_IIBT_PNG_BLOCK;
+
+typedef struct _EFI_HII_IIBT_SKIP1_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT8 SkipCount;
+} EFI_HII_IIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_IIBT_SKIP2_BLOCK {
+ EFI_HII_IMAGE_BLOCK Header;
+ UINT16 SkipCount;
+} EFI_HII_IIBT_SKIP2_BLOCK;
+
+typedef struct _EFI_HII_IMAGE_PALETTE_INFO_HEADER {
+ UINT16 PaletteCount;
+} EFI_HII_IMAGE_PALETTE_INFO_HEADER;
+
+typedef struct _EFI_HII_IMAGE_PALETTE_INFO {
+ UINT16 PaletteSize;
+ EFI_HII_RGB_PIXEL PaletteValue[1];
+} EFI_HII_IMAGE_PALETTE_INFO;
+
+//
+// Forms Package
+//
+
+typedef struct _EFI_HII_FORM_PACKAGE {
+ EFI_HII_PACKAGE_HEADER Header;
+ // EFI_IFR_OP_HEADER OpCodeHeader;
+ // More op-codes follow
+} EFI_HII_FORM_PACKAGE;
+
+typedef struct {
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+} EFI_HII_TIME;
+
+typedef struct {
+ UINT16 Year;
+ UINT8 Month;
+ UINT8 Day;
+} EFI_HII_DATE;
+
+typedef struct {
+ EFI_QUESTION_ID QuestionId;
+ EFI_FORM_ID FormId;
+ EFI_GUID FormSetGuid;
+ EFI_STRING_ID DevicePath;
+} EFI_HII_REF;
+
+typedef union {
+ UINT8 u8;
+ UINT16 u16;
+ UINT32 u32;
+ UINT64 u64;
+ BOOLEAN b;
+ EFI_HII_TIME time;
+ EFI_HII_DATE date;
+ EFI_STRING_ID string;
+ EFI_HII_REF ref;
+} EFI_IFR_TYPE_VALUE;
+
+#define EFI_IFR_FORM_OP 0x01
+#define EFI_IFR_SUBTITLE_OP 0x02
+#define EFI_IFR_TEXT_OP 0x03
+#define EFI_IFR_IMAGE_OP 0x04
+#define EFI_IFR_ONE_OF_OP 0x05
+#define EFI_IFR_CHECKBOX_OP 0x06
+#define EFI_IFR_NUMERIC_OP 0x07
+#define EFI_IFR_PASSWORD_OP 0x08
+#define EFI_IFR_ONE_OF_OPTION_OP 0x09
+#define EFI_IFR_SUPPRESS_IF_OP 0x0A
+#define EFI_IFR_LOCKED_OP 0x0B
+#define EFI_IFR_ACTION_OP 0x0C
+#define EFI_IFR_RESET_BUTTON_OP 0x0D
+#define EFI_IFR_FORM_SET_OP 0x0E
+#define EFI_IFR_REF_OP 0x0F
+#define EFI_IFR_NO_SUBMIT_IF_OP 0x10
+#define EFI_IFR_INCONSISTENT_IF_OP 0x11
+#define EFI_IFR_EQ_ID_VAL_OP 0x12
+#define EFI_IFR_EQ_ID_ID_OP 0x13
+#define EFI_IFR_EQ_ID_VAL_LIST_OP 0x14
+#define EFI_IFR_AND_OP 0x15
+#define EFI_IFR_OR_OP 0x16
+#define EFI_IFR_NOT_OP 0x17
+#define EFI_IFR_RULE_OP 0x18
+#define EFI_IFR_GRAY_OUT_IF_OP 0x19
+#define EFI_IFR_DATE_OP 0x1A
+#define EFI_IFR_TIME_OP 0x1B
+#define EFI_IFR_STRING_OP 0x1C
+#define EFI_IFR_REFRESH_OP 0x1D
+#define EFI_IFR_DISABLE_IF_OP 0x1E
+#define EFI_IFR_TO_LOWER_OP 0x20
+#define EFI_IFR_TO_UPPER_OP 0x21
+#define EFI_IFR_MAP_OP 0x22
+#define EFI_IFR_ORDERED_LIST_OP 0x23
+#define EFI_IFR_VARSTORE_OP 0x24
+#define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25
+#define EFI_IFR_VARSTORE_EFI_OP 0x26
+#define EFI_IFR_VARSTORE_DEVICE_OP 0x27
+#define EFI_IFR_VERSION_OP 0x28
+#define EFI_IFR_END_OP 0x29
+#define EFI_IFR_MATCH_OP 0x2A
+#define EFI_IFR_GET_OP 0x2B
+#define EFI_IFR_SET_OP 0x2C
+#define EFI_IFR_READ_OP 0x2D
+#define EFI_IFR_WRITE_OP 0x2E
+#define EFI_IFR_EQUAL_OP 0x2F
+#define EFI_IFR_NOT_EQUAL_OP 0x30
+#define EFI_IFR_GREATER_THAN_OP 0x31
+#define EFI_IFR_GREATER_EQUAL_OP 0x32
+#define EFI_IFR_LESS_THAN_OP 0x33
+#define EFI_IFR_LESS_EQUAL_OP 0x34
+#define EFI_IFR_BITWISE_AND_OP 0x35
+#define EFI_IFR_BITWISE_OR_OP 0x36
+#define EFI_IFR_BITWISE_NOT_OP 0x37
+#define EFI_IFR_SHIFT_LEFT_OP 0x38
+#define EFI_IFR_SHIFT_RIGHT_OP 0x39
+#define EFI_IFR_ADD_OP 0x3A
+#define EFI_IFR_SUBTRACT_OP 0x3B
+#define EFI_IFR_MULTIPLY_OP 0x3C
+#define EFI_IFR_DIVIDE_OP 0x3D
+#define EFI_IFR_MODULO_OP 0x3E
+#define EFI_IFR_RULE_REF_OP 0x3F
+#define EFI_IFR_QUESTION_REF1_OP 0x40
+#define EFI_IFR_QUESTION_REF2_OP 0x41
+#define EFI_IFR_UINT8_OP 0x42
+#define EFI_IFR_UINT16_OP 0x43
+#define EFI_IFR_UINT32_OP 0x44
+#define EFI_IFR_UINT64_OP 0x45
+#define EFI_IFR_TRUE_OP 0x46
+#define EFI_IFR_FALSE_OP 0x47
+#define EFI_IFR_TO_UINT_OP 0x48
+#define EFI_IFR_TO_STRING_OP 0x49
+#define EFI_IFR_TO_BOOLEAN_OP 0x4A
+#define EFI_IFR_MID_OP 0x4B
+#define EFI_IFR_FIND_OP 0x4C
+#define EFI_IFR_TOKEN_OP 0x4D
+#define EFI_IFR_STRING_REF1_OP 0x4E
+#define EFI_IFR_STRING_REF2_OP 0x4F
+#define EFI_IFR_CONDITIONAL_OP 0x50
+#define EFI_IFR_QUESTION_REF3_OP 0x51
+#define EFI_IFR_ZERO_OP 0x52
+#define EFI_IFR_ONE_OP 0x53
+#define EFI_IFR_ONES_OP 0x54
+#define EFI_IFR_UNDEFINED_OP 0x55
+#define EFI_IFR_LENGTH_OP 0x56
+#define EFI_IFR_DUP_OP 0x57
+#define EFI_IFR_THIS_OP 0x58
+#define EFI_IFR_SPAN_OP 0x59
+#define EFI_IFR_VALUE_OP 0x5A
+#define EFI_IFR_DEFAULT_OP 0x5B
+#define EFI_IFR_DEFAULTSTORE_OP 0x5C
+#define EFI_IFR_FORM_MAP_OP 0x5D
+#define EFI_IFR_CATENATE_OP 0x5E
+#define EFI_IFR_GUID_OP 0x5F
+#define EFI_IFR_SECURITY_OP 0x60
+#define EFI_IFR_MODAL_TAG_OP 0x61
+#define EFI_IFR_REFRESH_ID_OP 0x62
+#define EFI_IFR_WARNING_IF_OP 0x63
+#define EFI_IFR_MATCH2_OP 0x64
+
+
+typedef struct _EFI_IFR_OP_HEADER {
+ UINT8 OpCode;
+ UINT8 Length:7;
+ UINT8 Scope:1;
+} EFI_IFR_OP_HEADER;
+
+typedef struct _EFI_IFR_STATEMENT_HEADER {
+ EFI_STRING_ID Prompt;
+ EFI_STRING_ID Help;
+} EFI_IFR_STATEMENT_HEADER;
+
+typedef struct _EFI_IFR_QUESTION_HEADER {
+ EFI_IFR_STATEMENT_HEADER Header;
+ EFI_QUESTION_ID QuestionId;
+ EFI_VARSTORE_ID VarStoreId;
+ union {
+ EFI_STRING_ID VarName;
+ UINT16 VarOffset;
+ } VarStoreInfo;
+ UINT8 Flags;
+} EFI_IFR_QUESTION_HEADER;
+
+#define EFI_IFR_FLAG_READ_ONLY 0x01
+#define EFI_IFR_FLAG_CALLBACK 0x04
+#define EFI_IFR_FLAG_RESET_REQUIRED 0x10
+#define EFI_IFR_FLAG_REST_STYLE 0x20
+#define EFI_IFR_FLAG_RECONNECT_REQUIRED 0x40
+#define EFI_IFR_FLAG_OPTIONS_ONLY 0x80
+
+typedef struct _EFI_IFR_DEFAULTSTORE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID DefaultName;
+ UINT16 DefaultId;
+} EFI_IFR_DEFAULTSTORE;
+
+#define EFI_HII_DEFAULT_CLASS_STANDARD 0x0000
+#define EFI_HII_DEFAULT_CLASS_MANUFACTURING 0x0001
+#define EFI_HII_DEFAULT_CLASS_SAFE 0x0002
+#define EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN 0x4000
+#define EFI_HII_DEFAULT_CLASS_PLATFORM_END 0x7fff
+#define EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN 0x8000
+#define EFI_HII_DEFAULT_CLASS_HARDWARE_END 0xbfff
+#define EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN 0xc000
+#define EFI_HII_DEFAULT_CLASS_FIRMWARE_END 0xffff
+
+typedef struct _EFI_IFR_VARSTORE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID Guid;
+ EFI_VARSTORE_ID VarStoreId;
+ UINT16 Size;
+ UINT8 Name[1];
+} EFI_IFR_VARSTORE;
+
+typedef struct _EFI_IFR_VARSTORE_EFI {
+ EFI_IFR_OP_HEADER Header;
+ EFI_VARSTORE_ID VarStoreId;
+ EFI_GUID Guid;
+ UINT32 Attributes;
+ UINT16 Size;
+ UINT8 Name[1];
+} EFI_IFR_VARSTORE_EFI;
+
+typedef struct _EFI_IFR_VARSTORE_NAME_VALUE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_VARSTORE_ID VarStoreId;
+ EFI_GUID Guid;
+} EFI_IFR_VARSTORE_NAME_VALUE;
+
+typedef struct _EFI_IFR_FORM_SET {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID Guid;
+ EFI_STRING_ID FormSetTitle;
+ EFI_STRING_ID Help;
+ UINT8 Flags;
+ // EFI_GUID ClassGuid[];
+} EFI_IFR_FORM_SET;
+
+typedef struct _EFI_IFR_END {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_END;
+
+typedef struct _EFI_IFR_FORM {
+ EFI_IFR_OP_HEADER Header;
+ UINT16 FormId;
+ EFI_STRING_ID FormTitle;
+} EFI_IFR_FORM;
+
+typedef struct _EFI_IFR_IMAGE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IMAGE_ID Id;
+} EFI_IFR_IMAGE;
+
+typedef struct _EFI_IFR_MODAL_TAG {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MODAL_TAG;
+
+typedef struct _EFI_IFR_LOCKED {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_LOCKED;
+
+typedef struct _EFI_IFR_RULE {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 RuleId;
+} EFI_IFR_RULE;
+
+typedef struct _EFI_IFR_DEFAULT {
+ EFI_IFR_OP_HEADER Header;
+ UINT16 DefaultId;
+ UINT8 Type;
+ EFI_IFR_TYPE_VALUE Value;
+} EFI_IFR_DEFAULT;
+
+typedef struct _EFI_IFR_DEFAULT_2 {
+ EFI_IFR_OP_HEADER Header;
+ UINT16 DefaultId;
+ UINT8 Type;
+} EFI_IFR_DEFAULT_2;
+
+typedef struct _EFI_IFR_VALUE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_VALUE;
+
+typedef struct _EFI_IFR_SUBTITLE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_STATEMENT_HEADER Statement;
+ UINT8 Flags;
+} EFI_IFR_SUBTITLE;
+
+#define EFI_IFR_FLAGS_HORIZONTAL 0x01
+
+typedef struct _EFI_IFR_CHECKBOX {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 Flags;
+} EFI_IFR_CHECKBOX;
+
+#define EFI_IFR_CHECKBOX_DEFAULT 0x01
+#define EFI_IFR_CHECKBOX_DEFAULT_MFG 0x02
+
+typedef struct _EFI_IFR_TEXT {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_STATEMENT_HEADER Statement;
+ EFI_STRING_ID TextTwo;
+} EFI_IFR_TEXT;
+
+typedef struct _EFI_IFR_REF {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ EFI_FORM_ID FormId;
+} EFI_IFR_REF;
+
+typedef struct _EFI_IFR_REF2 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ EFI_FORM_ID FormId;
+ EFI_QUESTION_ID QuestionId;
+} EFI_IFR_REF2;
+
+typedef struct _EFI_IFR_REF3 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ EFI_FORM_ID FormId;
+ EFI_QUESTION_ID QuestionId;
+ EFI_GUID FormSetId;
+} EFI_IFR_REF3;
+
+typedef struct _EFI_IFR_REF4 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ EFI_FORM_ID FormId;
+ EFI_QUESTION_ID QuestionId;
+ EFI_GUID FormSetId;
+ EFI_STRING_ID DevicePath;
+} EFI_IFR_REF4;
+
+typedef struct _EFI_IFR_REF5 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+} EFI_IFR_REF5;
+
+typedef struct _EFI_IFR_RESET_BUTTON {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_STATEMENT_HEADER Statement;
+ EFI_DEFAULT_ID DefaultId;
+} EFI_IFR_RESET_BUTTON;
+
+typedef struct _EFI_IFR_ACTION {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ EFI_STRING_ID QuestionConfig;
+} EFI_IFR_ACTION;
+
+typedef struct _EFI_IFR_ACTION_1 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+} EFI_IFR_ACTION_1;
+
+typedef struct _EFI_IFR_DATE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 Flags;
+} EFI_IFR_DATE;
+
+#define EFI_QF_DATE_YEAR_SUPPRESS 0x01
+#define EFI_QF_DATE_MONTH_SUPPRESS 0x02
+#define EFI_QF_DATE_DAY_SUPPRESS 0x04
+
+#define EFI_QF_DATE_STORAGE 0x30
+#define QF_DATE_STORAGE_NORMAL 0x00
+#define QF_DATE_STORAGE_TIME 0x10
+#define QF_DATE_STORAGE_WAKEUP 0x20
+
+typedef union {
+ struct {
+ UINT8 MinValue;
+ UINT8 MaxValue;
+ UINT8 Step;
+ } u8;
+ struct {
+ UINT16 MinValue;
+ UINT16 MaxValue;
+ UINT16 Step;
+ } u16;
+ struct {
+ UINT32 MinValue;
+ UINT32 MaxValue;
+ UINT32 Step;
+ } u32;
+ struct {
+ UINT64 MinValue;
+ UINT64 MaxValue;
+ UINT64 Step;
+ } u64;
+} MINMAXSTEP_DATA;
+
+typedef struct _EFI_IFR_NUMERIC {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 Flags;
+ MINMAXSTEP_DATA data;
+} EFI_IFR_NUMERIC;
+
+#define EFI_IFR_NUMERIC_SIZE 0x03
+#define EFI_IFR_NUMERIC_SIZE_1 0x00
+#define EFI_IFR_NUMERIC_SIZE_2 0x01
+#define EFI_IFR_NUMERIC_SIZE_4 0x02
+#define EFI_IFR_NUMERIC_SIZE_8 0x03
+
+#define EFI_IFR_DISPLAY 0x30
+#define EFI_IFR_DISPLAY_INT_DEC 0x00
+#define EFI_IFR_DISPLAY_UINT_DEC 0x10
+#define EFI_IFR_DISPLAY_UINT_HEX 0x20
+
+typedef struct _EFI_IFR_ONE_OF {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 Flags;
+ MINMAXSTEP_DATA data;
+} EFI_IFR_ONE_OF;
+
+typedef struct _EFI_IFR_STRING {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 MinSize;
+ UINT8 MaxSize;
+ UINT8 Flags;
+} EFI_IFR_STRING;
+
+#define EFI_IFR_STRING_MULTI_LINE 0x01
+
+typedef struct _EFI_IFR_PASSWORD {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT16 MinSize;
+ UINT16 MaxSize;
+} EFI_IFR_PASSWORD;
+
+typedef struct _EFI_IFR_ORDERED_LIST {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 MaxContainers;
+ UINT8 Flags;
+} EFI_IFR_ORDERED_LIST;
+
+#define EFI_IFR_UNIQUE_SET 0x01
+#define EFI_IFR_NO_EMPTY_SET 0x02
+
+typedef struct _EFI_IFR_TIME {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+ UINT8 Flags;
+} EFI_IFR_TIME;
+
+#define QF_TIME_HOUR_SUPPRESS 0x01
+#define QF_TIME_MINUTE_SUPPRESS 0x02
+#define QF_TIME_SECOND_SUPPRESS 0x04
+
+#define QF_TIME_STORAGE 0x30
+#define QF_TIME_STORAGE_NORMAL 0x00
+#define QF_TIME_STORAGE_TIME 0x10
+#define QF_TIME_STORAGE_WAKEUP 0x20
+
+typedef struct _EFI_IFR_DISABLE_IF {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_DISABLE_IF;
+
+typedef struct _EFI_IFR_SUPPRESS_IF {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_SUPPRESS_IF;
+
+typedef struct _EFI_IFR_GRAY_OUT_IF {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_GRAY_OUT_IF;
+
+typedef struct _EFI_IFR_INCONSISTENT_IF {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID Error;
+} EFI_IFR_INCONSISTENT_IF;
+
+typedef struct _EFI_IFR_NO_SUBMIT_IF {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID Error;
+} EFI_IFR_NO_SUBMIT_IF;
+
+typedef struct _EFI_IFR_WARNING_IF {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID Warning;
+ UINT8 TimeOut;
+} EFI_IFR_WARNING_IF;
+
+typedef struct _EFI_IFR_REFRESH {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 RefreshInterval;
+} EFI_IFR_REFRESH;
+
+typedef struct _EFI_IFR_REFRESH_ID {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID RefreshEventGroupId;
+} EFI_IFR_REFRESH_ID;
+
+typedef struct _EFI_IFR_VARSTORE_DEVICE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID DevicePath;
+} EFI_IFR_VARSTORE_DEVICE;
+
+typedef struct _EFI_IFR_ONE_OF_OPTION {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID Option;
+ UINT8 Flags;
+ UINT8 Type;
+ EFI_IFR_TYPE_VALUE Value;
+} EFI_IFR_ONE_OF_OPTION;
+
+#define EFI_IFR_TYPE_NUM_SIZE_8 0x00
+#define EFI_IFR_TYPE_NUM_SIZE_16 0x01
+#define EFI_IFR_TYPE_NUM_SIZE_32 0x02
+#define EFI_IFR_TYPE_NUM_SIZE_64 0x03
+#define EFI_IFR_TYPE_BOOLEAN 0x04
+#define EFI_IFR_TYPE_TIME 0x05
+#define EFI_IFR_TYPE_DATE 0x06
+#define EFI_IFR_TYPE_STRING 0x07
+#define EFI_IFR_TYPE_OTHER 0x08
+#define EFI_IFR_TYPE_UNDEFINED 0x09
+#define EFI_IFR_TYPE_ACTION 0x0A
+#define EFI_IFR_TYPE_BUFFER 0x0B
+#define EFI_IFR_TYPE_REF 0x0C
+
+#define EFI_IFR_OPTION_DEFAULT 0x10
+#define EFI_IFR_OPTION_DEFAULT_MFG 0x20
+
+typedef struct _EFI_IFR_GUID {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID Guid;
+ //Optional Data Follows
+} EFI_IFR_GUID;
+
+typedef struct _EFI_IFR_DUP {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_DUP;
+
+typedef struct _EFI_IFR_EQ_ID_ID {
+ EFI_IFR_OP_HEADER Header;
+ EFI_QUESTION_ID QuestionId1;
+ EFI_QUESTION_ID QuestionId2;
+} EFI_IFR_EQ_ID_ID;
+
+typedef struct _EFI_IFR_EQ_ID_VAL {
+ EFI_IFR_OP_HEADER Header;
+ EFI_QUESTION_ID QuestionId;
+ UINT16 Value;
+} EFI_IFR_EQ_ID_VAL;
+
+typedef struct _EFI_IFR_EQ_ID_VAL_LIST {
+ EFI_IFR_OP_HEADER Header;
+ EFI_QUESTION_ID QuestionId;
+ UINT16 ListLength;
+ UINT16 ValueList[1];
+} EFI_IFR_EQ_ID_VAL_LIST;
+
+typedef struct _EFI_IFR_QUESTION_REF1 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_QUESTION_ID QuestionId;
+} EFI_IFR_QUESTION_REF1;
+
+typedef struct _EFI_IFR_UINT8 {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 Value;
+} EFI_IFR_UINT8;
+
+typedef struct _EFI_IFR_UINT16 {
+ EFI_IFR_OP_HEADER Header;
+ UINT16 Value;
+} EFI_IFR_UINT16;
+
+typedef struct _EFI_IFR_QUESTION_REF2 {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_QUESTION_REF2;
+
+typedef struct _EFI_IFR_UINT32 {
+ EFI_IFR_OP_HEADER Header;
+ UINT32 Value;
+} EFI_IFR_UINT32;
+
+typedef struct _EFI_IFR_UINT64 {
+ EFI_IFR_OP_HEADER Header;
+ UINT64 Value;
+} EFI_IFR_UINT64;
+
+typedef struct _EFI_IFR_QUESTION_REF3 {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_QUESTION_REF3;
+
+typedef struct _EFI_IFR_QUESTION_REF3_2 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID DevicePath;
+} EFI_IFR_QUESTION_REF3_2;
+
+typedef struct _EFI_IFR_QUESTION_REF3_3 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID DevicePath;
+ EFI_GUID Guid;
+} EFI_IFR_QUESTION_REF3_3;
+
+typedef struct _EFI_IFR_RULE_REF {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 RuleId;
+} EFI_IFR_RULE_REF;
+
+typedef struct _EFI_IFR_STRING_REF1 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_STRING_ID StringId;
+} EFI_IFR_STRING_REF1;
+
+typedef struct _EFI_IFR_STRING_REF2 {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_STRING_REF2;
+
+typedef struct _EFI_IFR_THIS {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_THIS;
+
+typedef struct _EFI_IFR_TRUE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_TRUE;
+
+typedef struct _EFI_IFR_FALSE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_FALSE;
+
+typedef struct _EFI_IFR_ONE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_ONE;
+
+typedef struct _EFI_IFR_ONES {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_ONES;
+
+typedef struct _EFI_IFR_ZERO {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_ZERO;
+
+typedef struct _EFI_IFR_UNDEFINED {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_UNDEFINED;
+
+typedef struct _EFI_IFR_VERSION {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_VERSION;
+
+typedef struct _EFI_IFR_LENGTH {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_LENGTH;
+
+typedef struct _EFI_IFR_NOT {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_NOT;
+
+typedef struct _EFI_IFR_BITWISE_NOT {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_BITWISE_NOT;
+
+typedef struct _EFI_IFR_TO_BOOLEAN {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_TO_BOOLEAN;
+
+#define EFI_IFR_STRING_UNSIGNED_DEC 0
+#define EFI_IFR_STRING_SIGNED_DEC 1
+#define EFI_IFR_STRING_LOWERCASE_HEX 2
+#define EFI_IFR_STRING_UPPERCASE_HEX 3
+
+#define EFI_IFR_STRING_ASCII 0
+#define EFI_IFR_STRING_UNICODE 8
+
+typedef struct _EFI_IFR_TO_STRING {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 Format;
+} EFI_IFR_TO_STRING;
+
+typedef struct _EFI_IFR_TO_UINT {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_TO_UINT;
+
+typedef struct _EFI_IFR_TO_UPPER {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_TO_UPPER;
+
+typedef struct _EFI_IFR_TO_LOWER {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_TO_LOWER;
+
+typedef struct _EFI_IFR_ADD {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_ADD;
+
+typedef struct _EFI_IFR_AND {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_AND;
+
+typedef struct _EFI_IFR_BITWISE_AND {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_BITWISE_AND;
+
+typedef struct _EFI_IFR_BITWISE_OR {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_BITWISE_OR;
+
+typedef struct _EFI_IFR_CATENATE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_CATENATE;
+
+typedef struct _EFI_IFR_DIVIDE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_DIVIDE;
+
+typedef struct _EFI_IFR_EQUAL {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_EQUAL;
+
+typedef struct _EFI_IFR_GREATER_EQUAL {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_GREATER_EQUAL;
+
+typedef struct _EFI_IFR_GREATER_THAN {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_GREATER_THAN;
+
+typedef struct _EFI_IFR_LESS_EQUAL {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_LESS_EQUAL;
+
+typedef struct _EFI_IFR_LESS_THAN {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_LESS_THAN;
+
+typedef struct _EFI_IFR_MATCH {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MATCH;
+
+typedef struct _EFI_IFR_MATCH2 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID SyntaxType;
+} EFI_IFR_MATCH2;
+
+typedef struct _EFI_IFR_MULTIPLY {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MULTIPLY;
+
+typedef struct _EFI_IFR_MODULO {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MODULO;
+
+typedef struct _EFI_IFR_NOT_EQUAL {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_NOT_EQUAL;
+
+typedef struct _EFI_IFR_OR {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_OR;
+
+typedef struct _EFI_IFR_SHIFT_LEFT {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_SHIFT_LEFT;
+
+typedef struct _EFI_IFR_SHIFT_RIGHT {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_SHIFT_RIGHT;
+
+typedef struct _EFI_IFR_SUBTRACT {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_SUBTRACT;
+
+typedef struct _EFI_IFR_CONDITIONAL {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_CONDITIONAL;
+
+#define EFI_IFR_FF_CASE_SENSITIVE 0x00
+#define EFI_IFR_FF_CASE_INSENSITIVE 0x01
+
+typedef struct _EFI_IFR_FIND {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 Format;
+} EFI_IFR_FIND;
+
+typedef struct _EFI_IFR_MID {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MID;
+
+typedef struct _EFI_IFR_TOKEN {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_TOKEN;
+
+#define EFI_IFR_FLAGS_FIRST_MATCHING 0x00
+#define EFI_IFR_FLAGS_FIRST_NON_MATCHING 0x01
+
+typedef struct _EFI_IFR_SPAN {
+ EFI_IFR_OP_HEADER Header;
+ UINT8 Flags;
+} EFI_IFR_SPAN;
+
+typedef struct _EFI_IFR_SECURITY {
+ ///
+ /// Standard opcode header, where Header.Op = EFI_IFR_SECURITY_OP.
+ ///
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// Security permission level.
+ ///
+ EFI_GUID Permissions;
+} EFI_IFR_SECURITY;
+
+typedef struct _EFI_IFR_FORM_MAP_METHOD {
+ ///
+ /// The string identifier which provides the human-readable name of
+ /// the configuration method for this standards map form.
+ ///
+ EFI_STRING_ID MethodTitle;
+ ///
+ /// Identifier which uniquely specifies the configuration methods
+ /// associated with this standards map form.
+ ///
+ EFI_GUID MethodIdentifier;
+} EFI_IFR_FORM_MAP_METHOD;
+
+typedef struct _EFI_IFR_FORM_MAP {
+ ///
+ /// The sequence that defines the type of opcode as well as the length
+ /// of the opcode being defined. Header.OpCode = EFI_IFR_FORM_MAP_OP.
+ ///
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// The unique identifier for this particular form.
+ ///
+ EFI_FORM_ID FormId;
+ ///
+ /// One or more configuration method's name and unique identifier.
+ ///
+ // EFI_IFR_FORM_MAP_METHOD Methods[];
+} EFI_IFR_FORM_MAP;
+
+typedef struct _EFI_IFR_SET {
+ ///
+ /// The sequence that defines the type of opcode as well as the length
+ /// of the opcode being defined. Header.OpCode = EFI_IFR_SET_OP.
+ ///
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// Specifies the identifier of a previously declared variable store to
+ /// use when storing the question's value.
+ ///
+ EFI_VARSTORE_ID VarStoreId;
+ union {
+ ///
+ /// A 16-bit Buffer Storage offset.
+ ///
+ EFI_STRING_ID VarName;
+ ///
+ /// A Name Value or EFI Variable name (VarName).
+ ///
+ UINT16 VarOffset;
+ } VarStoreInfo;
+ ///
+ /// Specifies the type used for storage.
+ ///
+ UINT8 VarStoreType;
+} EFI_IFR_SET;
+
+typedef struct _EFI_IFR_GET {
+ ///
+ /// The sequence that defines the type of opcode as well as the length
+ /// of the opcode being defined. Header.OpCode = EFI_IFR_GET_OP.
+ ///
+ EFI_IFR_OP_HEADER Header;
+ ///
+ /// Specifies the identifier of a previously declared variable store to
+ /// use when retrieving the value.
+ ///
+ EFI_VARSTORE_ID VarStoreId;
+ union {
+ ///
+ /// A 16-bit Buffer Storage offset.
+ ///
+ EFI_STRING_ID VarName;
+ ///
+ /// A Name Value or EFI Variable name (VarName).
+ ///
+ UINT16 VarOffset;
+ } VarStoreInfo;
+ ///
+ /// Specifies the type used for storage.
+ ///
+ UINT8 VarStoreType;
+} EFI_IFR_GET;
+
+typedef struct _EFI_IFR_READ {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_READ;
+
+typedef struct _EFI_IFR_WRITE {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_WRITE;
+
+typedef struct _EFI_IFR_MAP {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MAP;
+//
+// Keyboard Package
+//
+
+typedef enum {
+ EfiKeyLCtrl,
+ EfiKeyA0,
+ EfiKeyLAlt,
+ EfiKeySpaceBar,
+ EfiKeyA2,
+ EfiKeyA3,
+ EfiKeyA4,
+ EfiKeyRCtrl,
+ EfiKeyLeftArrow,
+ EfiKeyDownArrow,
+ EfiKeyRightArrow,
+ EfiKeyZero,
+ EfiKeyPeriod,
+ EfiKeyEnter,
+ EfiKeyLShift,
+ EfiKeyB0,
+ EfiKeyB1,
+ EfiKeyB2,
+ EfiKeyB3,
+ EfiKeyB4,
+ EfiKeyB5,
+ EfiKeyB6,
+ EfiKeyB7,
+ EfiKeyB8,
+ EfiKeyB9,
+ EfiKeyB10,
+ EfiKeyRshift,
+ EfiKeyUpArrow,
+ EfiKeyOne,
+ EfiKeyTwo,
+ EfiKeyThree,
+ EfiKeyCapsLock,
+ EfiKeyC1,
+ EfiKeyC2,
+ EfiKeyC3,
+ EfiKeyC4,
+ EfiKeyC5,
+ EfiKeyC6,
+ EfiKeyC7,
+ EfiKeyC8,
+ EfiKeyC9,
+ EfiKeyC10,
+ EfiKeyC11,
+ EfiKeyC12,
+ EfiKeyFour,
+ EfiKeyFive,
+ EfiKeySix,
+ EfiKeyPlus,
+ EfiKeyTab,
+ EfiKeyD1,
+ EfiKeyD2,
+ EfiKeyD3,
+ EfiKeyD4,
+ EfiKeyD5,
+ EfiKeyD6,
+ EfiKeyD7,
+ EfiKeyD8,
+ EfiKeyD9,
+ EfiKeyD10,
+ EfiKeyD11,
+ EfiKeyD12,
+ EfiKeyD13,
+ EfiKeyDel,
+ EfiKeyEnd,
+ EfiKeyPgDn,
+ EfiKeySeven,
+ EfiKeyEight,
+ EfiKeyNine,
+ EfiKeyE0,
+ EfiKeyE1,
+ EfiKeyE2,
+ EfiKeyE3,
+ EfiKeyE4,
+ EfiKeyE5,
+ EfiKeyE6,
+ EfiKeyE7,
+ EfiKeyE8,
+ EfiKeyE9,
+ EfiKeyE10,
+ EfiKeyE11,
+ EfiKeyE12,
+ EfiKeyBackSpace,
+ EfiKeyIns,
+ EfiKeyHome,
+ EfiKeyPgUp,
+ EfiKeyNLck,
+ EfiKeySlash,
+ EfiKeyAsterisk,
+ EfiKeyMinus,
+ EfiKeyEsc,
+ EfiKeyF1,
+ EfiKeyF2,
+ EfiKeyF3,
+ EfiKeyF4,
+ EfiKeyF5,
+ EfiKeyF6,
+ EfiKeyF7,
+ EfiKeyF8,
+ EfiKeyF9,
+ EfiKeyF10,
+ EfiKeyF11,
+ EfiKeyF12,
+ EfiKeyPrint,
+ EfiKeySLck,
+ EfiKeyPause
+} EFI_KEY;
+
+typedef struct {
+ EFI_KEY Key;
+ CHAR16 Unicode;
+ CHAR16 ShiftedUnicode;
+ CHAR16 AltGrUnicode;
+ CHAR16 ShiftedAltGrUnicode;
+ UINT16 Modifier;
+ UINT16 AffectedAttribute;
+} EFI_KEY_DESCRIPTOR;
+
+//
+// A key which is affected by all the standard shift modifiers.
+// Most keys would be expected to have this bit active.
+//
+#define EFI_AFFECTED_BY_STANDARD_SHIFT 0x0001
+//
+// This key is affected by the caps lock so that if a keyboard driver
+// would need to disambiguate between a key which had a "1" defined
+// versus a "a" character. Having this bit turned on would tell
+// the keyboard driver to use the appropriate shifted state or not.
+//
+#define EFI_AFFECTED_BY_CAPS_LOCK 0x0002
+//
+// Similar to the case of CAPS lock, if this bit is active, the key
+// is affected by the num lock being turned on.
+//
+#define EFI_AFFECTED_BY_NUM_LOCK 0x0004
+
+typedef struct {
+ UINT16 LayoutLength;
+ EFI_GUID Guid;
+ UINT32 LayoutDescriptorStringOffset;
+ UINT8 DescriptorCount;
+ // EFI_KEY_DESCRIPTOR Descriptors[];
+} EFI_HII_KEYBOARD_LAYOUT;
+
+typedef struct {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT16 LayoutCount;
+ // EFI_HII_KEYBOARD_LAYOUT Layout[];
+} EFI_HII_KEYBOARD_PACKAGE_HDR;
+
+typedef struct {
+ CHAR16 Language[3];
+ CHAR16 Space;
+ CHAR16 DescriptionString[1];
+} EFI_DESCRIPTION_STRING;
+
+typedef struct {
+ UINT16 DescriptionCount;
+ EFI_DESCRIPTION_STRING DescriptionString[1];
+} EFI_DESCRIPTION_STRING_BUNDLE;
+
+//
+// Modifier values
+//
+#define EFI_NULL_MODIFIER 0x0000
+#define EFI_LEFT_CONTROL_MODIFIER 0x0001
+#define EFI_RIGHT_CONTROL_MODIFIER 0x0002
+#define EFI_LEFT_ALT_MODIFIER 0x0003
+#define EFI_RIGHT_ALT_MODIFIER 0x0004
+#define EFI_ALT_GR_MODIFIER 0x0005
+#define EFI_INSERT_MODIFIER 0x0006
+#define EFI_DELETE_MODIFIER 0x0007
+#define EFI_PAGE_DOWN_MODIFIER 0x0008
+#define EFI_PAGE_UP_MODIFIER 0x0009
+#define EFI_HOME_MODIFIER 0x000A
+#define EFI_END_MODIFIER 0x000B
+#define EFI_LEFT_SHIFT_MODIFIER 0x000C
+#define EFI_RIGHT_SHIFT_MODIFIER 0x000D
+#define EFI_CAPS_LOCK_MODIFIER 0x000E
+#define EFI_NUM_LOCK _MODIFIER 0x000F
+#define EFI_LEFT_ARROW_MODIFIER 0x0010
+#define EFI_RIGHT_ARROW_MODIFIER 0x0011
+#define EFI_DOWN_ARROW_MODIFIER 0x0012
+#define EFI_UP_ARROW_MODIFIER 0x0013
+#define EFI_NS_KEY_MODIFIER 0x0014
+#define EFI_NS_KEY_DEPENDENCY_MODIFIER 0x0015
+#define EFI_FUNCTION_KEY_ONE_MODIFIER 0x0016
+#define EFI_FUNCTION_KEY_TWO_MODIFIER 0x0017
+#define EFI_FUNCTION_KEY_THREE_MODIFIER 0x0018
+#define EFI_FUNCTION_KEY_FOUR_MODIFIER 0x0019
+#define EFI_FUNCTION_KEY_FIVE_MODIFIER 0x001A
+#define EFI_FUNCTION_KEY_SIX_MODIFIER 0x001B
+#define EFI_FUNCTION_KEY_SEVEN_MODIFIER 0x001C
+#define EFI_FUNCTION_KEY_EIGHT_MODIFIER 0x001D
+#define EFI_FUNCTION_KEY_NINE_MODIFIER 0x001E
+#define EFI_FUNCTION_KEY_TEN_MODIFIER 0x001F
+#define EFI_FUNCTION_KEY_ELEVEN_MODIFIER 0x0020
+#define EFI_FUNCTION_KEY_TWELVE_MODIFIER 0x0021
+
+//
+// Keys that have multiple control functions based on modifier
+// settings are handled in the keyboard driver implementation.
+// For instance PRINT_KEY might have a modifier held down and
+// is still a nonprinting character, but might have an alternate
+// control function like SYSREQUEST
+//
+#define EFI_PRINT_MODIFIER 0x0022
+#define EFI_SYS_REQUEST_MODIFIER 0x0023
+#define EFI_SCROLL_LOCK_MODIFIER 0x0024
+#define EFI_PAUSE_MODIFIER 0x0025
+#define EFI_BREAK_MODIFIER 0x0026
+
+#pragma pack()
+
+
+
+//
+// References to string tokens must use this macro to enable scanning for
+// token usages.
+//
+//
+// STRING_TOKEN is not defined in UEFI specification. But it is placed
+// here for the easy access by C files and VFR source files.
+//
+#define STRING_TOKEN(t) t
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiMultiPhase.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiMultiPhase.h
new file mode 100644
index 00000000..dbaed77a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/UefiMultiPhase.h
@@ -0,0 +1,226 @@
+/** @file
+ This includes some definitions introduced in UEFI that will be used in both PEI
+ and DXE phases.
+
+ (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __UEFI_MULTIPHASE_H__
+#define __UEFI_MULTIPHASE_H__
+
+//
+// Enumeration of memory types introduced in UEFI.
+//
+typedef enum {
+ EfiReservedMemoryType,
+ EfiLoaderCode,
+ EfiLoaderData,
+ EfiBootServicesCode,
+ EfiBootServicesData,
+ EfiRuntimeServicesCode,
+ EfiRuntimeServicesData,
+ EfiConventionalMemory,
+ EfiUnusableMemory,
+ EfiACPIReclaimMemory,
+ EfiACPIMemoryNVS,
+ EfiMemoryMappedIO,
+ EfiMemoryMappedIOPortSpace,
+ EfiPalCode,
+ EfiPersistentMemory,
+ EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+
+//
+// Data structure that precedes all of the standard EFI table types.
+//
+typedef struct {
+ UINT64 Signature;
+ UINT32 Revision;
+ UINT32 HeaderSize;
+ UINT32 CRC32;
+ UINT32 Reserved;
+} EFI_TABLE_HEADER;
+
+//
+// Attributes of variable.
+//
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+
+//
+// This attribute is identified by the mnemonic 'HR'
+// elsewhere in this specification.
+//
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+
+
+
+//
+// _WIN_CERTIFICATE.wCertificateType
+//
+#define WIN_CERT_TYPE_EFI_PKCS115 0x0EF0
+#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
+
+/**
+
+ The WIN_CERTIFICATE structure is part of the PE/COFF
+ specification and has the following definition:
+
+ @param dwLength The length of the entire certificate,
+ including the length of the header, in
+ bytes.
+
+ @param wRevision The revision level of the WIN_CERTIFICATE
+ structure. The current revision level is
+ 0x0200.
+
+ @param wCertificateType The certificate type. See
+ WIN_CERT_TYPE_xxx for the UEFI
+ certificate types. The UEFI
+ specification reserves the range of
+ certificate type values from 0x0EF0
+ to 0x0EFF.
+
+ @param bCertificate The actual certificate. The format of
+ the certificate depends on
+ wCertificateType. The format of the UEFI
+ certificates is defined below.
+
+
+**/
+typedef struct _WIN_CERTIFICATE {
+ UINT32 dwLength;
+ UINT16 wRevision;
+ UINT16 wCertificateType;
+ //UINT8 bCertificate[ANYSIZE_ARRAY];
+} WIN_CERTIFICATE;
+
+//
+// WIN_CERTIFICATE_UEFI_GUID.CertType
+//
+#define EFI_CERT_TYPE_RSA2048_SHA256_GUID \
+ {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } }
+
+//
+// WIN_CERTIFICATE_UEFI_GUID.CertData
+//
+typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {
+ EFI_GUID HashType;
+ UINT8 PublicKey[256];
+ UINT8 Signature[256];
+} EFI_CERT_BLOCK_RSA_2048_SHA256;
+
+
+/**
+
+ @param Hdr This is the standard WIN_CERTIFICATE header, where
+ wCertificateType is set to
+ WIN_CERT_TYPE_EFI_GUID.
+
+ @param CertType This is the unique id which determines the
+ format of the CertData. In this case, the
+ value is EFI_CERT_TYPE_RSA2048_SHA256_GUID.
+
+ @param CertData This is the certificate data. The format of
+ the data is determined by the CertType. In
+ this case the value is
+ EFI_CERT_BLOCK_RSA_2048_SHA256.
+
+ @param Information The WIN_CERTIFICATE_UEFI_GUID certificate
+ type allows new types of certificates to
+ be developed for driver authentication
+ without requiring a new certificate type.
+ The CertType defines the format of the
+ CertData, which length is defined by the
+ size of the certificate less the fixed
+ size of the WIN_CERTIFICATE_UEFI_GUID
+ structure.
+
+**/
+typedef struct _WIN_CERTIFICATE_UEFI_GUID {
+ WIN_CERTIFICATE Hdr;
+ EFI_GUID CertType;
+ UINT8 CertData[1];
+} WIN_CERTIFICATE_UEFI_GUID;
+
+
+/**
+
+ Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital
+ signature.
+
+ The WIN_CERTIFICATE_UEFI_PKCS1_15 structure is derived from
+ WIN_CERTIFICATE and encapsulate the information needed to
+ implement the RSASSA-PKCS1-v1_5 digital signature algorithm as
+ specified in RFC2437.
+
+ @param Hdr This is the standard WIN_CERTIFICATE header, where
+ wCertificateType is set to
+ WIN_CERT_TYPE_UEFI_PKCS1_15.
+
+ @param HashAlgorithm This is the hashing algorithm which was
+ performed on the UEFI executable when
+ creating the digital signature. It is
+ one of the enumerated values pre-defined
+ in Section 26.4.1. See
+ EFI_HASH_ALGORITHM_x.
+
+ @param Signature This is the actual digital signature. The
+ size of the signature is the same size as
+ the key (1024-bit key is 128 bytes) and can
+ be determined by subtracting the length of
+ the other parts of this header from the
+ total length of the certificate as found in
+ Hdr.dwLength.
+
+**/
+typedef struct _WIN_CERTIFICATE_EFI_PKCS1_15 {
+ WIN_CERTIFICATE Hdr;
+ EFI_GUID HashAlgorithm;
+ // UINT8 Signature[ANYSIZE_ARRAY];
+} WIN_CERTIFICATE_EFI_PKCS1_15;
+
+
+/**
+
+ AuthInfo is a WIN_CERTIFICATE using the wCertificateType
+ WIN_CERTIFICATE_UEFI_GUID and the CertType
+ EFI_CERT_TYPE_RSA2048_SHA256. If the attribute specifies
+ authenticated access, then the Data buffer should begin with an
+ authentication descriptor prior to the data payload and DataSize
+ should reflect the data.and descriptor size. The caller
+ shall digest the Monotonic Count value and the associated data
+ for the variable update using the SHA-256 1-way hash algorithm.
+ The ensuing the 32-byte digest will be signed using the private
+ key associated w/ the public/private 2048-bit RSA key-pair. The
+ WIN_CERTIFICATE shall be used to describe the signature of the
+ Variable data *Data. In addition, the signature will also
+ include the MonotonicCount value to guard against replay attacks
+
+ @param MonotonicCount Included in the signature of
+ AuthInfo.Used to ensure freshness/no
+ replay. Incremented during each
+ "Write" access.
+
+ @param AuthInfo Provides the authorization for the variable
+ access. It is a signature across the
+ variable data and the Monotonic Count
+ value. Caller uses Private key that is
+ associated with a public key that has been
+ provisioned via the key exchange.
+
+**/
+typedef struct {
+ UINT64 MonotonicCount;
+ WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION;
+
+#endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/VariableFormat.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/VariableFormat.h
new file mode 100644
index 00000000..765f4e50
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/VariableFormat.h
@@ -0,0 +1,44 @@
+/**@file
+ Header file for EFI Variable Services.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __VARIABLE_FORMAT_H__
+#define __VARIABLE_FORMAT_H__
+
+#define VARIABLE_DATA 0x55AA
+
+//
+// Variable Store Header flags
+//
+#define VARIABLE_STORE_FORMATTED 0x5a
+#define VARIABLE_STORE_HEALTHY 0xfe
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_GUID Signature;
+ UINT32 Size;
+ UINT8 Format;
+ UINT8 State;
+ UINT16 Reserved;
+ UINT32 Reserved1;
+} VARIABLE_STORE_HEADER;
+
+typedef struct {
+ UINT16 StartId;
+ UINT8 State;
+ UINT8 Reserved;
+ UINT32 Attributes;
+ UINT32 NameSize;
+ UINT32 DataSize;
+ EFI_GUID VendorGuid;
+} VARIABLE_HEADER;
+
+#pragma pack()
+
+#endif // _EFI_VARIABLE_H_
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h
new file mode 100644
index 00000000..8912949b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h
@@ -0,0 +1,35 @@
+/** @file
+ Defines data structure that is the headers found at the runtime
+ updatable firmware volumes, such as the FileSystemGuid of the
+ working block, the header structure of the variable block, FTW
+ working block, or event log block.
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_WORKING_BLOCK_HEADER_H__
+#define __EFI_WORKING_BLOCK_HEADER_H__
+
+//
+// EFI Fault tolerant working block header
+// The header is immediately followed by the write queue.
+//
+typedef struct {
+ EFI_GUID Signature;
+ UINT32 Crc;
+ UINT8 WorkingBlockValid : 1;
+ UINT8 WorkingBlockInvalid : 1;
+#define WORKING_BLOCK_VALID 0x1
+#define WORKING_BLOCK_INVALID 0x2
+ UINT8 Reserved : 6;
+ UINT8 Reserved3[3];
+ UINT64 WriteQueueSize;
+ //
+ // UINT8 WriteQueue[WriteQueueSize];
+ //
+} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h
new file mode 100644
index 00000000..c067446a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/FfsSectionAlignmentPadding.h
@@ -0,0 +1,16 @@
+/** @file
+ Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FFS_SECTION_ALIGNMENT_PADDING_GUID_H__
+#define __FFS_SECTION_ALIGNMENT_PADDING_GUID_H__
+
+#define EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID \
+ { \
+ 0x04132C8D, 0x0A22, 0x4FA8, {0x82, 0x6E, 0x8B, 0xBF, 0xEF, 0xDB, 0x83, 0x6C } \
+ }
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PcAnsi.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PcAnsi.h
new file mode 100644
index 00000000..6f1cd564
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PcAnsi.h
@@ -0,0 +1,52 @@
+/** @file
+ Terminal Device Path Vendor Guid.
+ @par Revision Reference:
+ GUIDs defined in UEFI 2.0 spec.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PC_ANSI_H__
+#define __PC_ANSI_H__
+
+#define EFI_PC_ANSI_GUID \
+ { \
+ 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define EFI_VT_100_GUID \
+ { \
+ 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define EFI_VT_100_PLUS_GUID \
+ { \
+ 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 } \
+ }
+
+#define EFI_VT_UTF8_GUID \
+ { \
+ 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \
+ }
+
+#define EFI_UART_DEVICE_PATH_GUID \
+ { \
+ 0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \
+ }
+
+#define EFI_SAS_DEVICE_PATH_GUID \
+ { \
+ 0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \
+ }
+
+extern EFI_GUID gEfiPcAnsiGuid;
+extern EFI_GUID gEfiVT100Guid;
+extern EFI_GUID gEfiVT100PlusGuid;
+extern EFI_GUID gEfiVTUTF8Guid;
+extern EFI_GUID gEfiUartDevicePathGuid;
+extern EFI_GUID gEfiSasDevicePathGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h
new file mode 100644
index 00000000..c2ba64da
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h
@@ -0,0 +1,39 @@
+/** @file
+ Guid used to define the Firmware File System. See PI spec volume 3 for more
+ details.
+
+ @par Revision Reference:
+ Guids defined in PI Spec Volume 3
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FIRMWARE_FILE_SYSTEM2_GUID_H__
+#define __FIRMWARE_FILE_SYSTEM2_GUID_H__
+
+//
+// GUIDs defined by the PI specification.
+//
+#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
+ { \
+ 0x8c8ce578, 0x8a3d, 0x4f1c, {0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } \
+ }
+
+#define EFI_FIRMWARE_FILE_SYSTEM3_GUID \
+ { \
+ 0x5473c07a, 0x3dcb, 0x4dca, {0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a } \
+ }
+
+#define EFI_FFS_VOLUME_TOP_FILE_GUID \
+ { \
+ 0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x09 } \
+ }
+
+extern EFI_GUID gEfiFirmwareFileSystem2Guid;
+extern EFI_GUID gEfiFirmwareFileSystem3Guid;
+extern EFI_GUID gEfiFirmwareVolumeTopFileGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Ia32/ProcessorBind.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Ia32/ProcessorBind.h
new file mode 100644
index 00000000..983f7679
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Ia32/ProcessorBind.h
@@ -0,0 +1,155 @@
+/** @file
+ Processor or Compiler specific defines and types for x64.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+//
+// Define the processor type so other code can make processor based choices
+//
+#define MDE_CPU_IA32
+
+//
+// Make sure we are useing the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+#if _MSC_EXTENSIONS
+
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning ( disable : 4214 )
+
+//
+// Disabling the unreferenced formal parameter warnings.
+//
+#pragma warning ( disable : 4100 )
+
+//
+// Disable slightly different base types warning as CHAR8 * can not be set
+// to a constant string.
+//
+#pragma warning ( disable : 4057 )
+
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructs so suppress this warning
+//
+#pragma warning ( disable : 4127 )
+
+
+#endif
+
+
+#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)
+ //
+ // No ANSI C 2000 stdint.h integer width declarations, so define equivalents
+ //
+
+ #if _MSC_EXTENSIONS
+
+ //
+ // use Microsoft* C compiler dependent integer width types
+ //
+ typedef unsigned __int64 UINT64;
+ typedef __int64 INT64;
+ typedef unsigned __int32 UINT32;
+ typedef __int32 INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #else
+
+ //
+ // Assume standard IA-32 alignment.
+ // BugBug: Need to check portability of long long
+ //
+ typedef unsigned long long UINT64;
+ typedef long long INT64;
+ typedef unsigned int UINT32;
+ typedef int INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #endif
+
+ #define UINT8_MAX 0xff
+
+#else
+ //
+ // Use ANSI C 2000 stdint.h integer width declarations
+ //
+ #include "stdint.h"
+ typedef uint8_t BOOLEAN;
+ typedef int8_t INT8;
+ typedef uint8_t UINT8;
+ typedef int16_t INT16;
+ typedef uint16_t UINT16;
+ typedef int32_t INT32;
+ typedef uint32_t UINT32;
+ typedef int64_t INT64;
+ typedef uint64_t UINT64;
+ typedef char CHAR8;
+ typedef uint16_t CHAR16;
+
+#endif
+
+typedef UINT32 UINTN;
+typedef INT32 INTN;
+
+
+//
+// Processor specific defines
+//
+#define MAX_BIT 0x80000000
+#define MAX_2_BITS 0xC0000000
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#if _MSC_EXTENSIONS
+ //
+ // Microsoft* compiler requires _EFIAPI usage, __cdecl is Microsoft* specific C.
+ //
+ #define EFIAPI __cdecl
+#endif
+
+#ifdef __GNUC__
+ #define EFIAPI __attribute__((cdecl))
+#endif
+
+//
+// The Microsoft* C compiler can removed references to unreferenced data items
+// if the /OPT:REF linker option is used. We defined a macro as this is a
+// a non standard extension
+//
+#if _MSC_EXTENSIONS
+ #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
+#else
+ #define GLOBAL_REMOVE_IF_UNREFERENCED
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi.h
new file mode 100644
index 00000000..72577a22
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi.h
@@ -0,0 +1,117 @@
+/** @file
+ This file contains some basic ACPI definitions that are consumed by drivers
+ that do not care about ACPI versions.
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ACPI_H_
+#define _ACPI_H_
+
+//
+// Common table header, this prefaces all ACPI tables, including FACS, but
+// excluding the RSD PTR structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+} EFI_ACPI_COMMON_HEADER;
+
+//
+// Common ACPI description table header. This structure prefaces most ACPI tables.
+//
+#pragma pack(1)
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT8 Revision;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT64 OemTableId;
+ UINT32 OemRevision;
+ UINT32 CreatorId;
+ UINT32 CreatorRevision;
+} EFI_ACPI_DESCRIPTION_HEADER;
+
+#pragma pack()
+//
+// Define for Pci Host Bridge Resource Allocation
+//
+#define ACPI_ADDRESS_SPACE_DESCRIPTOR 0x8A
+#define ACPI_END_TAG_DESCRIPTOR 0x79
+
+#define ACPI_ADDRESS_SPACE_TYPE_MEM 0x00
+#define ACPI_ADDRESS_SPACE_TYPE_IO 0x01
+#define ACPI_ADDRESS_SPACE_TYPE_BUS 0x02
+
+//
+// Power Management Timer frequency is fixed at 3.579545MHz
+//
+#define ACPI_TIMER_FREQUENCY 3579545
+
+//
+// Make sure structures match spec
+//
+#pragma pack(1)
+
+typedef struct {
+ UINT8 Desc;
+ UINT16 Len;
+ UINT8 ResType;
+ UINT8 GenFlag;
+ UINT8 SpecificFlag;
+ UINT64 AddrSpaceGranularity;
+ UINT64 AddrRangeMin;
+ UINT64 AddrRangeMax;
+ UINT64 AddrTranslationOffset;
+ UINT64 AddrLen;
+} EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;
+
+typedef struct {
+ UINT8 Desc;
+ UINT8 Checksum;
+} EFI_ACPI_END_TAG_DESCRIPTOR;
+
+//
+// General use definitions
+//
+#define EFI_ACPI_RESERVED_BYTE 0x00
+#define EFI_ACPI_RESERVED_WORD 0x0000
+#define EFI_ACPI_RESERVED_DWORD 0x00000000
+#define EFI_ACPI_RESERVED_QWORD 0x0000000000000000
+
+//
+// Resource Type Specific Flags
+// Ref ACPI specification 6.4.3.5.5
+//
+// Bit [0] : Write Status, _RW
+//
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_WRITE (1 << 0)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_READ_ONLY (0 << 0)
+//
+// Bit [2:1] : Memory Attributes, _MEM
+//
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_NON_CACHEABLE (0 << 1)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE (1 << 1)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_WRITE_COMBINING (2 << 1)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE (3 << 1)
+//
+// Bit [4:3] : Memory Attributes, _MTP
+//
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_MEMORY (0 << 3)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_RESERVED (1 << 3)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_ACPI (2 << 3)
+#define EFI_APCI_MEMORY_RESOURCE_SPECIFIC_FLAG_ADDRESS_RANGE_NVS (3 << 3)
+//
+// Bit [5] : Memory to I/O Translation, _TTP
+//
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_TRANSLATION (1 << 5)
+#define EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_TYPE_STATIC (0 << 5)
+
+#pragma pack()
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi1_0.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi1_0.h
new file mode 100644
index 00000000..55b9168a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi1_0.h
@@ -0,0 +1,285 @@
+/** @file
+ ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ACPI_1_0_H_
+#define _ACPI_1_0_H_
+
+#include "IndustryStandard/Acpi.h"
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// ACPI 1.0b table structures
+//
+//
+// Root System Description Pointer Structure
+//
+typedef struct {
+ UINT64 Signature;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT8 Reserved;
+ UINT32 RsdtAddress;
+} EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
+
+//
+// Root System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT32 table pointers.
+//
+//
+// RSDT Revision (as defined in ACPI 1.0b spec.)
+//
+#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Fixed ACPI Description Table Structure (FADT)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 FirmwareCtrl;
+ UINT32 Dsdt;
+ UINT8 IntModel;
+ UINT8 Reserved1;
+ UINT16 SciInt;
+ UINT32 SmiCmd;
+ UINT8 AcpiEnable;
+ UINT8 AcpiDisable;
+ UINT8 S4BiosReq;
+ UINT8 Reserved2;
+ UINT32 Pm1aEvtBlk;
+ UINT32 Pm1bEvtBlk;
+ UINT32 Pm1aCntBlk;
+ UINT32 Pm1bCntBlk;
+ UINT32 Pm2CntBlk;
+ UINT32 PmTmrBlk;
+ UINT32 Gpe0Blk;
+ UINT32 Gpe1Blk;
+ UINT8 Pm1EvtLen;
+ UINT8 Pm1CntLen;
+ UINT8 Pm2CntLen;
+ UINT8 PmTmLen;
+ UINT8 Gpe0BlkLen;
+ UINT8 Gpe1BlkLen;
+ UINT8 Gpe1Base;
+ UINT8 Reserved3;
+ UINT16 PLvl2Lat;
+ UINT16 PLvl3Lat;
+ UINT16 FlushSize;
+ UINT16 FlushStride;
+ UINT8 DutyOffset;
+ UINT8 DutyWidth;
+ UINT8 DayAlrm;
+ UINT8 MonAlrm;
+ UINT8 Century;
+ UINT8 Reserved4;
+ UINT8 Reserved5;
+ UINT8 Reserved6;
+ UINT32 Flags;
+} EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE;
+
+//
+// FADT Version (as defined in ACPI 1.0b spec.)
+//
+#define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Fixed ACPI Description Table Fixed Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_1_0_WBINVD (1 << 0)
+#define EFI_ACPI_1_0_WBINVD_FLUSH (1 << 1)
+#define EFI_ACPI_1_0_PROC_C1 (1 << 2)
+#define EFI_ACPI_1_0_P_LVL2_UP (1 << 3)
+#define EFI_ACPI_1_0_PWR_BUTTON (1 << 4)
+#define EFI_ACPI_1_0_SLP_BUTTON (1 << 5)
+#define EFI_ACPI_1_0_FIX_RTC (1 << 6)
+#define EFI_ACPI_1_0_RTC_S4 (1 << 7)
+#define EFI_ACPI_1_0_TMR_VAL_EXT (1 << 8)
+#define EFI_ACPI_1_0_DCK_CAP (1 << 9)
+
+#define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x0
+//
+// Firmware ACPI Control Structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT32 HardwareSignature;
+ UINT32 FirmwareWakingVector;
+ UINT32 GlobalLock;
+ UINT32 Flags;
+ UINT8 Reserved[40];
+} EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
+
+//
+// Firmware Control Structure Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_1_0_S4BIOS_F (1 << 0)
+
+//
+// Multiple APIC Description Table header definition. The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 LocalApicAddress;
+ UINT32 Flags;
+} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
+
+//
+// MADT Revision (as defined in ACPI 1.0b spec.)
+//
+#define EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Multiple APIC Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_1_0_PCAT_COMPAT (1 << 0)
+
+//
+// Multiple APIC Description Table APIC structure types
+// All other values between 0x09 an 0xFF are reserved and
+// will be ignored by OSPM.
+//
+#define EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC 0x00
+#define EFI_ACPI_1_0_IO_APIC 0x01
+#define EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE 0x02
+#define EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03
+#define EFI_ACPI_1_0_LOCAL_APIC_NMI 0x04
+
+//
+// APIC Structure Definitions
+//
+//
+// Processor Local APIC Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 ApicId;
+ UINT32 Flags;
+} EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
+
+//
+// Local APIC Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_1_0_LOCAL_APIC_ENABLED (1 << 0)
+
+//
+// IO APIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 IoApicAddress;
+ UINT32 SystemVectorBase;
+} EFI_ACPI_1_0_IO_APIC_STRUCTURE;
+
+//
+// Interrupt Source Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Bus;
+ UINT8 Source;
+ UINT32 GlobalSystemInterruptVector;
+ UINT16 Flags;
+} EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
+
+//
+// Non-Maskable Interrupt Source Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT32 GlobalSystemInterruptVector;
+} EFI_ACPI_1_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
+
+//
+// Local APIC NMI Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT16 Flags;
+ UINT8 LocalApicInti;
+} EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE;
+
+//
+// Smart Battery Description Table (SBST)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 WarningEnergyLevel;
+ UINT32 LowEnergyLevel;
+ UINT32 CriticalEnergyLevel;
+} EFI_ACPI_1_0_SMART_BATTERY_DESCRIPTION_TABLE;
+
+//
+// Known table signatures
+//
+//
+// "RSD PTR " Root System Description Pointer
+//
+#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352ULL
+
+//
+// "APIC" Multiple APIC Description Table
+//
+#define EFI_ACPI_1_0_APIC_SIGNATURE 0x43495041
+
+//
+// "DSDT" Differentiated System Description Table
+//
+#define EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344
+
+//
+// "FACS" Firmware ACPI Control Structure
+//
+#define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146
+
+//
+// "FACP" Fixed ACPI Description Table
+//
+#define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146
+
+//
+// "PSDT" Persistent System Description Table
+//
+#define EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350
+
+//
+// "RSDT" Root System Description Table
+//
+#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352
+
+//
+// "SBST" Smart Battery Specification Table
+//
+#define EFI_ACPI_1_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253
+
+//
+// "SSDT" Secondary System Description Table
+//
+#define EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353
+
+#pragma pack()
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi2_0.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi2_0.h
new file mode 100644
index 00000000..22ce87f8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi2_0.h
@@ -0,0 +1,520 @@
+/** @file
+ ACPI 2.0 definitions from the ACPI Specification, revision 2.0
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ACPI_2_0_H_
+#define _ACPI_2_0_H_
+
+#include "IndustryStandard/Acpi.h"
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// ACPI Specification Revision
+//
+#define EFI_ACPI_2_0_REVISION 0x02
+
+//
+// BUGBUG: OEM values need to be moved somewhere else, probably read from data hub
+// and produced by a platform specific driver.
+//
+//
+// ACPI OEM ID
+//
+#define EFI_ACPI_2_0_OEM_ID "INTEL "
+#define EFI_ACPI_2_0_OEM_TABLE_ID 0x5034303738543245 // "E2T8704P"
+//
+// ACPI OEM Revision
+//
+#define EFI_ACPI_2_0_OEM_REVISION 0x00000002
+
+//
+// ACPI table creator ID
+//
+#define EFI_ACPI_2_0_CREATOR_ID 0x5446534D // TBD "MSFT"
+//
+// ACPI table creator revision
+//
+#define EFI_ACPI_2_0_CREATOR_REVISION 0x01000013 // TBD
+//
+// ACPI 2.0 Generic Address Space definition
+//
+typedef struct {
+ UINT8 AddressSpaceId;
+ UINT8 RegisterBitWidth;
+ UINT8 RegisterBitOffset;
+ UINT8 Reserved;
+ UINT64 Address;
+} EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE;
+
+//
+// Generic Address Space Address IDs
+//
+#define EFI_ACPI_2_0_SYSTEM_MEMORY 0
+#define EFI_ACPI_2_0_SYSTEM_IO 1
+#define EFI_ACPI_2_0_PCI_CONFIGURATION_SPACE 2
+#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER 3
+#define EFI_ACPI_2_0_SMBUS 4
+#define EFI_ACPI_2_0_FUNCTIONAL_FIXED_HARDWARE 0x7F
+
+//
+// ACPI 2.0 table structures
+//
+//
+// Root System Description Pointer Structure
+//
+typedef struct {
+ UINT64 Signature;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT8 Revision;
+ UINT32 RsdtAddress;
+ UINT32 Length;
+ UINT64 XsdtAddress;
+ UINT8 ExtendedChecksum;
+ UINT8 Reserved[3];
+} EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
+
+//
+// RSD_PTR Revision (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02
+
+//
+// Common table header, this prefaces all ACPI tables, including FACS, but
+// excluding the RSD PTR structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+} EFI_ACPI_2_0_COMMON_HEADER;
+
+//
+// Root System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT32 table pointers.
+//
+//
+// RSDT Revision (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Extended System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT64 table pointers.
+//
+//
+// XSDT Revision (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Fixed ACPI Description Table Structure (FADT)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 FirmwareCtrl;
+ UINT32 Dsdt;
+ UINT8 Reserved0;
+ UINT8 PreferredPmProfile;
+ UINT16 SciInt;
+ UINT32 SmiCmd;
+ UINT8 AcpiEnable;
+ UINT8 AcpiDisable;
+ UINT8 S4BiosReq;
+ UINT8 PstateCnt;
+ UINT32 Pm1aEvtBlk;
+ UINT32 Pm1bEvtBlk;
+ UINT32 Pm1aCntBlk;
+ UINT32 Pm1bCntBlk;
+ UINT32 Pm2CntBlk;
+ UINT32 PmTmrBlk;
+ UINT32 Gpe0Blk;
+ UINT32 Gpe1Blk;
+ UINT8 Pm1EvtLen;
+ UINT8 Pm1CntLen;
+ UINT8 Pm2CntLen;
+ UINT8 PmTmrLen;
+ UINT8 Gpe0BlkLen;
+ UINT8 Gpe1BlkLen;
+ UINT8 Gpe1Base;
+ UINT8 CstCnt;
+ UINT16 PLvl2Lat;
+ UINT16 PLvl3Lat;
+ UINT16 FlushSize;
+ UINT16 FlushStride;
+ UINT8 DutyOffset;
+ UINT8 DutyWidth;
+ UINT8 DayAlrm;
+ UINT8 MonAlrm;
+ UINT8 Century;
+ UINT16 IaPcBootArch;
+ UINT8 Reserved1;
+ UINT32 Flags;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE ResetReg;
+ UINT8 ResetValue;
+ UINT8 Reserved2[3];
+ UINT64 XFirmwareCtrl;
+ UINT64 XDsdt;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk;
+} EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE;
+
+//
+// FADT Version (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x03
+
+//
+// Fixed ACPI Description Table Boot Architecture Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_2_0_LEGACY_DEVICES (1 << 0)
+#define EFI_ACPI_2_0_8042 (1 << 1)
+
+//
+// Fixed ACPI Description Table Fixed Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_2_0_WBINVD (1 << 0)
+#define EFI_ACPI_2_0_WBINVD_FLUSH (1 << 1)
+#define EFI_ACPI_2_0_PROC_C1 (1 << 2)
+#define EFI_ACPI_2_0_P_LVL2_UP (1 << 3)
+#define EFI_ACPI_2_0_PWR_BUTTON (1 << 4)
+#define EFI_ACPI_2_0_SLP_BUTTON (1 << 5)
+#define EFI_ACPI_2_0_FIX_RTC (1 << 6)
+#define EFI_ACPI_2_0_RTC_S4 (1 << 7)
+#define EFI_ACPI_2_0_TMR_VAL_EXT (1 << 8)
+#define EFI_ACPI_2_0_DCK_CAP (1 << 9)
+#define EFI_ACPI_2_0_RESET_REG_SUP (1 << 10)
+#define EFI_ACPI_2_0_SEALED_CASE (1 << 11)
+#define EFI_ACPI_2_0_HEADLESS (1 << 12)
+#define EFI_ACPI_2_0_CPU_SW_SLP (1 << 13)
+
+//
+// Firmware ACPI Control Structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT32 HardwareSignature;
+ UINT32 FirmwareWakingVector;
+ UINT32 GlobalLock;
+ UINT32 Flags;
+ UINT64 XFirmwareWakingVector;
+ UINT8 Version;
+ UINT8 Reserved[31];
+} EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
+
+//
+// FACS Version (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01
+
+//
+// Firmware Control Structure Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_2_0_S4BIOS_F (1 << 0)
+
+//
+// Multiple APIC Description Table header definition. The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 LocalApicAddress;
+ UINT32 Flags;
+} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
+
+//
+// MADT Revision (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Multiple APIC Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_2_0_PCAT_COMPAT (1 << 0)
+
+//
+// Multiple APIC Description Table APIC structure types
+// All other values between 0x09 an 0xFF are reserved and
+// will be ignored by OSPM.
+//
+#define EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC 0x00
+#define EFI_ACPI_2_0_IO_APIC 0x01
+#define EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE 0x02
+#define EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03
+#define EFI_ACPI_2_0_LOCAL_APIC_NMI 0x04
+#define EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05
+#define EFI_ACPI_2_0_IO_SAPIC 0x06
+#define EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC 0x07
+#define EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES 0x08
+
+//
+// APIC Structure Definitions
+//
+//
+// Processor Local APIC Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 ApicId;
+ UINT32 Flags;
+} EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
+
+//
+// Local APIC Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_2_0_LOCAL_APIC_ENABLED (1 << 0)
+
+//
+// IO APIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 IoApicAddress;
+ UINT32 GlobalSystemInterruptBase;
+} EFI_ACPI_2_0_IO_APIC_STRUCTURE;
+
+//
+// Interrupt Source Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Bus;
+ UINT8 Source;
+ UINT32 GlobalSystemInterrupt;
+ UINT16 Flags;
+} EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
+
+//
+// Non-Maskable Interrupt Source Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT32 GlobalSystemInterrupt;
+} EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
+
+//
+// Local APIC NMI Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT16 Flags;
+ UINT8 LocalApicLint;
+} EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE;
+
+//
+// Local APIC Address Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Reserved;
+ UINT64 LocalApicAddress;
+} EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
+
+//
+// IO SAPIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 GlobalSystemInterruptBase;
+ UINT64 IoSapicAddress;
+} EFI_ACPI_2_0_IO_SAPIC_STRUCTURE;
+
+//
+// Local SAPIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 LocalSapicId;
+ UINT8 LocalSapicEid;
+ UINT8 Reserved[3];
+ UINT32 Flags;
+} EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
+
+//
+// Platform Interrupt Sources Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT8 InterruptType;
+ UINT8 ProcessorId;
+ UINT8 ProcessorEid;
+ UINT8 IoSapicVector;
+ UINT32 GlobalSystemInterrupt;
+ UINT32 Reserved;
+} EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
+
+//
+// Smart Battery Description Table (SBST)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 WarningEnergyLevel;
+ UINT32 LowEnergyLevel;
+ UINT32 CriticalEnergyLevel;
+} EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE;
+
+//
+// SBST Version (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Embedded Controller Boot Resources Table (ECDT)
+// The table is followed by a null terminated ASCII string that contains
+// a fully qualified reference to the name space object.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcControl;
+ EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE EcData;
+ UINT32 Uid;
+ UINT8 GpeBit;
+} EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
+
+//
+// ECDT Version (as defined in ACPI 2.0 spec.)
+//
+#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01
+
+//
+// Known table signatures
+//
+//
+// "RSD PTR " Root System Description Pointer
+//
+#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352
+
+//
+// "SPIC" Multiple SAPIC Description Table
+//
+// BUGBUG: Don't know where this came from except SR870BN4 uses it.
+// #define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE 0x43495053
+//
+#define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041
+
+//
+// "BOOT" MS Simple Boot Spec
+//
+#define EFI_ACPI_2_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE 0x544F4F42
+
+//
+// "DBGP" MS Bebug Port Spec
+//
+#define EFI_ACPI_2_0_DEBUG_PORT_TABLE_SIGNATURE 0x50474244
+
+//
+// "DSDT" Differentiated System Description Table
+//
+#define EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344
+
+//
+// "ECDT" Embedded Controller Boot Resources Table
+//
+#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE 0x54444345
+
+//
+// "ETDT" Event Timer Description Table
+//
+#define EFI_ACPI_2_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE 0x54445445
+
+//
+// "FACS" Firmware ACPI Control Structure
+//
+#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146
+
+//
+// "FACP" Fixed ACPI Description Table
+//
+#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146
+
+//
+// "APIC" Multiple APIC Description Table
+//
+#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041
+
+//
+// "PSDT" Persistent System Description Table
+//
+#define EFI_ACPI_2_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350
+
+//
+// "RSDT" Root System Description Table
+//
+#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352
+
+//
+// "SBST" Smart Battery Specification Table
+//
+#define EFI_ACPI_2_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253
+
+//
+// "SLIT" System Locality Information Table
+//
+#define EFI_ACPI_2_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE 0x54494C53
+
+//
+// "SPCR" Serial Port Console Redirection Table
+//
+#define EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE 0x52435053
+
+//
+// "SRAT" Static Resource Affinity Table
+//
+#define EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE 0x54415253
+
+//
+// "SSDT" Secondary System Description Table
+//
+#define EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353
+
+//
+// "SPMI" Server Platform Management Interface Table
+//
+#define EFI_ACPI_2_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_SIGNATURE 0x494D5053
+
+//
+// "XSDT" Extended System Description Table
+//
+#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445358
+
+#pragma pack()
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi3_0.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi3_0.h
new file mode 100644
index 00000000..3fd85f60
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Acpi3_0.h
@@ -0,0 +1,668 @@
+/** @file
+ ACPI 3.0 definitions from the ACPI Specification Revision 3.0 September 2, 2004
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ACPI_3_0_H_
+#define _ACPI_3_0_H_
+
+#include "IndustryStandard/Acpi.h"
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// ACPI Specification Revision
+//
+#define EFI_ACPI_3_0_REVISION 0x03 // BUGBUG: Not in spec yet.
+//
+// BUGBUG: OEM values need to be moved somewhere else, probably read from data hub
+// and produced by a platform specific driver.
+//
+//
+// ACPI 3.0 Generic Address Space definition
+//
+typedef struct {
+ UINT8 AddressSpaceId;
+ UINT8 RegisterBitWidth;
+ UINT8 RegisterBitOffset;
+ UINT8 AccessSize;
+ UINT64 Address;
+} EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE;
+
+//
+// Generic Address Space Address IDs
+//
+#define EFI_ACPI_3_0_SYSTEM_MEMORY 0
+#define EFI_ACPI_3_0_SYSTEM_IO 1
+#define EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE 2
+#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER 3
+#define EFI_ACPI_3_0_SMBUS 4
+#define EFI_ACPI_3_0_FUNCTIONAL_FIXED_HARDWARE 0x7F
+
+//
+// Generic Address Space Access Sizes
+//
+#define EFI_ACPI_3_0_UNDEFINED 0
+#define EFI_ACPI_3_0_BYTE 1
+#define EFI_ACPI_3_0_WORD 2
+#define EFI_ACPI_3_0_DWORD 3
+#define EFI_ACPI_3_0_QWORD 4
+
+//
+// ACPI 3.0 table structures
+//
+//
+// Root System Description Pointer Structure
+//
+typedef struct {
+ UINT64 Signature;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT8 Revision;
+ UINT32 RsdtAddress;
+ UINT32 Length;
+ UINT64 XsdtAddress;
+ UINT8 ExtendedChecksum;
+ UINT8 Reserved[3];
+} EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
+
+//
+// RSD_PTR Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 // ACPISpec30 (Revision 3.0 September 2, 2004) says current value is 2
+//
+// Common table header, this prefaces all ACPI tables, including FACS, but
+// excluding the RSD PTR structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+} EFI_ACPI_3_0_COMMON_HEADER;
+
+//
+// Root System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT32 table pointers.
+//
+//
+// RSDT Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Extended System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT64 table pointers.
+//
+//
+// XSDT Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Fixed ACPI Description Table Structure (FADT)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 FirmwareCtrl;
+ UINT32 Dsdt;
+ UINT8 Reserved0;
+ UINT8 PreferredPmProfile;
+ UINT16 SciInt;
+ UINT32 SmiCmd;
+ UINT8 AcpiEnable;
+ UINT8 AcpiDisable;
+ UINT8 S4BiosReq;
+ UINT8 PstateCnt;
+ UINT32 Pm1aEvtBlk;
+ UINT32 Pm1bEvtBlk;
+ UINT32 Pm1aCntBlk;
+ UINT32 Pm1bCntBlk;
+ UINT32 Pm2CntBlk;
+ UINT32 PmTmrBlk;
+ UINT32 Gpe0Blk;
+ UINT32 Gpe1Blk;
+ UINT8 Pm1EvtLen;
+ UINT8 Pm1CntLen;
+ UINT8 Pm2CntLen;
+ UINT8 PmTmrLen;
+ UINT8 Gpe0BlkLen;
+ UINT8 Gpe1BlkLen;
+ UINT8 Gpe1Base;
+ UINT8 CstCnt;
+ UINT16 PLvl2Lat;
+ UINT16 PLvl3Lat;
+ UINT16 FlushSize;
+ UINT16 FlushStride;
+ UINT8 DutyOffset;
+ UINT8 DutyWidth;
+ UINT8 DayAlrm;
+ UINT8 MonAlrm;
+ UINT8 Century;
+ UINT16 IaPcBootArch;
+ UINT8 Reserved1;
+ UINT32 Flags;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ResetReg;
+ UINT8 ResetValue;
+ UINT8 Reserved2[3];
+ UINT64 XFirmwareCtrl;
+ UINT64 XDsdt;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk;
+} EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE;
+
+//
+// FADT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x04
+
+//
+// Fixed ACPI Description Table Preferred Power Management Profile
+//
+#define EFI_ACPI_3_0_PM_PROFILE_UNSPECIFIED 0
+#define EFI_ACPI_3_0_PM_PROFILE_DESKTOP 1
+#define EFI_ACPI_3_0_PM_PROFILE_MOBILE 2
+#define EFI_ACPI_3_0_PM_PROFILE_WORKSTATION 3
+#define EFI_ACPI_3_0_PM_PROFILE_ENTERPRISE_SERVER 4
+#define EFI_ACPI_3_0_PM_PROFILE_SOHO_SERVER 5
+#define EFI_ACPI_3_0_PM_PROFILE_APPLIANCE_PC 6
+#define EFI_ACPI_3_0_PM_PROFILE_PERFORMANCE_SERVER 7
+
+//
+// Fixed ACPI Description Table Boot Architecture Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_LEGACY_DEVICES (1 << 0)
+#define EFI_ACPI_3_0_8042 (1 << 1)
+#define EFI_ACPI_3_0_VGA_NOT_PRESENT (1 << 2)
+#define EFI_ACPI_3_0_MSI_NOT_SUPPORTED (1 << 3)
+//
+// Fixed ACPI Description Table Fixed Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_WBINVD (1 << 0)
+#define EFI_ACPI_3_0_WBINVD_FLUSH (1 << 1)
+#define EFI_ACPI_3_0_PROC_C1 (1 << 2)
+#define EFI_ACPI_3_0_P_LVL2_UP (1 << 3)
+#define EFI_ACPI_3_0_PWR_BUTTON (1 << 4)
+#define EFI_ACPI_3_0_SLP_BUTTON (1 << 5)
+#define EFI_ACPI_3_0_FIX_RTC (1 << 6)
+#define EFI_ACPI_3_0_RTC_S4 (1 << 7)
+#define EFI_ACPI_3_0_TMR_VAL_EXT (1 << 8)
+#define EFI_ACPI_3_0_DCK_CAP (1 << 9)
+#define EFI_ACPI_3_0_RESET_REG_SUP (1 << 10)
+#define EFI_ACPI_3_0_SEALED_CASE (1 << 11)
+#define EFI_ACPI_3_0_HEADLESS (1 << 12)
+#define EFI_ACPI_3_0_CPU_SW_SLP (1 << 13)
+#define EFI_ACPI_3_0_PCI_EXP_WAK (1 << 14)
+#define EFI_ACPI_3_0_USE_PLATFORM_CLOCK (1 << 15)
+#define EFI_ACPI_3_0_S4_RTC_STS_VALID (1 << 16)
+#define EFI_ACPI_3_0_REMOTE_POWER_ON_CAPABLE (1 << 17)
+#define EFI_ACPI_3_0_FORCE_APIC_CLUSTER_MODEL (1 << 18)
+#define EFI_ACPI_3_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE (1 << 19)
+
+//
+// Firmware ACPI Control Structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT32 HardwareSignature;
+ UINT32 FirmwareWakingVector;
+ UINT32 GlobalLock;
+ UINT32 Flags;
+ UINT64 XFirmwareWakingVector;
+ UINT8 Version;
+ UINT8 Reserved[31];
+} EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
+
+//
+// FACS Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01
+
+//
+// Firmware Control Structure Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_S4BIOS_F (1 << 0)
+
+//
+// Differentiated System Description Table,
+// Secondary System Description Table
+// and Persistent System Description Table,
+// no definition needed as they are common description table header followed by a
+// definition block.
+//
+#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02
+#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02
+
+//
+// Multiple APIC Description Table header definition. The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 LocalApicAddress;
+ UINT32 Flags;
+} EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
+
+//
+// MADT Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x02
+
+//
+// Multiple APIC Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_PCAT_COMPAT (1 << 0)
+
+//
+// Multiple APIC Description Table APIC structure types
+// All other values between 0x09 an 0xFF are reserved and
+// will be ignored by OSPM.
+//
+#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC 0x00
+#define EFI_ACPI_3_0_IO_APIC 0x01
+#define EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE 0x02
+#define EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03
+#define EFI_ACPI_3_0_LOCAL_APIC_NMI 0x04
+#define EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05
+#define EFI_ACPI_3_0_IO_SAPIC 0x06
+#define EFI_ACPI_3_0_LOCAL_SAPIC 0x07
+#define EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES 0x08
+
+//
+// APIC Structure Definitions
+//
+//
+// Processor Local APIC Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 ApicId;
+ UINT32 Flags;
+} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
+
+//
+// Local APIC Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_3_0_LOCAL_APIC_ENABLED (1 << 0)
+
+//
+// IO APIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 IoApicAddress;
+ UINT32 GlobalSystemInterruptBase;
+} EFI_ACPI_3_0_IO_APIC_STRUCTURE;
+
+//
+// Interrupt Source Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Bus;
+ UINT8 Source;
+ UINT32 GlobalSystemInterrupt;
+ UINT16 Flags;
+} EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
+
+//
+// Platform Interrupt Sources Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT8 InterruptType;
+ UINT8 ProcessorId;
+ UINT8 ProcessorEid;
+ UINT8 IoSapicVector;
+ UINT32 GlobalSystemInterrupt;
+ UINT32 PlatformInterruptSourceFlags;
+ UINT8 CpeiProcessorOverride;
+ UINT8 Reserved[31];
+} EFI_ACPI_3_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
+
+//
+// MPS INTI flags.
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_POLARITY (3 << 0)
+#define EFI_ACPI_3_0_TRIGGER_MODE (3 << 2)
+
+//
+// Non-Maskable Interrupt Source Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT32 GlobalSystemInterrupt;
+} EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
+
+//
+// Local APIC NMI Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT16 Flags;
+ UINT8 LocalApicLint;
+} EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE;
+
+//
+// Local APIC Address Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Reserved;
+ UINT64 LocalApicAddress;
+} EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
+
+//
+// IO SAPIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 GlobalSystemInterruptBase;
+ UINT64 IoSapicAddress;
+} EFI_ACPI_3_0_IO_SAPIC_STRUCTURE;
+
+//
+// Local SAPIC Structure
+// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 LocalSapicId;
+ UINT8 LocalSapicEid;
+ UINT8 Reserved[3];
+ UINT32 Flags;
+ UINT32 ACPIProcessorUIDValue;
+} EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
+
+//
+// Platform Interrupt Sources Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT8 InterruptType;
+ UINT8 ProcessorId;
+ UINT8 ProcessorEid;
+ UINT8 IoSapicVector;
+ UINT32 GlobalSystemInterrupt;
+ UINT32 PlatformInterruptSourceFlags;
+} EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
+
+//
+// Platform Interrupt Source Flags.
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_CPEI_PROCESSOR_OVERRIDE (1 << 0)
+
+//
+// Smart Battery Description Table (SBST)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 WarningEnergyLevel;
+ UINT32 LowEnergyLevel;
+ UINT32 CriticalEnergyLevel;
+} EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE;
+
+//
+// SBST Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Embedded Controller Boot Resources Table (ECDT)
+// The table is followed by a null terminated ASCII string that contains
+// a fully qualified reference to the name space object.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcControl;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcData;
+ UINT32 Uid;
+ UINT8 GpeBit;
+} EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
+
+//
+// ECDT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01
+
+//
+// System Resource Affinity Table (SRAT. The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 Reserved1; // Must be set to 1
+ UINT64 Reserved2;
+} EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
+
+//
+// SRAT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x02
+
+//
+// SRAT structure types.
+// All other values between 0x02 an 0xFF are reserved and
+// will be ignored by OSPM.
+//
+#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00
+#define EFI_ACPI_3_0_MEMORY_AFFINITY 0x01
+
+//
+// Processor Local APIC/SAPIC Affinity Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 ProximityDomain7To0;
+ UINT8 ApicId;
+ UINT32 Flags;
+ UINT8 LocalSapicEid;
+ UINT8 ProximityDomain31To8[3];
+ UINT8 Reserved[4];
+} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
+
+//
+// Local APIC/SAPIC Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
+
+//
+// Memory Affinity Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT32 ProximityDomain;
+ UINT16 Reserved1;
+ UINT32 AddressBaseLow;
+ UINT32 AddressBaseHigh;
+ UINT32 LengthLow;
+ UINT32 LengthHigh;
+ UINT32 Reserved2;
+ UINT32 Flags;
+ UINT64 Reserved3;
+} EFI_ACPI_3_0_MEMORY_AFFINITY_STRUCTURE;
+
+//
+// Memory Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_3_0_MEMORY_ENABLED (1 << 0)
+#define EFI_ACPI_3_0_MEMORY_HOT_PLUGGABLE (1 << 1)
+#define EFI_ACPI_3_0_MEMORY_NONVOLATILE (1 << 2)
+
+//
+// System Locality Distance Information Table (SLIT).
+// The rest of the table is a matrix.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT64 NumberOfSystemLocalities;
+} EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
+
+//
+// SLIT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01
+
+//
+// Known table signatures
+//
+//
+// "RSD PTR " Root System Description Pointer
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352ULL
+
+//
+// "APIC" Multiple APIC Description Table
+//
+#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041
+
+//
+// "DSDT" Differentiated System Description Table
+//
+#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344
+
+//
+// "ECDT" Embedded Controller Boot Resources Table
+//
+#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE 0x54444345
+
+//
+// "FACP" Fixed ACPI Description Table
+//
+#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146
+
+//
+// "FACS" Firmware ACPI Control Structure
+//
+#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146
+
+//
+// "PSDT" Persistent System Description Table
+//
+#define EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350
+
+//
+// "RSDT" Root System Description Table
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352
+
+//
+// "SBST" Smart Battery Specification Table
+//
+#define EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253
+
+//
+// "SLIT" System Locality Information Table
+//
+#define EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE 0x54494C53
+
+//
+// "SRAT" System Resource Affinity Table
+//
+#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE 0x54415253
+
+//
+// "SSDT" Secondary System Description Table
+//
+#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353
+
+//
+// "XSDT" Extended System Description Table
+//
+#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445358
+
+//
+// "BOOT" MS Simple Boot Spec
+//
+#define EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE 0x544F4F42
+
+//
+// "CPEP" Corrected Platform Error Polling Table
+// See
+//
+#define EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE 0x50455043
+
+//
+// "DBGP" MS Debug Port Spec
+//
+#define EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE 0x50474244
+
+//
+// "ETDT" Event Timer Description Table
+//
+#define EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE 0x54445445
+
+//
+// "HPET" IA-PC High Precision Event Timer Table
+//
+#define EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE 0x54455048
+
+//
+// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
+//
+#define EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE 0x4746434D
+
+//
+// "SPCR" Serial Port Console Redirection Table
+//
+#define EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE 0x52435053
+
+//
+// "SPMI" Server Platform Management Interface Table
+//
+#define EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE 0x494D5053
+
+//
+// "TCPA" Trusted Computing Platform Alliance Capabilities Table
+//
+#define EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE 0x41504354
+
+//
+// "WDRT" Watchdog Resource Table
+//
+#define EFI_ACPI_3_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE 0x54524457
+
+#pragma pack()
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h
new file mode 100644
index 00000000..0e8c5227
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/Bluetooth.h
@@ -0,0 +1,56 @@
+/** @file
+ This file contains the Bluetooth definitions that are consumed by drivers.
+ These definitions are from Bluetooth Core Specification Version 4.0 June, 2010
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _BLUETOOTH_H_
+#define _BLUETOOTH_H_
+
+#pragma pack(1)
+
+///
+/// BLUETOOTH_ADDRESS
+///
+typedef struct {
+ ///
+ /// 48bit Bluetooth device address.
+ ///
+ UINT8 Address[6];
+} BLUETOOTH_ADDRESS;
+
+///
+/// BLUETOOTH_CLASS_OF_DEVICE. See Bluetooth specification for detail.
+///
+typedef struct {
+ UINT8 FormatType:2;
+ UINT8 MinorDeviceClass: 6;
+ UINT16 MajorDeviceClass: 5;
+ UINT16 MajorServiceClass:11;
+} BLUETOOTH_CLASS_OF_DEVICE;
+
+///
+/// BLUETOOTH_LE_ADDRESS
+///
+typedef struct {
+ ///
+ /// 48-bit Bluetooth device address
+ ///
+ UINT8 Address[6];
+ ///
+ /// 0x00 - Public Device Address
+ /// 0x01 - Random Device Address
+ ///
+ UINT8 Type;
+} BLUETOOTH_LE_ADDRESS;
+
+#pragma pack()
+
+#define BLUETOOTH_HCI_COMMAND_LOCAL_READABLE_NAME_MAX_SIZE 248
+
+#define BLUETOOTH_HCI_LINK_KEY_SIZE 16
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/EfiPci.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/EfiPci.h
new file mode 100644
index 00000000..27fa8bd4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/EfiPci.h
@@ -0,0 +1,51 @@
+/** @file
+ Support for EFI PCI specification.
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_PCI_H_
+#define _EFI_PCI_H_
+
+//#include "pci22.h"
+//#include "pci23.h"
+//#include "pci30.h"
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 Register;
+ UINT8 Function;
+ UINT8 Device;
+ UINT8 Bus;
+ UINT8 Reserved[4];
+} DEFIO_PCI_ADDR;
+
+#define EFI_ROOT_BRIDGE_LIST 'eprb'
+#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1
+
+typedef struct {
+ UINT16 Signature; // 0xaa55
+ UINT16 InitializationSize;
+ UINT32 EfiSignature; // 0x0EF1
+ UINT16 EfiSubsystem;
+ UINT16 EfiMachineType;
+ UINT16 CompressionType;
+ UINT8 Reserved[8];
+ UINT16 EfiImageHeaderOffset;
+ UINT16 PcirOffset;
+} EFI_PCI_EXPANSION_ROM_HEADER;
+
+typedef union {
+ UINT8 *Raw;
+ PCI_EXPANSION_ROM_HEADER *Generic;
+ EFI_PCI_EXPANSION_ROM_HEADER *Efi;
+ EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt;
+} EFI_PCI_ROM_HEADER;
+
+#pragma pack(pop)
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h
new file mode 100644
index 00000000..5b90a229
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h
@@ -0,0 +1,39 @@
+/** @file
+ ACPI memory mapped configuration space access table definition, defined at
+ in the PCI Firmware Specification, version 3.0 draft version 0.5.
+ Specification is available at http://www.pcisig.com.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_H_
+#define _MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_H_
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// Memory Mapped Configuration Space Access Table (MCFG)
+// This table is a basic description table header followed by
+// a number of base address allocation structures.
+//
+typedef struct {
+ UINT64 BaseAddress;
+ UINT16 PciSegmentGroupNumber;
+ UINT8 StartBusNumber;
+ UINT8 EndBusNumber;
+ UINT32 Reserved;
+} EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE;
+
+//
+// MCFG Revision (defined in spec)
+//
+#define EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION 0x01
+
+#pragma pack()
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/PeImage.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
new file mode 100644
index 00000000..36039220
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
@@ -0,0 +1,768 @@
+/** @file
+ EFI image format for PE32+. Please note some data structures are different
+ for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64
+
+ @bug Fix text - doc as defined in MSFT EFI specification.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PE_IMAGE_H__
+#define __PE_IMAGE_H__
+
+//
+// PE32+ Subsystem type for EFI images
+//
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13
+
+//
+// BugBug: Need to get a real answer for this problem. This is not in the
+// PE specification.
+//
+// A SAL runtime driver does not get fixed up when a transition to
+// virtual mode is made. In all other cases it should be treated
+// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image
+//
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13
+
+//
+// PE32+ Machine type for EFI images
+//
+#define IMAGE_FILE_MACHINE_I386 0x014c
+#define IMAGE_FILE_MACHINE_EBC 0x0EBC
+#define IMAGE_FILE_MACHINE_X64 0x8664
+#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only
+#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian
+#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA
+
+//
+// Support old names for backward compatible
+//
+#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386
+#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC
+#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64
+#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT
+#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64
+#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64
+
+#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE
+#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE
+#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
+
+///
+/// PE images can start with an optional DOS header, so if an image is run
+/// under DOS it can print an error message.
+///
+typedef struct {
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+} EFI_IMAGE_DOS_HEADER;
+
+///
+/// File header format.
+///
+typedef struct {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} EFI_IMAGE_FILE_HEADER;
+
+#define EFI_IMAGE_SIZEOF_FILE_HEADER 20
+
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
+#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // Supports addresses > 2-GB
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
+#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File.
+#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0
+#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
+#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian
+#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian
+#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP*
+#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian
+#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
+//
+// * Other names and brands may be claimed as the property of others.
+//
+
+///
+/// Directory format.
+///
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} EFI_IMAGE_DATA_DIRECTORY;
+
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
+
+typedef struct {
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ UINT32 BaseOfBss;
+ UINT32 GprMask;
+ UINT32 CprMask[4];
+ UINT32 GpValue;
+} EFI_IMAGE_ROM_OPTIONAL_HEADER;
+
+#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)
+
+typedef struct {
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} EFI_IMAGE_ROM_HEADERS;
+
+///
+/// @attention
+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+/// are for use ONLY by tools. All proper EFI code MUST use
+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+///
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ //
+ // NT additional fields.
+ //
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER32;
+
+///
+/// @attention
+/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+/// are for use ONLY by tools. All proper EFI code MUST use
+/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+///
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ //
+ // NT additional fields.
+ //
+ UINT64 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT64 SizeOfStackReserve;
+ UINT64 SizeOfStackCommit;
+ UINT64 SizeOfHeapReserve;
+ UINT64 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER64;
+
+///
+/// @attention
+/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY
+/// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!
+///
+typedef struct {
+ UINT32 Signature;
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS32;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)
+
+typedef struct {
+ UINT32 Signature;
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS64;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)
+
+//
+// Subsystem Values
+//
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0
+#define EFI_IMAGE_SUBSYSTEM_NATIVE 1
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7
+
+//
+// Directory Entries
+//
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+
+//
+// Section header format.
+//
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct {
+ UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} EFI_IMAGE_SECTION_HEADER;
+
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
+#define EFI_IMAGE_SCN_CNT_CODE 0x00000020
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+
+#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
+#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
+#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
+#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000
+
+#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000
+
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000
+#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define EFI_IMAGE_SCN_MEM_READ 0x40000000
+#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000
+
+///
+/// Symbol format.
+///
+#define EFI_IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common.
+#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value.
+#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item.
+//
+// Type (fundamental) values.
+//
+#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type.
+#define EFI_IMAGE_SYM_TYPE_VOID 1 //
+#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character.
+#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer.
+#define EFI_IMAGE_SYM_TYPE_INT 4
+#define EFI_IMAGE_SYM_TYPE_LONG 5
+#define EFI_IMAGE_SYM_TYPE_FLOAT 6
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8
+#define EFI_IMAGE_SYM_TYPE_UNION 9
+#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration.
+#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
+#define EFI_IMAGE_SYM_TYPE_BYTE 12
+#define EFI_IMAGE_SYM_TYPE_WORD 13
+#define EFI_IMAGE_SYM_TYPE_UINT 14
+#define EFI_IMAGE_SYM_TYPE_DWORD 15
+
+//
+// Type (derived) values.
+//
+#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type.
+#define EFI_IMAGE_SYM_DTYPE_POINTER 1
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2
+#define EFI_IMAGE_SYM_DTYPE_ARRAY 3
+
+//
+// Storage classes.
+//
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1
+#define EFI_IMAGE_SYM_CLASS_NULL 0
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2
+#define EFI_IMAGE_SYM_CLASS_STATIC 3
+#define EFI_IMAGE_SYM_CLASS_REGISTER 4
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define EFI_IMAGE_SYM_CLASS_LABEL 6
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18
+#define EFI_IMAGE_SYM_CLASS_BLOCK 100
+#define EFI_IMAGE_SYM_CLASS_FUNCTION 101
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define EFI_IMAGE_SYM_CLASS_FILE 103
+#define EFI_IMAGE_SYM_CLASS_SECTION 104
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+
+//
+// type packing constants
+//
+#define EFI_IMAGE_N_BTMASK 017
+#define EFI_IMAGE_N_TMASK 060
+#define EFI_IMAGE_N_TMASK1 0300
+#define EFI_IMAGE_N_TMASK2 0360
+#define EFI_IMAGE_N_BTSHFT 4
+#define EFI_IMAGE_N_TSHIFT 2
+
+//
+// Communal selection types.
+//
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define EFI_IMAGE_COMDAT_SELECT_ANY 2
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+///
+/// Relocation format.
+///
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 SymbolTableIndex;
+ UINT16 Type;
+} EFI_IMAGE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
+#define EFI_IMAGE_REL_I386_SEG12 09 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define EFI_IMAGE_REL_I386_SECTION 010
+#define EFI_IMAGE_REL_I386_SECREL 011
+#define EFI_IMAGE_REL_I386_REL32 020 // PC-relative 32-bit reference to the symbols virtual address
+
+//
+// x64 processor relocation types.
+//
+#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
+#define IMAGE_REL_AMD64_ADDR64 0x0001
+#define IMAGE_REL_AMD64_ADDR32 0x0002
+#define IMAGE_REL_AMD64_ADDR32NB 0x0003
+#define IMAGE_REL_AMD64_REL32 0x0004
+#define IMAGE_REL_AMD64_REL32_1 0x0005
+#define IMAGE_REL_AMD64_REL32_2 0x0006
+#define IMAGE_REL_AMD64_REL32_3 0x0007
+#define IMAGE_REL_AMD64_REL32_4 0x0008
+#define IMAGE_REL_AMD64_REL32_5 0x0009
+#define IMAGE_REL_AMD64_SECTION 0x000A
+#define IMAGE_REL_AMD64_SECREL 0x000B
+#define IMAGE_REL_AMD64_SECREL7 0x000C
+#define IMAGE_REL_AMD64_TOKEN 0x000D
+#define IMAGE_REL_AMD64_SREL32 0x000E
+#define IMAGE_REL_AMD64_PAIR 0x000F
+#define IMAGE_REL_AMD64_SSPAN32 0x0010
+
+///
+/// Based relocation format.
+///
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 SizeOfBlock;
+} EFI_IMAGE_BASE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8
+
+//
+// Based relocation types.
+//
+#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
+#define EFI_IMAGE_REL_BASED_HIGH 1
+#define EFI_IMAGE_REL_BASED_LOW 2
+#define EFI_IMAGE_REL_BASED_HIGHLOW 3
+#define EFI_IMAGE_REL_BASED_HIGHADJ 4
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
+#define EFI_IMAGE_REL_BASED_RISCV_HI20 5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8
+#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
+#define EFI_IMAGE_REL_BASED_DIR64 10
+
+
+///
+/// Line number format.
+///
+typedef struct {
+ union {
+ UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+ UINT32 VirtualAddress; // Virtual address of line number.
+ } Type;
+ UINT16 Linenumber; // Line number.
+} EFI_IMAGE_LINENUMBER;
+
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+#define EFI_IMAGE_ARCHIVE_START_SIZE 8
+#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"
+#define EFI_IMAGE_ARCHIVE_END "`\n"
+#define EFI_IMAGE_ARCHIVE_PAD "\n"
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct {
+ UINT8 Name[16]; // File member name - `/' terminated.
+ UINT8 Date[12]; // File member date - decimal.
+ UINT8 UserID[6]; // File member user id - decimal.
+ UINT8 GroupID[6]; // File member group id - decimal.
+ UINT8 Mode[8]; // File member mode - octal.
+ UINT8 Size[10]; // File member size - decimal.
+ UINT8 EndHeader[2]; // String to end header.
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+
+///
+/// DLL Export Format
+///
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Name;
+ UINT32 Base;
+ UINT32 NumberOfFunctions;
+ UINT32 NumberOfNames;
+ UINT32 AddressOfFunctions;
+ UINT32 AddressOfNames;
+ UINT32 AddressOfNameOrdinals;
+} EFI_IMAGE_EXPORT_DIRECTORY;
+
+///
+/// DLL support.
+/// Import Format
+///
+typedef struct {
+ UINT16 Hint;
+ UINT8 Name[1];
+} EFI_IMAGE_IMPORT_BY_NAME;
+
+typedef struct {
+ union {
+ UINT32 Function;
+ UINT32 Ordinal;
+ EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;
+ } u1;
+} EFI_IMAGE_THUNK_DATA;
+
+#define EFI_IMAGE_ORDINAL_FLAG 0x80000000
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
+#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT32 ForwarderChain;
+ UINT32 Name;
+ EFI_IMAGE_THUNK_DATA *FirstThunk;
+} EFI_IMAGE_IMPORT_DESCRIPTOR;
+
+///
+/// Debug Format
+///
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Type;
+ UINT32 SizeOfData;
+ UINT32 RVA;
+ UINT32 FileOffset;
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
+
+#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"
+typedef struct {
+ UINT32 Signature; // "NB10"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
+
+#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS"
+typedef struct {
+ UINT32 Signature; // "RSDS"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ UINT32 Unknown4;
+ UINT32 Unknown5;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
+
+///
+/// Debug Data Structure defined by Apple Mach-O to Coff utility
+///
+#define CODEVIEW_SIGNATURE_MTOC SIGNATURE_32('M', 'T', 'O', 'C')
+typedef struct {
+ UINT32 Signature; ///< "MTOC"
+ EFI_GUID MachOUuid;
+ //
+ // Filename of .DLL (Mach-O with debug info) goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
+
+//
+// .pdata entries for X64
+//
+#if defined(VBOX) && !defined(_SKIP_DEFINE_RUNTIME_FUNCTION)
+typedef struct {
+ UINT32 FunctionStartAddress;
+ UINT32 FunctionEndAddress;
+ UINT32 UnwindInfoAddress;
+} RUNTIME_FUNCTION;
+#endif
+
+typedef struct {
+ UINT8 Version:3;
+ UINT8 Flags:5;
+ UINT8 SizeOfProlog;
+ UINT8 CountOfUnwindCodes;
+ UINT8 FrameRegister:4;
+ UINT8 FrameRegisterOffset:4;
+} UNWIND_INFO;
+
+///
+/// Resource format.
+///
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT16 NumberOfNamedEntries;
+ UINT16 NumberOfIdEntries;
+ //
+ // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here.
+ //
+} EFI_IMAGE_RESOURCE_DIRECTORY;
+
+///
+/// Resource directory entry format.
+///
+typedef struct {
+ union {
+ struct {
+ UINT32 NameOffset:31;
+ UINT32 NameIsString:1;
+ } s;
+ UINT32 Id;
+ } u1;
+ union {
+ UINT32 OffsetToData;
+ struct {
+ UINT32 OffsetToDirectory:31;
+ UINT32 DataIsDirectory:1;
+ } s;
+ } u2;
+} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+///
+/// Resource directory entry for string.
+///
+typedef struct {
+ UINT16 Length;
+ CHAR16 String[1];
+} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
+
+///
+/// Resource directory entry for data array.
+///
+typedef struct {
+ UINT32 OffsetToData;
+ UINT32 Size;
+ UINT32 CodePage;
+ UINT32 Reserved;
+} EFI_IMAGE_RESOURCE_DATA_ENTRY;
+
+///
+/// Header format for TE images
+///
+typedef struct {
+ UINT16 Signature; // signature for TE format = "VZ"
+ UINT16 Machine; // from the original file header
+ UINT8 NumberOfSections; // from the original file header
+ UINT8 Subsystem; // from original optional header
+ UINT16 StrippedSize; // how many bytes we removed from the header
+ UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header
+ UINT32 BaseOfCode; // from original image -- required for ITP debug
+ UINT64 ImageBase; // from original file header
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory
+} EFI_TE_IMAGE_HEADER;
+
+#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ"
+
+//
+// Data directory indexes in our TE image header
+//
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1
+
+
+//
+// Union of PE32, PE32+, and TE headers
+//
+typedef union {
+ EFI_IMAGE_NT_HEADERS32 Pe32;
+ EFI_IMAGE_NT_HEADERS64 Pe32Plus;
+ EFI_TE_IMAGE_HEADER Te;
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;
+
+typedef union {
+ EFI_IMAGE_NT_HEADERS32 *Pe32;
+ EFI_IMAGE_NT_HEADERS64 *Pe32Plus;
+ EFI_TE_IMAGE_HEADER *Te;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *Union;
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci22.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci22.h
new file mode 100644
index 00000000..616bc473
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci22.h
@@ -0,0 +1,536 @@
+/** @file
+ Support for PCI 2.2 standard.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCI22_H
+#define _PCI22_H
+
+#define PCI_MAX_SEGMENT 0
+
+#define PCI_MAX_BUS 255
+
+#define PCI_MAX_DEVICE 31
+#define PCI_MAX_FUNC 7
+
+//
+// Command
+//
+#define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20
+
+#pragma pack(push, 1)
+typedef struct {
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 Command;
+ UINT16 Status;
+ UINT8 RevisionID;
+ UINT8 ClassCode[3];
+ UINT8 CacheLineSize;
+ UINT8 LatencyTimer;
+ UINT8 HeaderType;
+ UINT8 BIST;
+} PCI_DEVICE_INDEPENDENT_REGION;
+
+typedef struct {
+ UINT32 Bar[6];
+ UINT32 CISPtr;
+ UINT16 SubsystemVendorID;
+ UINT16 SubsystemID;
+ UINT32 ExpansionRomBar;
+ UINT8 CapabilityPtr;
+ UINT8 Reserved1[3];
+ UINT32 Reserved2;
+ UINT8 InterruptLine;
+ UINT8 InterruptPin;
+ UINT8 MinGnt;
+ UINT8 MaxLat;
+} PCI_DEVICE_HEADER_TYPE_REGION;
+
+typedef struct {
+ PCI_DEVICE_INDEPENDENT_REGION Hdr;
+ PCI_DEVICE_HEADER_TYPE_REGION Device;
+} PCI_TYPE00;
+
+typedef struct {
+ UINT32 Bar[2];
+ UINT8 PrimaryBus;
+ UINT8 SecondaryBus;
+ UINT8 SubordinateBus;
+ UINT8 SecondaryLatencyTimer;
+ UINT8 IoBase;
+ UINT8 IoLimit;
+ UINT16 SecondaryStatus;
+ UINT16 MemoryBase;
+ UINT16 MemoryLimit;
+ UINT16 PrefetchableMemoryBase;
+ UINT16 PrefetchableMemoryLimit;
+ UINT32 PrefetchableBaseUpper32;
+ UINT32 PrefetchableLimitUpper32;
+ UINT16 IoBaseUpper16;
+ UINT16 IoLimitUpper16;
+ UINT8 CapabilityPtr;
+ UINT8 Reserved[3];
+ UINT32 ExpansionRomBAR;
+ UINT8 InterruptLine;
+ UINT8 InterruptPin;
+ UINT16 BridgeControl;
+} PCI_BRIDGE_CONTROL_REGISTER;
+
+typedef struct {
+ PCI_DEVICE_INDEPENDENT_REGION Hdr;
+ PCI_BRIDGE_CONTROL_REGISTER Bridge;
+} PCI_TYPE01;
+
+typedef union {
+ PCI_TYPE00 Device;
+ PCI_TYPE01 Bridge;
+} PCI_TYPE_GENERIC;
+
+typedef struct {
+ UINT32 CardBusSocketReg; // Cardbus Socket/ExCA Base
+ // Address Register
+ //
+ UINT16 Reserved;
+ UINT16 SecondaryStatus; // Secondary Status
+ UINT8 PciBusNumber; // PCI Bus Number
+ UINT8 CardBusBusNumber; // CardBus Bus Number
+ UINT8 SubordinateBusNumber; // Subordinate Bus Number
+ UINT8 CardBusLatencyTimer; // CardBus Latency Timer
+ UINT32 MemoryBase0; // Memory Base Register 0
+ UINT32 MemoryLimit0; // Memory Limit Register 0
+ UINT32 MemoryBase1;
+ UINT32 MemoryLimit1;
+ UINT32 IoBase0;
+ UINT32 IoLimit0; // I/O Base Register 0
+ UINT32 IoBase1; // I/O Limit Register 0
+ UINT32 IoLimit1;
+ UINT8 InterruptLine; // Interrupt Line
+ UINT8 InterruptPin; // Interrupt Pin
+ UINT16 BridgeControl; // Bridge Control
+} PCI_CARDBUS_CONTROL_REGISTER;
+
+//
+// Definitions of PCI class bytes and manipulation macros.
+//
+#define PCI_CLASS_OLD 0x00
+#define PCI_CLASS_OLD_OTHER 0x00
+#define PCI_CLASS_OLD_VGA 0x01
+
+#define PCI_CLASS_MASS_STORAGE 0x01
+#define PCI_CLASS_MASS_STORAGE_SCSI 0x00
+#define PCI_CLASS_MASS_STORAGE_IDE 0x01 // obsolete
+#define PCI_CLASS_IDE 0x01
+#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02
+#define PCI_CLASS_MASS_STORAGE_IPI 0x03
+#define PCI_CLASS_MASS_STORAGE_RAID 0x04
+#define PCI_CLASS_MASS_STORAGE_OTHER 0x80
+
+#define PCI_CLASS_NETWORK 0x02
+#define PCI_CLASS_NETWORK_ETHERNET 0x00
+#define PCI_CLASS_ETHERNET 0x00 // obsolete
+#define PCI_CLASS_NETWORK_TOKENRING 0x01
+#define PCI_CLASS_NETWORK_FDDI 0x02
+#define PCI_CLASS_NETWORK_ATM 0x03
+#define PCI_CLASS_NETWORK_ISDN 0x04
+#define PCI_CLASS_NETWORK_OTHER 0x80
+
+#define PCI_CLASS_DISPLAY 0x03
+#define PCI_CLASS_DISPLAY_CTRL 0x03 // obsolete
+#define PCI_CLASS_DISPLAY_VGA 0x00
+#define PCI_CLASS_VGA 0x00 // obsolete
+#define PCI_CLASS_DISPLAY_XGA 0x01
+#define PCI_CLASS_DISPLAY_3D 0x02
+#define PCI_CLASS_DISPLAY_OTHER 0x80
+#define PCI_CLASS_DISPLAY_GFX 0x80
+#define PCI_CLASS_GFX 0x80 // obsolete
+#define PCI_CLASS_BRIDGE 0x06
+#define PCI_CLASS_BRIDGE_HOST 0x00
+#define PCI_CLASS_BRIDGE_ISA 0x01
+#define PCI_CLASS_ISA 0x01 // obsolete
+#define PCI_CLASS_BRIDGE_EISA 0x02
+#define PCI_CLASS_BRIDGE_MCA 0x03
+#define PCI_CLASS_BRIDGE_P2P 0x04
+#define PCI_CLASS_BRIDGE_PCMCIA 0x05
+#define PCI_CLASS_BRIDGE_NUBUS 0x06
+#define PCI_CLASS_BRIDGE_CARDBUS 0x07
+#define PCI_CLASS_BRIDGE_RACEWAY 0x08
+#define PCI_CLASS_BRIDGE_ISA_PDECODE 0x80
+#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80 // obsolete
+
+#define PCI_CLASS_SCC 0x07 // Simple communications controllers
+#define PCI_SUBCLASS_SERIAL 0x00
+#define PCI_IF_GENERIC_XT 0x00
+#define PCI_IF_16450 0x01
+#define PCI_IF_16550 0x02
+#define PCI_IF_16650 0x03
+#define PCI_IF_16750 0x04
+#define PCI_IF_16850 0x05
+#define PCI_IF_16950 0x06
+#define PCI_SUBCLASS_PARALLEL 0x01
+#define PCI_IF_PARALLEL_PORT 0x00
+#define PCI_IF_BI_DIR_PARALLEL_PORT 0x01
+#define PCI_IF_ECP_PARALLEL_PORT 0x02
+#define PCI_IF_1284_CONTROLLER 0x03
+#define PCI_IF_1284_DEVICE 0xFE
+#define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02
+#define PCI_SUBCLASS_MODEM 0x03
+#define PCI_IF_GENERIC_MODEM 0x00
+#define PCI_IF_16450_MODEM 0x01
+#define PCI_IF_16550_MODEM 0x02
+#define PCI_IF_16650_MODEM 0x03
+#define PCI_IF_16750_MODEM 0x04
+#define PCI_SUBCLASS_OTHER 0x80
+
+#define PCI_CLASS_SYSTEM_PERIPHERAL 0x08
+#define PCI_SUBCLASS_PIC 0x00
+#define PCI_IF_8259_PIC 0x00
+#define PCI_IF_ISA_PIC 0x01
+#define PCI_IF_EISA_PIC 0x02
+#define PCI_IF_APIC_CONTROLLER 0x10 // I/O APIC interrupt controller , 32 byte none-prefetchable memory.
+#define PCI_IF_APIC_CONTROLLER2 0x20
+#define PCI_SUBCLASS_TIMER 0x02
+#define PCI_IF_8254_TIMER 0x00
+#define PCI_IF_ISA_TIMER 0x01
+#define PCI_EISA_TIMER 0x02
+#define PCI_SUBCLASS_RTC 0x03
+#define PCI_IF_GENERIC_RTC 0x00
+#define PCI_IF_ISA_RTC 0x00
+#define PCI_SUBCLASS_PNP_CONTROLLER 0x04 // HotPlug Controller
+
+#define PCI_CLASS_INPUT_DEVICE 0x09
+#define PCI_SUBCLASS_KEYBOARD 0x00
+#define PCI_SUBCLASS_PEN 0x01
+#define PCI_SUBCLASS_MOUSE_CONTROLLER 0x02
+#define PCI_SUBCLASS_SCAN_CONTROLLER 0x03
+#define PCI_SUBCLASS_GAMEPORT 0x04
+
+#define PCI_CLASS_DOCKING_STATION 0x0A
+
+#define PCI_CLASS_PROCESSOR 0x0B
+#define PCI_SUBCLASS_PROC_386 0x00
+#define PCI_SUBCLASS_PROC_486 0x01
+#define PCI_SUBCLASS_PROC_PENTIUM 0x02
+#define PCI_SUBCLASS_PROC_ALPHA 0x10
+#define PCI_SUBCLASS_PROC_POWERPC 0x20
+#define PCI_SUBCLASS_PROC_MIPS 0x30
+#define PCI_SUBCLASS_PROC_CO_PORC 0x40 // Co-Processor
+
+#define PCI_CLASS_SERIAL 0x0C
+#define PCI_CLASS_SERIAL_FIREWIRE 0x00
+#define PCI_CLASS_SERIAL_ACCESS_BUS 0x01
+#define PCI_CLASS_SERIAL_SSA 0x02
+#define PCI_CLASS_SERIAL_USB 0x03
+#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04
+#define PCI_CLASS_SERIAL_SMB 0x05
+
+#define PCI_CLASS_WIRELESS 0x0D
+#define PCI_SUBCLASS_IRDA 0x00
+#define PCI_SUBCLASS_IR 0x01
+#define PCI_SUBCLASS_RF 0x02
+
+#define PCI_CLASS_INTELLIGENT_IO 0x0E
+
+#define PCI_CLASS_SATELLITE 0x0F
+#define PCI_SUBCLASS_TV 0x01
+#define PCI_SUBCLASS_AUDIO 0x02
+#define PCI_SUBCLASS_VOICE 0x03
+#define PCI_SUBCLASS_DATA 0x04
+
+#define PCI_SECURITY_CONTROLLER 0x10 // Encryption and decryption controller
+#define PCI_SUBCLASS_NET_COMPUT 0x00
+#define PCI_SUBCLASS_ENTERTAINMENT 0x10
+
+#define PCI_CLASS_DPIO 0x11
+
+#define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c))
+#define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s)))
+#define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p)))
+
+#define IS_PCI_DISPLAY(_p) IS_CLASS1 (_p, PCI_CLASS_DISPLAY)
+#define IS_PCI_VGA(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0)
+#define IS_PCI_8514(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1)
+#define IS_PCI_GFX(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0)
+#define IS_PCI_OLD(_p) IS_CLASS1 (_p, PCI_CLASS_OLD)
+#define IS_PCI_OLD_VGA(_p) IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA)
+#define IS_PCI_IDE(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE)
+#define IS_PCI_SCSI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0)
+#define IS_PCI_RAID(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0)
+#define IS_PCI_LPC(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0)
+#define IS_PCI_P2P(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0)
+#define IS_PCI_P2P_SUB(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1)
+#define IS_PCI_USB(_p) IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB)
+
+#define HEADER_TYPE_DEVICE 0x00
+#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01
+#define HEADER_TYPE_CARDBUS_BRIDGE 0x02
+
+#define HEADER_TYPE_MULTI_FUNCTION 0x80
+#define HEADER_LAYOUT_CODE 0x7f
+
+#define IS_PCI_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE))
+#define IS_CARDBUS_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE))
+#define IS_PCI_MULTI_FUNC(_p) ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)
+
+#define PCI_DEVICE_ROMBAR 0x30
+#define PCI_BRIDGE_ROMBAR 0x38
+
+#define PCI_MAX_BAR 0x0006
+#define PCI_MAX_CONFIG_OFFSET 0x0100
+
+#define PCI_VENDOR_ID_OFFSET 0x00
+#define PCI_DEVICE_ID_OFFSET 0x02
+#define PCI_COMMAND_OFFSET 0x04
+#define PCI_PRIMARY_STATUS_OFFSET 0x06
+#define PCI_REVISION_ID_OFFSET 0x08
+#define PCI_CLASSCODE_OFFSET 0x09
+#define PCI_CACHELINE_SIZE_OFFSET 0x0C
+#define PCI_LATENCY_TIMER_OFFSET 0x0D
+#define PCI_HEADER_TYPE_OFFSET 0x0E
+#define PCI_BIST_OFFSET 0x0F
+#define PCI_BASE_ADDRESSREG_OFFSET 0x10
+#define PCI_CARDBUS_CIS_OFFSET 0x28
+#define PCI_SVID_OFFSET 0x2C // SubSystem Vendor id
+#define PCI_SUBSYSTEM_VENDOR_ID_OFFSET 0x2C
+#define PCI_SID_OFFSET 0x2E // SubSystem ID
+#define PCI_SUBSYSTEM_ID_OFFSET 0x2E
+#define PCI_EXPANSION_ROM_BASE 0x30
+#define PCI_CAPBILITY_POINTER_OFFSET 0x34
+#define PCI_INT_LINE_OFFSET 0x3C // Interrupt Line Register
+#define PCI_INT_PIN_OFFSET 0x3D // Interrupt Pin Register
+#define PCI_MAXGNT_OFFSET 0x3E // Max Grant Register
+#define PCI_MAXLAT_OFFSET 0x3F // Max Latency Register
+
+#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET 0x3E
+#define PCI_BRIDGE_STATUS_REGISTER_OFFSET 0x1E
+
+#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET 0x18
+#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET 0x19
+#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET 0x1a
+
+typedef union {
+ struct {
+ UINT32 Reg : 8;
+ UINT32 Func : 3;
+ UINT32 Dev : 5;
+ UINT32 Bus : 8;
+ UINT32 Reserved : 7;
+ UINT32 Enable : 1;
+ } Bits;
+ UINT32 Uint32;
+} PCI_CONFIG_ACCESS_CF8;
+
+#pragma pack()
+
+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55
+#define PCI_DATA_STRUCTURE_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'R')
+#define PCI_CODE_TYPE_PCAT_IMAGE 0x00
+#define PCI_CODE_TYPE_EFI_IMAGE 0x03
+#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED 0x0001
+
+#define EFI_PCI_COMMAND_IO_SPACE 0x0001
+#define EFI_PCI_COMMAND_MEMORY_SPACE 0x0002
+#define EFI_PCI_COMMAND_BUS_MASTER 0x0004
+#define EFI_PCI_COMMAND_SPECIAL_CYCLE 0x0008
+#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE 0x0010
+#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP 0x0020
+#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND 0x0040
+#define EFI_PCI_COMMAND_STEPPING_CONTROL 0x0080
+#define EFI_PCI_COMMAND_SERR 0x0100
+#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK 0x0200
+
+#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE 0x0001
+#define EFI_PCI_BRIDGE_CONTROL_SERR 0x0002
+#define EFI_PCI_BRIDGE_CONTROL_ISA 0x0004
+#define EFI_PCI_BRIDGE_CONTROL_VGA 0x0008
+#define EFI_PCI_BRIDGE_CONTROL_VGA_16 0x0010
+#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT 0x0020
+#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS 0x0040
+#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK 0x0080
+#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER 0x0100
+#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER 0x0200
+#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS 0x0400
+#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR 0x0800
+
+//
+// Following are the PCI-CARDBUS bridge control bit
+//
+#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE 0x0080
+#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE 0x0100
+#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE 0x0200
+#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400
+
+//
+// Following are the PCI status control bit
+//
+#define EFI_PCI_STATUS_CAPABILITY 0x0010
+#define EFI_PCI_STATUS_66MZ_CAPABLE 0x0020
+#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE 0x0080
+#define EFI_PCI_MASTER_DATA_PARITY_ERROR 0x0100
+
+#define EFI_PCI_CAPABILITY_PTR 0x34
+#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14
+
+#pragma pack(1)
+typedef struct {
+ UINT16 Signature; // 0xaa55
+ UINT8 Reserved[0x16];
+ UINT16 PcirOffset;
+} PCI_EXPANSION_ROM_HEADER;
+
+typedef struct {
+ UINT16 Signature; // 0xaa55
+ UINT8 Size512;
+ UINT8 InitEntryPoint[3];
+ UINT8 Reserved[0x12];
+ UINT16 PcirOffset;
+} EFI_LEGACY_EXPANSION_ROM_HEADER;
+
+typedef struct {
+ UINT32 Signature; // "PCIR"
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 Reserved0;
+ UINT16 Length;
+ UINT8 Revision;
+ UINT8 ClassCode[3];
+ UINT16 ImageLength;
+ UINT16 CodeRevision;
+ UINT8 CodeType;
+ UINT8 Indicator;
+ UINT16 Reserved1;
+} PCI_DATA_STRUCTURE;
+
+//
+// PCI Capability List IDs and records
+//
+#define EFI_PCI_CAPABILITY_ID_PMI 0x01
+#define EFI_PCI_CAPABILITY_ID_AGP 0x02
+#define EFI_PCI_CAPABILITY_ID_VPD 0x03
+#define EFI_PCI_CAPABILITY_ID_SLOTID 0x04
+#define EFI_PCI_CAPABILITY_ID_MSI 0x05
+#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06
+#define EFI_PCI_CAPABILITY_ID_PCIX 0x07
+
+typedef struct {
+ UINT8 CapabilityID;
+ UINT8 NextItemPtr;
+} EFI_PCI_CAPABILITY_HDR;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_PMI
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 PMC;
+ UINT16 PMCSR;
+ UINT8 BridgeExtention;
+ UINT8 Data;
+} EFI_PCI_CAPABILITY_PMI;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_AGP
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT8 Rev;
+ UINT8 Reserved;
+ UINT32 Status;
+ UINT32 Command;
+} EFI_PCI_CAPABILITY_AGP;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_VPD
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 AddrReg;
+ UINT32 DataReg;
+} EFI_PCI_CAPABILITY_VPD;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_SLOTID
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT8 ExpnsSlotReg;
+ UINT8 ChassisNo;
+} EFI_PCI_CAPABILITY_SLOTID;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_MSI
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 MsgCtrlReg;
+ UINT32 MsgAddrReg;
+ UINT16 MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI32;
+
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 MsgCtrlReg;
+ UINT32 MsgAddrRegLsdw;
+ UINT32 MsgAddrRegMsdw;
+ UINT16 MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI64;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ //
+ // not finished - fields need to go here
+ //
+} EFI_PCI_CAPABILITY_HOTPLUG;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_PCIX
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 CommandReg;
+ UINT32 StatusReg;
+} EFI_PCI_CAPABILITY_PCIX;
+
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 SecStatusReg;
+ UINT32 StatusReg;
+ UINT32 SplitTransCtrlRegUp;
+ UINT32 SplitTransCtrlRegDn;
+} EFI_PCI_CAPABILITY_PCIX_BRDG;
+
+#define DEVICE_ID_NOCARE 0xFFFF
+
+#define PCI_ACPI_UNUSED 0
+#define PCI_BAR_NOCHANGE 0
+#define PCI_BAR_OLD_ALIGN 0xFFFFFFFFFFFFFFFFULL
+#define PCI_BAR_EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL
+#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL
+#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL
+
+#define PCI_BAR_IDX0 0x00
+#define PCI_BAR_IDX1 0x01
+#define PCI_BAR_IDX2 0x02
+#define PCI_BAR_IDX3 0x03
+#define PCI_BAR_IDX4 0x04
+#define PCI_BAR_IDX5 0x05
+#define PCI_BAR_ALL 0xFF
+
+#pragma pack(pop)
+
+//
+// NOTE: The following header files are included here for
+// compatibility consideration.
+//
+#include "pci23.h"
+#include "pci30.h"
+#include "EfiPci.h"
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci23.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci23.h
new file mode 100644
index 00000000..256b7989
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci23.h
@@ -0,0 +1,18 @@
+/** @file
+ Support for PCI 2.3 standard.
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCI23_H
+#define _PCI23_H
+
+//#include "pci22.h"
+
+#define PCI_EXP_MAX_CONFIG_OFFSET 0x1000
+#define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci30.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci30.h
new file mode 100644
index 00000000..c1ffa9a0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/IndustryStandard/pci30.h
@@ -0,0 +1,38 @@
+/** @file
+ Support for PCI 3.0 standard.
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCI30_H
+#define _PCI30_H
+
+//#include "pci23.h"
+
+#define PCI_CLASS_MASS_STORAGE_SATADPA 0x06
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 Signature; // "PCIR"
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 DeviceListOffset;
+ UINT16 Length;
+ UINT8 Revision;
+ UINT8 ClassCode[3];
+ UINT16 ImageLength;
+ UINT16 CodeRevision;
+ UINT8 CodeType;
+ UINT8 Indicator;
+ UINT16 MaxRuntimeImageLength;
+ UINT16 ConfigUtilityCodeHeaderOffset;
+ UINT16 DMTFCLPEntryPointOffset;
+} PCI_3_0_DATA_STRUCTURE;
+
+#pragma pack(pop)
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePath.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePath.h
new file mode 100644
index 00000000..644499b6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePath.h
@@ -0,0 +1,1404 @@
+/** @file
+ The device path protocol as defined in UEFI 2.0.
+
+ The device path represents a programmatic path to a device,
+ from a software point of view. The path must persist from boot to boot, so
+ it can not contain things like PCI bus numbers that change from boot to boot.
+
+Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_DEVICE_PATH_H__
+#define __EFI_DEVICE_PATH_H__
+
+#include <Guid/PcAnsi.h>
+#include <IndustryStandard/Acpi3_0.h>
+#include <IndustryStandard/Bluetooth.h>
+
+///
+/// Device Path protocol.
+///
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+///
+/// Device Path guid definition for backward-compatible with EFI1.1.
+///
+#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID
+
+#pragma pack(1)
+
+#if defined(_MSC_EXTENSIONS)
+//
+// Disable warning when last field of data structure is a zero sized array.
+//
+#pragma warning ( disable : 4200 )
+#endif
+
+/**
+ This protocol can be used on any device handle to obtain generic path/location
+ information concerning the physical device or logical device. If the handle does
+ not logically map to a physical device, the handle may not necessarily support
+ the device path protocol. The device path describes the location of the device
+ the handle is for. The size of the Device Path can be determined from the structures
+ that make up the Device Path.
+**/
+typedef struct {
+ UINT8 Type; ///< 0x01 Hardware Device Path.
+ ///< 0x02 ACPI Device Path.
+ ///< 0x03 Messaging Device Path.
+ ///< 0x04 Media Device Path.
+ ///< 0x05 BIOS Boot Specification Device Path.
+ ///< 0x7F End of Hardware Device Path.
+
+ UINT8 SubType; ///< Varies by Type
+ ///< 0xFF End Entire Device Path, or
+ ///< 0x01 End This Instance of a Device Path and start a new
+ ///< Device Path.
+
+ UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define
+ ///< type of data. Size of data is included in Length.
+
+} EFI_DEVICE_PATH_PROTOCOL;
+
+///
+/// Device Path protocol definition for backward-compatible with EFI1.1.
+///
+typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
+
+///
+/// Hardware Device Paths.
+///
+#define HARDWARE_DEVICE_PATH 0x01
+
+///
+/// PCI Device Path SubType.
+///
+#define HW_PCI_DP 0x01
+
+///
+/// PCI Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// PCI Function Number.
+ ///
+ UINT8 Function;
+ ///
+ /// PCI Device Number.
+ ///
+ UINT8 Device;
+} PCI_DEVICE_PATH;
+
+///
+/// PCCARD Device Path SubType.
+///
+#define HW_PCCARD_DP 0x02
+
+///
+/// PCCARD Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Function Number (0 = First Function).
+ ///
+ UINT8 FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+///
+/// Memory Mapped Device Path SubType.
+///
+#define HW_MEMMAP_DP 0x03
+
+///
+/// Memory Mapped Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// EFI_MEMORY_TYPE
+ ///
+ UINT32 MemoryType;
+ ///
+ /// Starting Memory Address.
+ ///
+ EFI_PHYSICAL_ADDRESS StartingAddress;
+ ///
+ /// Ending Memory Address.
+ ///
+ EFI_PHYSICAL_ADDRESS EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+///
+/// Hardware Vendor Device Path SubType.
+///
+#define HW_VENDOR_DP 0x04
+
+///
+/// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must
+/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the
+/// contents on the n bytes that follow in the Vendor Device Path node.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Vendor-assigned GUID that defines the data that follows.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// Vendor-defined variable size data.
+ ///
+} VENDOR_DEVICE_PATH;
+
+///
+/// Controller Device Path SubType.
+///
+#define HW_CONTROLLER_DP 0x05
+
+///
+/// Controller Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Controller number.
+ ///
+ UINT32 ControllerNumber;
+} CONTROLLER_DEVICE_PATH;
+
+///
+/// BMC Device Path SubType.
+///
+#define HW_BMC_DP 0x06
+
+///
+/// BMC Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Interface Type.
+ ///
+ UINT8 InterfaceType;
+ ///
+ /// Base Address.
+ ///
+ UINT8 BaseAddress[8];
+} BMC_DEVICE_PATH;
+
+///
+/// ACPI Device Paths.
+///
+#define ACPI_DEVICE_PATH 0x02
+
+///
+/// ACPI Device Path SubType.
+///
+#define ACPI_DP 0x01
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Device's PnP hardware ID stored in a numeric 32-bit
+ /// compressed EISA-type ID. This value must match the
+ /// corresponding _HID in the ACPI name space.
+ ///
+ UINT32 HID;
+ ///
+ /// Unique ID that is required by ACPI if two devices have the
+ /// same _HID. This value must also match the corresponding
+ /// _UID/_HID pair in the ACPI name space. Only the 32-bit
+ /// numeric value type of _UID is supported. Thus, strings must
+ /// not be used for the _UID in the ACPI name space.
+ ///
+ UINT32 UID;
+} ACPI_HID_DEVICE_PATH;
+
+///
+/// Expanded ACPI Device Path SubType.
+///
+#define ACPI_EXTENDED_DP 0x02
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Device's PnP hardware ID stored in a numeric 32-bit
+ /// compressed EISA-type ID. This value must match the
+ /// corresponding _HID in the ACPI name space.
+ ///
+ UINT32 HID;
+ ///
+ /// Unique ID that is required by ACPI if two devices have the
+ /// same _HID. This value must also match the corresponding
+ /// _UID/_HID pair in the ACPI name space.
+ ///
+ UINT32 UID;
+ ///
+ /// Device's compatible PnP hardware ID stored in a numeric
+ /// 32-bit compressed EISA-type ID. This value must match at
+ /// least one of the compatible device IDs returned by the
+ /// corresponding _CID in the ACPI name space.
+ ///
+ UINT32 CID;
+ ///
+ /// Optional variable length _HIDSTR.
+ /// Optional variable length _UIDSTR.
+ /// Optional variable length _CIDSTR.
+ ///
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+//
+// EISA ID Macro
+// EISA ID Definition 32-bits
+// bits[15:0] - three character compressed ASCII EISA ID.
+// bits[31:16] - binary number
+// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST 0x41d0
+#define EISA_ID(_Name, _Num) ((UINT32)((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK 0xffff
+#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16)
+
+///
+/// ACPI _ADR Device Path SubType.
+///
+#define ACPI_ADR_DP 0x03
+
+///
+/// The _ADR device path is used to contain video output device attributes to support the Graphics
+/// Output Protocol. The device path can contain multiple _ADR entries if multiple video output
+/// devices are displaying the same output.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// _ADR value. For video output devices the value of this
+ /// field comes from Table B-2 of the ACPI 3.0 specification. At
+ /// least one _ADR value is required.
+ ///
+ UINT32 ADR;
+ //
+ // This device path may optionally contain more than one _ADR entry.
+ //
+} ACPI_ADR_DEVICE_PATH;
+
+#define ACPI_ADR_DISPLAY_TYPE_OTHER 0
+#define ACPI_ADR_DISPLAY_TYPE_VGA 1
+#define ACPI_ADR_DISPLAY_TYPE_TV 2
+#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3
+#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4
+
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
+ ((UINT32)( ((UINT32)((_DeviceIdScheme) & 0x1) << 31) | \
+ (((_HeadId) & 0x7) << 18) | \
+ (((_NonVgaOutput) & 0x1) << 17) | \
+ (((_BiosCanDetect) & 0x1) << 16) | \
+ (((_VendorInfo) & 0xf) << 12) | \
+ (((_Type) & 0xf) << 8) | \
+ (((_Port) & 0xf) << 4) | \
+ ((_Index) & 0xf) ))
+
+///
+/// Messaging Device Paths.
+/// This Device Path is used to describe the connection of devices outside the resource domain of the
+/// system. This Device Path can describe physical messaging information like SCSI ID, or abstract
+/// information like networking protocol IP addresses.
+///
+#define MESSAGING_DEVICE_PATH 0x03
+
+///
+/// ATAPI Device Path SubType
+///
+#define MSG_ATAPI_DP 0x01
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Set to zero for primary, or one for secondary.
+ ///
+ UINT8 PrimarySecondary;
+ ///
+ /// Set to zero for master, or one for slave mode.
+ ///
+ UINT8 SlaveMaster;
+ ///
+ /// Logical Unit Number.
+ ///
+ UINT16 Lun;
+} ATAPI_DEVICE_PATH;
+
+///
+/// SCSI Device Path SubType.
+///
+#define MSG_SCSI_DP 0x02
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Target ID on the SCSI bus (PUN).
+ ///
+ UINT16 Pun;
+ ///
+ /// Logical Unit Number (LUN).
+ ///
+ UINT16 Lun;
+} SCSI_DEVICE_PATH;
+
+///
+/// Fibre Channel SubType.
+///
+#define MSG_FIBRECHANNEL_DP 0x03
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved for the future.
+ ///
+ UINT32 Reserved;
+ ///
+ /// Fibre Channel World Wide Number.
+ ///
+ UINT64 WWN;
+ ///
+ /// Fibre Channel Logical Unit Number.
+ ///
+ UINT64 Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+///
+/// Fibre Channel Ex SubType.
+///
+#define MSG_FIBRECHANNELEX_DP 0x15
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved for the future.
+ ///
+ UINT32 Reserved;
+ ///
+ /// 8 byte array containing Fibre Channel End Device Port Name.
+ ///
+ UINT8 WWN[8];
+ ///
+ /// 8 byte array containing Fibre Channel Logical Unit Number.
+ ///
+ UINT8 Lun[8];
+} FIBRECHANNELEX_DEVICE_PATH;
+
+///
+/// 1394 Device Path SubType
+///
+#define MSG_1394_DP 0x04
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved for the future.
+ ///
+ UINT32 Reserved;
+ ///
+ /// 1394 Global Unique ID (GUID).
+ ///
+ UINT64 Guid;
+} F1394_DEVICE_PATH;
+
+///
+/// USB Device Path SubType.
+///
+#define MSG_USB_DP 0x05
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// USB Parent Port Number.
+ ///
+ UINT8 ParentPortNumber;
+ ///
+ /// USB Interface Number.
+ ///
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+
+///
+/// USB Class Device Path SubType.
+///
+#define MSG_USB_CLASS_DP 0x0f
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Vendor ID assigned by USB-IF. A value of 0xFFFF will
+ /// match any Vendor ID.
+ ///
+ UINT16 VendorId;
+ ///
+ /// Product ID assigned by USB-IF. A value of 0xFFFF will
+ /// match any Product ID.
+ ///
+ UINT16 ProductId;
+ ///
+ /// The class code assigned by the USB-IF. A value of 0xFF
+ /// will match any class code.
+ ///
+ UINT8 DeviceClass;
+ ///
+ /// The subclass code assigned by the USB-IF. A value of
+ /// 0xFF will match any subclass code.
+ ///
+ UINT8 DeviceSubClass;
+ ///
+ /// The protocol code assigned by the USB-IF. A value of
+ /// 0xFF will match any protocol code.
+ ///
+ UINT8 DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+///
+/// USB WWID Device Path SubType.
+///
+#define MSG_USB_WWID_DP 0x10
+
+///
+/// This device path describes a USB device using its serial number.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// USB interface number.
+ ///
+ UINT16 InterfaceNumber;
+ ///
+ /// USB vendor id of the device.
+ ///
+ UINT16 VendorId;
+ ///
+ /// USB product id of the device.
+ ///
+ UINT16 ProductId;
+ ///
+ /// Last 64-or-fewer UTF-16 characters of the USB
+ /// serial number. The length of the string is
+ /// determined by the Length field less the offset of the
+ /// Serial Number field (10)
+ ///
+ /// CHAR16 SerialNumber[...];
+} USB_WWID_DEVICE_PATH;
+
+///
+/// Device Logical Unit SubType.
+///
+#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Logical Unit Number for the interface.
+ ///
+ UINT8 Lun;
+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+
+///
+/// SATA Device Path SubType.
+///
+#define MSG_SATA_DP 0x12
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The HBA port number that facilitates the connection to the
+ /// device or a port multiplier. The value 0xFFFF is reserved.
+ ///
+ UINT16 HBAPortNumber;
+ ///
+ /// The Port multiplier port number that facilitates the connection
+ /// to the device. Must be set to 0xFFFF if the device is directly
+ /// connected to the HBA.
+ ///
+ UINT16 PortMultiplierPortNumber;
+ ///
+ /// Logical Unit Number.
+ ///
+ UINT16 Lun;
+} SATA_DEVICE_PATH;
+
+///
+/// Flag for if the device is directly connected to the HBA.
+///
+#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000
+
+///
+/// I2O Device Path SubType.
+///
+#define MSG_I2O_DP 0x06
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Target ID (TID) for a device.
+ ///
+ UINT32 Tid;
+} I2O_DEVICE_PATH;
+
+///
+/// MAC Address Device Path SubType.
+///
+#define MSG_MAC_ADDR_DP 0x0b
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The MAC address for a network interface padded with 0s.
+ ///
+ EFI_MAC_ADDRESS MacAddress;
+ ///
+ /// Network interface type(i.e. 802.3, FDDI).
+ ///
+ UINT8 IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+///
+/// IPv4 Device Path SubType
+///
+#define MSG_IPv4_DP 0x0c
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The local IPv4 address.
+ ///
+ EFI_IPv4_ADDRESS LocalIpAddress;
+ ///
+ /// The remote IPv4 address.
+ ///
+ EFI_IPv4_ADDRESS RemoteIpAddress;
+ ///
+ /// The local port number.
+ ///
+ UINT16 LocalPort;
+ ///
+ /// The remote port number.
+ ///
+ UINT16 RemotePort;
+ ///
+ /// The network protocol(i.e. UDP, TCP).
+ ///
+ UINT16 Protocol;
+ ///
+ /// 0x00 - The Source IP Address was assigned though DHCP.
+ /// 0x01 - The Source IP Address is statically bound.
+ ///
+ BOOLEAN StaticIpAddress;
+ ///
+ /// The gateway IP address
+ ///
+ EFI_IPv4_ADDRESS GatewayIpAddress;
+ ///
+ /// The subnet mask
+ ///
+ EFI_IPv4_ADDRESS SubnetMask;
+} IPv4_DEVICE_PATH;
+
+///
+/// IPv6 Device Path SubType.
+///
+#define MSG_IPv6_DP 0x0d
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The local IPv6 address.
+ ///
+ EFI_IPv6_ADDRESS LocalIpAddress;
+ ///
+ /// The remote IPv6 address.
+ ///
+ EFI_IPv6_ADDRESS RemoteIpAddress;
+ ///
+ /// The local port number.
+ ///
+ UINT16 LocalPort;
+ ///
+ /// The remote port number.
+ ///
+ UINT16 RemotePort;
+ ///
+ /// The network protocol(i.e. UDP, TCP).
+ ///
+ UINT16 Protocol;
+ ///
+ /// 0x00 - The Local IP Address was manually configured.
+ /// 0x01 - The Local IP Address is assigned through IPv6
+ /// stateless auto-configuration.
+ /// 0x02 - The Local IP Address is assigned through IPv6
+ /// stateful configuration.
+ ///
+ UINT8 IpAddressOrigin;
+ ///
+ /// The prefix length
+ ///
+ UINT8 PrefixLength;
+ ///
+ /// The gateway IP address
+ ///
+ EFI_IPv6_ADDRESS GatewayIpAddress;
+} IPv6_DEVICE_PATH;
+
+///
+/// InfiniBand Device Path SubType.
+///
+#define MSG_INFINIBAND_DP 0x09
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Flags to help identify/manage InfiniBand device path elements:
+ /// Bit 0 - IOC/Service (0b = IOC, 1b = Service).
+ /// Bit 1 - Extend Boot Environment.
+ /// Bit 2 - Console Protocol.
+ /// Bit 3 - Storage Protocol.
+ /// Bit 4 - Network Protocol.
+ /// All other bits are reserved.
+ ///
+ UINT32 ResourceFlags;
+ ///
+ /// 128-bit Global Identifier for remote fabric port.
+ ///
+ UINT8 PortGid[16];
+ ///
+ /// 64-bit unique identifier to remote IOC or server process.
+ /// Interpretation of field specified by Resource Flags (bit 0).
+ ///
+ UINT64 ServiceId;
+ ///
+ /// 64-bit persistent ID of remote IOC port.
+ ///
+ UINT64 TargetPortId;
+ ///
+ /// 64-bit persistent ID of remote device.
+ ///
+ UINT64 DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10
+
+///
+/// UART Device Path SubType.
+///
+#define MSG_UART_DP 0x0e
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Reserved.
+ ///
+ UINT32 Reserved;
+ ///
+ /// The baud rate setting for the UART style device. A value of 0
+ /// means that the device's default baud rate will be used.
+ ///
+ UINT64 BaudRate;
+ ///
+ /// The number of data bits for the UART style device. A value
+ /// of 0 means that the device's default number of data bits will be used.
+ ///
+ UINT8 DataBits;
+ ///
+ /// The parity setting for the UART style device.
+ /// Parity 0x00 - Default Parity.
+ /// Parity 0x01 - No Parity.
+ /// Parity 0x02 - Even Parity.
+ /// Parity 0x03 - Odd Parity.
+ /// Parity 0x04 - Mark Parity.
+ /// Parity 0x05 - Space Parity.
+ ///
+ UINT8 Parity;
+ ///
+ /// The number of stop bits for the UART style device.
+ /// Stop Bits 0x00 - Default Stop Bits.
+ /// Stop Bits 0x01 - 1 Stop Bit.
+ /// Stop Bits 0x02 - 1.5 Stop Bits.
+ /// Stop Bits 0x03 - 2 Stop Bits.
+ ///
+ UINT8 StopBits;
+} UART_DEVICE_PATH;
+
+///
+/// NVDIMM Namespace Device Path SubType.
+///
+#define NVDIMM_NAMESPACE_DP 0x20
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Namespace unique label identifier UUID.
+ ///
+ EFI_GUID Uuid;
+} NVDIMM_NAMESPACE_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MSG_VENDOR_DP 0x0a
+typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH;
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID
+#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID
+#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID
+
+///
+/// A new device path node is defined to declare flow control characteristics.
+/// UART Flow Control Messaging Device Path
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// Bitmap of supported flow control types.
+ /// Bit 0 set indicates hardware flow control.
+ /// Bit 1 set indicates Xon/Xoff flow control.
+ /// All other bits are reserved and are clear.
+ ///
+ UINT32 FlowControlMap;
+} UART_FLOW_CONTROL_DEVICE_PATH;
+
+#define UART_FLOW_CONTROL_HARDWARE 0x00000001
+#define UART_FLOW_CONTROL_XON_XOFF 0x00000010
+
+#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID
+///
+/// Serial Attached SCSI (SAS) Device Path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// DEVICE_PATH_MESSAGING_SAS GUID.
+ ///
+ EFI_GUID Guid;
+ ///
+ /// Reserved for future use.
+ ///
+ UINT32 Reserved;
+ ///
+ /// SAS Address for Serial Attached SCSI Target.
+ ///
+ UINT64 SasAddress;
+ ///
+ /// SAS Logical Unit Number.
+ ///
+ UINT64 Lun;
+ ///
+ /// More Information about the device and its interconnect.
+ ///
+ UINT16 DeviceTopology;
+ ///
+ /// Relative Target Port (RTP).
+ ///
+ UINT16 RelativeTargetPort;
+} SAS_DEVICE_PATH;
+
+///
+/// Serial Attached SCSI (SAS) Ex Device Path SubType
+///
+#define MSG_SASEX_DP 0x16
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port.
+ ///
+ UINT8 SasAddress[8];
+ ///
+ /// 8-byte array of the SAS Logical Unit Number.
+ ///
+ UINT8 Lun[8];
+ ///
+ /// More Information about the device and its interconnect.
+ ///
+ UINT16 DeviceTopology;
+ ///
+ /// Relative Target Port (RTP).
+ ///
+ UINT16 RelativeTargetPort;
+} SASEX_DEVICE_PATH;
+
+///
+/// NvmExpress Namespace Device Path SubType.
+///
+#define MSG_NVME_NAMESPACE_DP 0x17
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 NamespaceId;
+ UINT64 NamespaceUuid;
+} NVME_NAMESPACE_DEVICE_PATH;
+
+///
+/// DNS Device Path SubType
+///
+#define MSG_DNS_DP 0x1F
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Indicates the DNS server address is IPv4 or IPv6 address.
+ ///
+ UINT8 IsIPv6;
+ ///
+ /// Instance of the DNS server address.
+ ///
+ EFI_IP_ADDRESS DnsServerIp[];
+} DNS_DEVICE_PATH;
+
+///
+/// Uniform Resource Identifiers (URI) Device Path SubType
+///
+#define MSG_URI_DP 0x18
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Instance of the URI pursuant to RFC 3986.
+ ///
+ CHAR8 Uri[];
+} URI_DEVICE_PATH;
+
+///
+/// Universal Flash Storage (UFS) Device Path SubType.
+///
+#define MSG_UFS_DP 0x19
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Target ID on the UFS bus (PUN).
+ ///
+ UINT8 Pun;
+ ///
+ /// Logical Unit Number (LUN).
+ ///
+ UINT8 Lun;
+} UFS_DEVICE_PATH;
+
+///
+/// SD (Secure Digital) Device Path SubType.
+///
+#define MSG_SD_DP 0x1A
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 SlotNumber;
+} SD_DEVICE_PATH;
+
+///
+/// EMMC (Embedded MMC) Device Path SubType.
+///
+#define MSG_EMMC_DP 0x1D
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 SlotNumber;
+} EMMC_DEVICE_PATH;
+
+///
+/// iSCSI Device Path SubType
+///
+#define MSG_ISCSI_DP 0x13
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Network Protocol (0 = TCP, 1+ = reserved).
+ ///
+ UINT16 NetworkProtocol;
+ ///
+ /// iSCSI Login Options.
+ ///
+ UINT16 LoginOption;
+ ///
+ /// iSCSI Logical Unit Number.
+ ///
+ UINT64 Lun;
+ ///
+ /// iSCSI Target Portal group tag the initiator intends
+ /// to establish a session with.
+ ///
+ UINT16 TargetPortalGroupTag;
+ ///
+ /// iSCSI NodeTarget Name. The length of the name
+ /// is determined by subtracting the offset of this field from Length.
+ ///
+ /// CHAR8 iSCSI Target Name.
+} ISCSI_DEVICE_PATH;
+
+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000
+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002
+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000
+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000
+#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000
+#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000
+
+///
+/// VLAN Device Path SubType.
+///
+#define MSG_VLAN_DP 0x14
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// VLAN identifier (0-4094).
+ ///
+ UINT16 VlanId;
+} VLAN_DEVICE_PATH;
+
+///
+/// Bluetooth Device Path SubType.
+///
+#define MSG_BLUETOOTH_DP 0x1b
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// 48bit Bluetooth device address.
+ ///
+ BLUETOOTH_ADDRESS BD_ADDR;
+} BLUETOOTH_DEVICE_PATH;
+
+///
+/// Wi-Fi Device Path SubType.
+///
+#define MSG_WIFI_DP 0x1C
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Service set identifier. A 32-byte octets string.
+ ///
+ UINT8 SSId[32];
+} WIFI_DEVICE_PATH;
+
+///
+/// Bluetooth LE Device Path SubType.
+///
+#define MSG_BLUETOOTH_LE_DP 0x1E
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ BLUETOOTH_LE_ADDRESS Address;
+} BLUETOOTH_LE_DEVICE_PATH;
+
+//
+// Media Device Path
+//
+#define MEDIA_DEVICE_PATH 0x04
+
+///
+/// Hard Drive Media Device Path SubType.
+///
+#define MEDIA_HARDDRIVE_DP 0x01
+
+///
+/// The Hard Drive Media Device Path is used to represent a partition on a hard drive.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Describes the entry in a partition table, starting with entry 1.
+ /// Partition number zero represents the entire device. Valid
+ /// partition numbers for a MBR partition are [1, 4]. Valid
+ /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries].
+ ///
+ UINT32 PartitionNumber;
+ ///
+ /// Starting LBA of the partition on the hard drive.
+ ///
+ UINT64 PartitionStart;
+ ///
+ /// Size of the partition in units of Logical Blocks.
+ ///
+ UINT64 PartitionSize;
+ ///
+ /// Signature unique to this partition:
+ /// If SignatureType is 0, this field has to be initialized with 16 zeros.
+ /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field.
+ /// The other 12 bytes are initialized with zeros.
+ /// If SignatureType is 2, this field contains a 16 byte signature.
+ ///
+ UINT8 Signature[16];
+ ///
+ /// Partition Format: (Unused values reserved).
+ /// 0x01 - PC-AT compatible legacy MBR.
+ /// 0x02 - GUID Partition Table.
+ ///
+ UINT8 MBRType;
+ ///
+ /// Type of Disk Signature: (Unused values reserved).
+ /// 0x00 - No Disk Signature.
+ /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR.
+ /// 0x02 - GUID signature.
+ ///
+ UINT8 SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define NO_DISK_SIGNATURE 0x00
+#define SIGNATURE_TYPE_MBR 0x01
+#define SIGNATURE_TYPE_GUID 0x02
+
+///
+/// CD-ROM Media Device Path SubType.
+///
+#define MEDIA_CDROM_DP 0x02
+
+///
+/// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero.
+ ///
+ UINT32 BootEntry;
+ ///
+ /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing.
+ ///
+ UINT64 PartitionStart;
+ ///
+ /// Size of the partition in units of Blocks, also called Sectors.
+ ///
+ UINT64 PartitionSize;
+} CDROM_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MEDIA_VENDOR_DP 0x03 ///< Media vendor device path subtype.
+
+///
+/// File Path Media Device Path SubType
+///
+#define MEDIA_FILEPATH_DP 0x04
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// A NULL-terminated Path string including directory and file names.
+ ///
+ CHAR16 PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH OFFSET_OF(FILEPATH_DEVICE_PATH,PathName)
+
+///
+/// Media Protocol Device Path SubType.
+///
+#define MEDIA_PROTOCOL_DP 0x05
+
+///
+/// The Media Protocol Device Path is used to denote the protocol that is being
+/// used in a device path at the location of the path specified.
+/// Many protocols are inherent to the style of device path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// The ID of the protocol.
+ ///
+ EFI_GUID Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+///
+/// PIWG Firmware File SubType.
+///
+#define MEDIA_PIWG_FW_FILE_DP 0x06
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Firmware file name
+ ///
+ EFI_GUID FvFileName;
+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;
+
+///
+/// PIWG Firmware Volume Device Path SubType.
+///
+#define MEDIA_PIWG_FW_VOL_DP 0x07
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Firmware volume name.
+ ///
+ EFI_GUID FvName;
+} MEDIA_FW_VOL_DEVICE_PATH;
+
+///
+/// Media relative offset range device path.
+///
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08
+
+///
+/// Used to describe the offset range of media relative.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Reserved;
+ UINT64 StartingOffset;
+ UINT64 EndingOffset;
+} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in volatile memory.
+///
+#define EFI_VIRTUAL_DISK_GUID \
+ { \
+ 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E } \
+ }
+
+extern EFI_GUID gEfiVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
+///
+#define EFI_VIRTUAL_CD_GUID \
+ { \
+ 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB } \
+ }
+extern EFI_GUID gEfiVirtualCdGuid;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_DISK_GUID \
+ { \
+ 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 } \
+ }
+
+extern EFI_GUID gEfiPersistentVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_CD_GUID \
+ { \
+ 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D } \
+ }
+
+extern EFI_GUID gEfiPersistentVirtualCdGuid;
+
+///
+/// Media ram disk device path.
+///
+#define MEDIA_RAM_DISK_DP 0x09
+
+///
+/// Used to describe the ram disk device path.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Starting Memory Address.
+ ///
+ UINT32 StartingAddr[2];
+ ///
+ /// Ending Memory Address.
+ ///
+ UINT32 EndingAddr[2];
+ ///
+ /// GUID that defines the type of the RAM Disk.
+ ///
+ EFI_GUID TypeGuid;
+ ///
+ /// RAM Diskinstance number, if supported. The default value is zero.
+ ///
+ UINT16 Instance;
+} MEDIA_RAM_DISK_DEVICE_PATH;
+
+///
+/// BIOS Boot Specification Device Path.
+///
+#define BBS_DEVICE_PATH 0x05
+
+///
+/// BIOS Boot Specification Device Path SubType.
+///
+#define BBS_BBS_DP 0x01
+
+///
+/// This Device Path is used to describe the booting of non-EFI-aware operating systems.
+///
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ ///
+ /// Device Type as defined by the BIOS Boot Specification.
+ ///
+ UINT16 DeviceType;
+ ///
+ /// Status Flags as defined by the BIOS Boot Specification.
+ ///
+ UINT16 StatusFlag;
+ ///
+ /// Null-terminated ASCII string that describes the boot device to a user.
+ ///
+ CHAR8 String[1];
+} BBS_BBS_DEVICE_PATH;
+
+//
+// DeviceType definitions - from BBS specification
+//
+#define BBS_TYPE_FLOPPY 0x01
+#define BBS_TYPE_HARDDRIVE 0x02
+#define BBS_TYPE_CDROM 0x03
+#define BBS_TYPE_PCMCIA 0x04
+#define BBS_TYPE_USB 0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_BEV 0x80
+#define BBS_TYPE_UNKNOWN 0xFF
+
+
+///
+/// Union of all possible Device Paths and pointers to Device Paths.
+///
+typedef union {
+ EFI_DEVICE_PATH_PROTOCOL DevPath;
+ PCI_DEVICE_PATH Pci;
+ PCCARD_DEVICE_PATH PcCard;
+ MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+
+ CONTROLLER_DEVICE_PATH Controller;
+ BMC_DEVICE_PATH Bmc;
+ ACPI_HID_DEVICE_PATH Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi;
+ ACPI_ADR_DEVICE_PATH AcpiAdr;
+
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ ISCSI_DEVICE_PATH Iscsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+ FIBRECHANNELEX_DEVICE_PATH FibreChannelEx;
+
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ SATA_DEVICE_PATH Sata;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ USB_WWID_DEVICE_PATH UsbWwid;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit;
+ I2O_DEVICE_PATH I2O;
+ MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ VLAN_DEVICE_PATH Vlan;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl;
+ SAS_DEVICE_PATH Sas;
+ SASEX_DEVICE_PATH SasEx;
+ NVME_NAMESPACE_DEVICE_PATH NvmeNamespace;
+ DNS_DEVICE_PATH Dns;
+ URI_DEVICE_PATH Uri;
+ BLUETOOTH_DEVICE_PATH Bluetooth;
+ WIFI_DEVICE_PATH WiFi;
+ UFS_DEVICE_PATH Ufs;
+ SD_DEVICE_PATH Sd;
+ EMMC_DEVICE_PATH Emmc;
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+
+ FILEPATH_DEVICE_PATH FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+
+ MEDIA_FW_VOL_DEVICE_PATH FirmwareVolume;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FirmwareFile;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset;
+ MEDIA_RAM_DISK_DEVICE_PATH RamDisk;
+ BBS_BBS_DEVICE_PATH Bbs;
+} EFI_DEV_PATH;
+
+
+
+typedef union {
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ PCI_DEVICE_PATH *Pci;
+ PCCARD_DEVICE_PATH *PcCard;
+ MEMMAP_DEVICE_PATH *MemMap;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ CONTROLLER_DEVICE_PATH *Controller;
+ BMC_DEVICE_PATH *Bmc;
+ ACPI_HID_DEVICE_PATH *Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+
+ ATAPI_DEVICE_PATH *Atapi;
+ SCSI_DEVICE_PATH *Scsi;
+ ISCSI_DEVICE_PATH *Iscsi;
+ FIBRECHANNEL_DEVICE_PATH *FibreChannel;
+ FIBRECHANNELEX_DEVICE_PATH *FibreChannelEx;
+
+ F1394_DEVICE_PATH *F1394;
+ USB_DEVICE_PATH *Usb;
+ SATA_DEVICE_PATH *Sata;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit;
+ I2O_DEVICE_PATH *I2O;
+ MAC_ADDR_DEVICE_PATH *MacAddr;
+ IPv4_DEVICE_PATH *Ipv4;
+ IPv6_DEVICE_PATH *Ipv6;
+ VLAN_DEVICE_PATH *Vlan;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+ UART_DEVICE_PATH *Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+ SAS_DEVICE_PATH *Sas;
+ SASEX_DEVICE_PATH *SasEx;
+ NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace;
+ DNS_DEVICE_PATH *Dns;
+ URI_DEVICE_PATH *Uri;
+ BLUETOOTH_DEVICE_PATH *Bluetooth;
+ WIFI_DEVICE_PATH *WiFi;
+ UFS_DEVICE_PATH *Ufs;
+ SD_DEVICE_PATH *Sd;
+ EMMC_DEVICE_PATH *Emmc;
+ HARDDRIVE_DEVICE_PATH *HardDrive;
+ CDROM_DEVICE_PATH *CD;
+
+ FILEPATH_DEVICE_PATH *FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol;
+
+ MEDIA_FW_VOL_DEVICE_PATH *FirmwareVolume;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FirmwareFile;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ BBS_BBS_DEVICE_PATH *Bbs;
+ UINT8 *Raw;
+} EFI_DEV_PATH_PTR;
+
+#define EFI_DEBUGPORT_PROTOCOL_GUID \
+ { \
+ 0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
+ }
+//
+// DEBUGPORT variable definitions...
+//
+#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT"
+#define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID
+extern EFI_GUID gEfiDebugPortVariableGuid;
+
+//
+// DebugPort device path definitions...
+//
+#define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID
+extern EFI_GUID gEfiDebugPortProtocolGuid;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+} DEBUGPORT_DEVICE_PATH;
+
+#pragma pack()
+
+#define END_DEVICE_PATH_TYPE 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+
+extern EFI_GUID gEfiDevicePathProtocolGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h
new file mode 100644
index 00000000..bd6920c6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h
@@ -0,0 +1,288 @@
+/** @file
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0.
+ Use to create and manipulate device paths and device nodes.
+
+ Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __DEVICE_PATH_UTILITIES_H__
+#define __DEVICE_PATH_UTILITIES_H__
+
+///
+/// Device Path Utilities protocol
+///
+#define EFI_DEVICE_PATH_UTILITIES_GUID \
+ { \
+ 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
+ }
+
+/**
+ Returns the size of the device path, in bytes.
+
+ @param DevicePath Points to the start of the EFI device path.
+
+ @return Size Size of the specified device path, in bytes, including the end-of-path tag.
+ @retval 0 DevicePath is NULL
+
+**/
+typedef
+UINTN
+( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+/**
+ Create a duplicate of the specified path.
+
+ @param DevicePath Points to the source EFI device path.
+
+ @retval Pointer A pointer to the duplicate device path.
+ @retval NULL insufficient memory or DevicePath is NULL
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Create a new path by appending the second device path to the first.
+ If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned.
+ If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned.
+ If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned.
+
+ @param Src1 Points to the first device path.
+ @param Src2 Points to the second device path.
+
+ @retval Pointer A pointer to the newly created device path.
+ @retval NULL Memory could not be allocated
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+ If DeviceNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned.
+ If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned.
+
+ @param DevicePath Points to the device path.
+ @param DeviceNode Points to the device node.
+
+ @retval Pointer A pointer to the allocated device node.
+ @retval NULL There was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ );
+
+/**
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ @param DevicePath Points to the device path. If NULL, then ignored.
+ @param DevicePathInstance Points to the device path instance.
+
+ @retval Pointer A pointer to the newly created device path
+ @retval NULL Memory could not be allocated or DevicePathInstance is NULL.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ @param DevicePathInstance On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ @param DevicePathInstanceSize On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is NULL.
+ If NULL, then the instance size is not output.
+
+ @retval Pointer A pointer to the copy of the current device path instance.
+ @retval NULL DevicePathInstance was NULL on entry or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)(
+ EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ UINTN *DevicePathInstanceSize
+ );
+
+/**
+ Creates a device node
+
+ @param NodeType NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ @param NodeSubType NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ @param NodeLength NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ @retval Pointer A pointer to the newly created device node.
+ @retval NULL NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)(
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+);
+
+/**
+ Returns whether a device path is multi-instance.
+
+ @param DevicePath Points to the device path. If NULL, then ignored.
+
+ @retval TRUE The device path has more than one instance
+ @retval FALSE The device path is empty or contains only a single instance.
+
+**/
+typedef
+BOOLEAN
+( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)(
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+///
+/// This protocol is used to creates and manipulates device paths and device nodes.
+///
+typedef struct {
+ EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
+ EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath;
+ EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode;
+ EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance;
+ EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance;
+ EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode;
+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid;
+
+VOID
+SetDevicePathEndNode (
+ VOID *Node
+ );
+
+BOOLEAN
+IsDevicePathValid (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ UINTN MaxSize
+ );
+
+UINT8
+DevicePathType (
+ CONST VOID *Node
+ );
+
+UINT8
+DevicePathSubType (
+ CONST VOID *Node
+ );
+
+UINTN
+DevicePathNodeLength (
+ CONST VOID *Node
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+NextDevicePathNode (
+ CONST VOID *Node
+ );
+
+BOOLEAN
+IsDevicePathEndType (
+ CONST VOID *Node
+ );
+
+BOOLEAN
+IsDevicePathEnd (
+ CONST VOID *Node
+ );
+BOOLEAN
+IsDevicePathEndInstance (
+ CONST VOID *Node
+ );
+
+UINT16
+SetDevicePathNodeLength (
+ VOID *Node,
+ UINTN Length
+ );
+
+VOID
+SetDevicePathEndNode (
+ VOID *Node
+ );
+
+UINTN
+UefiDevicePathLibGetDevicePathSize (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibDuplicateDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePath (
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathNode (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibAppendDevicePathInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibGetNextDevicePathInstance (
+ EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ UINTN *Size
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+UefiDevicePathLibCreateDeviceNode (
+ UINT8 NodeType,
+ UINT8 NodeSubType,
+ UINT16 NodeLength
+ );
+
+BOOLEAN
+UefiDevicePathLibIsDevicePathMultiInstance (
+ CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h
new file mode 100644
index 00000000..d075365c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h
@@ -0,0 +1,187 @@
+/** @file
+ Graphics Output Protocol from the UEFI 2.0 specification.
+
+ Abstraction of a very simple graphics device.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __GRAPHICS_OUTPUT_H__
+#define __GRAPHICS_OUTPUT_H__
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { \
+ 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \
+ }
+
+typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;
+
+typedef struct {
+ UINT32 RedMask;
+ UINT32 GreenMask;
+ UINT32 BlueMask;
+ UINT32 ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef enum {
+ PixelRedGreenBlueReserved8BitPerColor,
+ PixelBlueGreenRedReserved8BitPerColor,
+ PixelBitMask,
+ PixelBltOnly,
+ PixelFormatMax
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef struct {
+ UINT32 Version;
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelInformation;
+ UINT32 PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+/**
+ Return the current video mode information.
+
+ @param This Protocol instance pointer.
+ @param ModeNumber The mode number to return information on.
+ @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
+ @param Info A pointer to callee allocated buffer that returns information about ModeNumber.
+
+ @retval EFI_SUCCESS Mode information returned.
+ @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
+ @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
+ @retval EFI_INVALID_PARAMETER One of the input args was NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+;
+
+/**
+ Return the current video mode information.
+
+ @param This Protocol instance pointer.
+ @param ModeNumber The mode number to be set.
+
+ @retval EFI_SUCCESS Graphics mode was changed.
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+ @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+ )
+;
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+
+typedef union {
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel;
+ UINT32 Raw;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION;
+
+typedef enum {
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphicsOutputBltOperationMax
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+
+/**
+ The following table defines actions for BltOperations:
+
+ <B>EfiBltVideoFill</B> - Write data from the BltBuffer pixel (SourceX, SourceY)
+ directly to every pixel of the video display rectangle
+ (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+ Only one pixel will be used from the BltBuffer. Delta is NOT used.
+
+ <B>EfiBltVideoToBltBuffer</B> - Read data from the video display rectangle
+ (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
+ the BltBuffer rectangle (DestinationX, DestinationY )
+ (DestinationX + Width, DestinationY + Height). If DestinationX or
+ DestinationY is not zero then Delta must be set to the length in bytes
+ of a row in the BltBuffer.
+
+ <B>EfiBltBufferToVideo</B> - Write data from the BltBuffer rectangle
+ (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
+ video display rectangle (DestinationX, DestinationY)
+ (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
+ not zero then Delta must be set to the length in bytes of a row in the
+ BltBuffer.
+
+ <B>EfiBltVideoToVideo</B> - Copy from the video display rectangle (SourceX, SourceY)
+ (SourceX + Width, SourceY + Height) .to the video display rectangle
+ (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+ The BltBuffer and Delta are not used in this mode.
+
+ @param This Protocol instance pointer.
+ @param BltBuffer Buffer containing data to blit into video buffer. This
+ buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ @param BltOperation Operation to perform on BlitBuffer and video memory
+ @param SourceX X coordinate of source for the BltBuffer.
+ @param SourceY Y coordinate of source for the BltBuffer.
+ @param DestinationX X coordinate of destination for the BltBuffer.
+ @param DestinationY Y coordinate of destination for the BltBuffer.
+ @param Width Width of rectangle in BltBuffer in pixels.
+ @param Height Height of rectangle in BltBuffer in pixels.
+ @param Delta OPTIONAL
+
+ @retval EFI_SUCCESS The Blt operation completed.
+ @retval EFI_INVALID_PARAMETER BltOperation is not valid.
+ @retval EFI_DEVICE_ERROR A hardware error occurred writing to the video buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+ );
+
+typedef struct {
+ UINT32 MaxMode;
+ UINT32 Mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+ EFI_PHYSICAL_ADDRESS FrameBufferBase;
+ UINTN FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+struct _EFI_GRAPHICS_OUTPUT_PROTOCOL {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
+};
+
+extern EFI_GUID gEfiGraphicsOutputProtocolGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h
new file mode 100644
index 00000000..6dfe1db3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h
@@ -0,0 +1,145 @@
+/** @file
+ This file declares GUIDed section extraction protocol.
+
+ This interface provides a means of decoding a GUID defined encapsulation
+ section. There may be multiple different GUIDs associated with the GUIDed
+ section extraction protocol. That is, all instances of the GUIDed section
+ extraction protocol must have the same interface structure.
+
+ @par Revision Reference: PI
+ Version 1.00.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_H__
+#define __EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_H__
+
+//
+// Forward reference for pure ANSI compatibility
+
+typedef struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL;
+
+
+/**
+ The ExtractSection() function processes the input section and
+ allocates a buffer from the pool in which it returns the section
+ contents. If the section being extracted contains
+ authentication information (the section's
+ GuidedSectionHeader.Attributes field has the
+ EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values
+ returned in AuthenticationStatus must reflect the results of
+ the authentication operation. Depending on the algorithm and
+ size of the encapsulated data, the time that is required to do
+ a full authentication may be prohibitively long for some
+ classes of systems. To indicate this, use
+ EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by
+ the security policy driver (see the Platform Initialization
+ Driver Execution Environment Core Interface Specification for
+ more details and the GUID definition). If the
+ EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle
+ database, then, if possible, full authentication should be
+ skipped and the section contents simply returned in the
+ OutputBuffer. In this case, the
+ EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus
+ must be set on return. ExtractSection() is callable only from
+ TPL_NOTIFY and below. Behavior of ExtractSection() at any
+ EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is
+ defined in RaiseTPL() in the UEFI 2.0 specification.
+
+
+ @param This Indicates the
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.
+
+ @param InputSection Buffer containing the input GUIDed section
+ to be processed. OutputBuffer OutputBuffer
+ is allocated from boot services pool
+ memory and contains the new section
+ stream. The caller is responsible for
+ freeing this buffer.
+
+ @param OutputSize A pointer to a caller-allocated UINTN in
+ which the size of OutputBuffer allocation
+ is stored. If the function returns
+ anything other than EFI_SUCCESS, the value
+ of OutputSize is undefined.
+
+ @param AuthenticationStatus A pointer to a caller-allocated
+ UINT32 that indicates the
+ authentication status of the
+ output buffer. If the input
+ section's
+ GuidedSectionHeader.Attributes
+ field has the
+ EFI_GUIDED_SECTION_AUTH_STATUS_VAL
+ bit as clear, AuthenticationStatus
+ must return zero. Both local bits
+ (19:16) and aggregate bits (3:0)
+ in AuthenticationStatus are
+ returned by ExtractSection().
+ These bits reflect the status of
+ the extraction operation. The bit
+ pattern in both regions must be
+ the same, as the local and
+ aggregate authentication statuses
+ have equivalent meaning at this
+ level. If the function returns
+ anything other than EFI_SUCCESS,
+ the value of AuthenticationStatus
+ is undefined.
+
+
+ @retval EFI_SUCCESS The InputSection was successfully
+ processed and the section contents were
+ returned.
+
+ @retval EFI_OUT_OF_RESOURCES The system has insufficient
+ resources to process the
+ request.
+
+ @retval EFI_INVALID_PARAMETER The GUID in InputSection does
+ not match this instance of the
+ GUIDed Section Extraction
+ Protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXTRACT_GUIDED_SECTION)(
+ IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+);
+
+
+/**
+
+ Takes the GUIDed section as input and produces the section
+ stream data. See the ExtractSection() function description.
+
+**/
+struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL {
+ EFI_EXTRACT_GUIDED_SECTION ExtractSection;
+};
+
+//
+// Protocol GUID definition. Each GUIDed section extraction protocol has the
+// same interface but with different GUID. All the GUIDs is defined here.
+// May add multiple GUIDs here.
+//
+#define EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID \
+ { \
+ 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } \
+ }
+
+//
+// may add other GUID here
+//
+extern EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/HiiFramework.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/HiiFramework.h
new file mode 100644
index 00000000..5cf78739
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/HiiFramework.h
@@ -0,0 +1,944 @@
+/** @file
+ This file defines the Human Interface Infrastructure protocol which will
+ be used by resources which want to publish IFR/Font/String data and have it
+ collected by the Configuration engine.
+
+ @par Revision Reference:
+ This protocol is defined in HII spec 0.92.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FRAMEWORK_HII_H_
+#define _FRAMEWORK_HII_H_
+
+//#include <PiDxe.h>
+
+//
+// To get EFI_GRAPHICS_OUTPUT_BLT_PIXEL,
+// is defined in MdePkg/Protocol/GraphicsOutput.h
+//
+#include <Protocol/GraphicsOutput.h>
+
+#define EFI_HII_PROTOCOL_GUID \
+ { \
+ 0xd7ad636e, 0xb997, 0x459b, {0xbf, 0x3f, 0x88, 0x46, 0x89, 0x79, 0x80, 0xe1} \
+ }
+
+// BugBug:
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// If UGA goes away we need to put this some place. I'm not sure where?
+//
+//typedef struct {
+// UINT8 Blue;
+// UINT8 Green;
+// UINT8 Red;
+// UINT8 Reserved;
+//} EFI_UGA_PIXEL;
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+
+typedef struct _EFI_HII_PROTOCOL EFI_HII_PROTOCOL;
+
+//
+// Global definition
+//
+#define NARROW_CHAR 0xFFF0
+#define WIDE_CHAR 0xFFF1
+#define NON_BREAKING_CHAR 0xFFF2
+#define GLYPH_WIDTH 8
+#define GLYPH_HEIGHT 19
+
+#define EFI_HII_FONT 1
+#define EFI_HII_STRING 2
+#define EFI_HII_IFR 3
+#define EFI_HII_KEYBOARD 4
+#define EFI_HII_HANDLES 5
+#define EFI_HII_VARIABLE 6
+#define EFI_HII_DEVICE_PATH 7
+
+
+// References to string tokens must use this macro to enable scanning for
+// token usages.
+//
+#define STRING_TOKEN(t) t
+
+//
+// The following types are currently defined:
+// EFI_FROM_ID has been defined in UEFI spec.
+//
+typedef UINT16 EFI_FORM_LABEL;
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 Length;
+ UINT16 Type;
+} EFI_HII_PACK_HEADER;
+
+//
+// A form list consists of a large variety of structure
+// possibilities so to represent the binary blob of data
+// associated with a package of forms, we will assume a
+// pointer to a self-describing data buffer.
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+} EFI_HII_IFR_PACK;
+
+typedef struct {
+ EFI_HII_PACK_HEADER Header; // Must be filled in
+ EFI_HANDLE ImageHandle; // Must be filled in
+ EFI_HANDLE DeviceHandle; // Optional
+ EFI_HANDLE ControllerHandle; // Optional
+ EFI_HANDLE CallbackHandle; // Optional
+ EFI_HANDLE COBExportHandle; // Optional
+} EFI_HII_HANDLE_PACK;
+
+//
+// ********************************************************
+// EFI_VARIABLE_CONTENTS
+// ********************************************************
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+ EFI_GUID VariableGuid;
+ UINT32 VariableNameLength;
+ UINT16 VariableId;
+ //
+ // CHAR16 VariableName[]; //Null-terminated
+ //
+} EFI_HII_VARIABLE_PACK;
+
+//
+// ********************************************************
+// EFI_DEVICE_PATH_PACK
+// ********************************************************
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+ //
+ // EFI_DEVICE_PATH DevicePath[];
+ //
+} EFI_HII_DEVICE_PATH_PACK;
+
+//
+// ********************************************************
+// EFI_HII_DATA_TABLE
+// ********************************************************
+//
+typedef struct {
+ EFI_HII_HANDLE HiiHandle;
+ EFI_GUID PackageGuid;
+ UINT32 DataTableSize;
+ UINT32 IfrDataOffset;
+ UINT32 StringDataOffset;
+ UINT32 VariableDataOffset;
+ UINT32 DevicePathOffset;
+ UINT32 NumberOfVariableData;
+ UINT32 NumberOfLanguages;
+ //
+ // EFI_HII_DEVICE_PATH_PACK DevicePath[];
+ // EFI_HII_VARIABLE_PACK VariableData[];
+ // EFI_HII_IFR_PACK IfrData;
+ // EFI_HII_STRING_PACK StringData[];
+ //
+} EFI_HII_DATA_TABLE;
+
+//
+// ********************************************************
+// EFI_HII_EXPORT_TABLE
+// ********************************************************
+//
+typedef struct {
+ UINT32 NumberOfHiiDataTables;
+ EFI_GUID Revision;
+ //
+ // EFI_HII_DATA_TABLE HiiDataTable[];
+ //
+} EFI_HII_EXPORT_TABLE;
+
+typedef struct {
+ BOOLEAN FormSetUpdate; // If TRUE, next variable is significant
+ EFI_PHYSICAL_ADDRESS FormCallbackHandle; // If not 0, will update Formset with this info
+ BOOLEAN FormUpdate; // If TRUE, next variable is significant
+ UINT16 FormValue; // specify which form is to be updated if FormUpdate value is TRUE.
+ STRING_REF FormTitle; // If not 0, will update Form with this info
+ UINT16 DataCount; // The number of Data entries in this structure
+ UINT8 *Data; // An array of 1+ op-codes, specified by DataCount
+} EFI_HII_UPDATE_DATA;
+
+//
+// String attributes
+//
+#define LANG_RIGHT_TO_LEFT 0x00000001
+
+//
+// A string package is used to localize strings to a particular
+// language. The package is associated with a particular driver
+// or set of drivers. Tools are used to associate tokens with
+// string references in forms and in programs. These tokens are
+// language agnostic. When paired with a language pack (directly
+// or indirectly), the string token resolves into an actual
+// UNICODE string. The NumStringPointers determines how many
+// StringPointers (offset values) there are as well as the total
+// number of Strings that are defined.
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+ RELOFST LanguageNameString;
+ RELOFST PrintableLanguageName;
+ UINT32 NumStringPointers;
+ UINT32 Attributes;
+ //
+ // RELOFST StringPointers[];
+ // EFI_STRING Strings[];
+ //
+} EFI_HII_STRING_PACK;
+
+//
+// Glyph Attributes
+//
+#define EFI_GLYPH_NON_SPACING 1
+#define EFI_GLYPH_WIDE 2
+
+typedef struct {
+ CHAR16 UnicodeWeight;
+ UINT8 Attributes;
+ UINT8 GlyphCol1[GLYPH_HEIGHT];
+} EFI_NARROW_GLYPH;
+
+typedef struct {
+ CHAR16 UnicodeWeight;
+ UINT8 Attributes;
+ UINT8 GlyphCol1[GLYPH_HEIGHT];
+ UINT8 GlyphCol2[GLYPH_HEIGHT];
+ UINT8 Pad[3];
+} EFI_WIDE_GLYPH;
+
+//
+// A font list consists of a font header followed by a series
+// of glyph structures. Note that fonts are not language specific.
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+ UINT16 NumberOfNarrowGlyphs;
+ UINT16 NumberOfWideGlyphs;
+} EFI_HII_FONT_PACK;
+
+//
+// The IfrData in the EFI_HII_IFR_PACK structure definition
+// is variable length, and not really part of the header. To
+// simplify from code the size of the header, define an
+// identical structure that does not include the IfrData field.
+// Then use sizeof() this new structure to determine the
+// actual size of the header.
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+} EFI_HII_IFR_PACK_HEADER;
+
+//
+// pedef EFI_HII_PACK_HEADER EFI_HII_IFR_PACK_HEADER;
+//
+typedef enum {
+ EfiKeyLCtrl,
+ EfiKeyA0,
+ EfiKeyLAlt,
+ EfiKeySpaceBar,
+ EfiKeyA2,
+ EfiKeyA3,
+ EfiKeyA4,
+ EfiKeyRCtrl,
+ EfiKeyLeftArrow,
+ EfiKeyDownArrow,
+ EfiKeyRightArrow,
+ EfiKeyZero,
+ EfiKeyPeriod,
+ EfiKeyEnter,
+ EfiKeyLShift,
+ EfiKeyB0,
+ EfiKeyB1,
+ EfiKeyB2,
+ EfiKeyB3,
+ EfiKeyB4,
+ EfiKeyB5,
+ EfiKeyB6,
+ EfiKeyB7,
+ EfiKeyB8,
+ EfiKeyB9,
+ EfiKeyB10,
+ EfiKeyRshift,
+ EfiKeyUpArrow,
+ EfiKeyOne,
+ EfiKeyTwo,
+ EfiKeyThree,
+ EfiKeyCapsLock,
+ EfiKeyC1,
+ EfiKeyC2,
+ EfiKeyC3,
+ EfiKeyC4,
+ EfiKeyC5,
+ EfiKeyC6,
+ EfiKeyC7,
+ EfiKeyC8,
+ EfiKeyC9,
+ EfiKeyC10,
+ EfiKeyC11,
+ EfiKeyC12,
+ EfiKeyFour,
+ EfiKeyFive,
+ EfiKeySix,
+ EfiKeyPlus,
+ EfiKeyTab,
+ EfiKeyD1,
+ EfiKeyD2,
+ EfiKeyD3,
+ EfiKeyD4,
+ EfiKeyD5,
+ EfiKeyD6,
+ EfiKeyD7,
+ EfiKeyD8,
+ EfiKeyD9,
+ EfiKeyD10,
+ EfiKeyD11,
+ EfiKeyD12,
+ EfiKeyD13,
+ EfiKeyDel,
+ EfiKeyEnd,
+ EfiKeyPgDn,
+ EfiKeySeven,
+ EfiKeyEight,
+ EfiKeyNine,
+ EfiKeyE0,
+ EfiKeyE1,
+ EfiKeyE2,
+ EfiKeyE3,
+ EfiKeyE4,
+ EfiKeyE5,
+ EfiKeyE6,
+ EfiKeyE7,
+ EfiKeyE8,
+ EfiKeyE9,
+ EfiKeyE10,
+ EfiKeyE11,
+ EfiKeyE12,
+ EfiKeyBackSpace,
+ EfiKeyIns,
+ EfiKeyHome,
+ EfiKeyPgUp,
+ EfiKeyNLck,
+ EfiKeySlash,
+ EfiKeyAsterisk,
+ EfiKeyMinus,
+ EfiKeyEsc,
+ EfiKeyF1,
+ EfiKeyF2,
+ EfiKeyF3,
+ EfiKeyF4,
+ EfiKeyF5,
+ EfiKeyF6,
+ EfiKeyF7,
+ EfiKeyF8,
+ EfiKeyF9,
+ EfiKeyF10,
+ EfiKeyF11,
+ EfiKeyF12,
+ EfiKeyPrint,
+ EfiKeySLck,
+ EfiKeyPause
+} EFI_KEY;
+
+typedef struct {
+ EFI_KEY Key;
+ CHAR16 Unicode;
+ CHAR16 ShiftedUnicode;
+ CHAR16 AltGrUnicode;
+ CHAR16 ShiftedAltGrUnicode;
+ UINT16 Modifier;
+} EFI_KEY_DESCRIPTOR;
+
+//
+// This structure allows a sparse set of keys to be redefined
+// or a complete redefinition of the keyboard layout. Most
+// keyboards have a lot of commonality in their layouts, therefore
+// only defining those keys that need to change from the default
+// minimizes the passed in information.
+//
+// Additionally, when an update occurs, the active keyboard layout
+// will be switched to the newly updated keyboard layout. This
+// allows for situations that when a keyboard layout driver is
+// loaded as part of system initialization, the system will default
+// the keyboard behavior to the new layout.
+//
+// Each call to update the keyboard mapping should contain the
+// complete set of key descriptors to be updated, since every
+// call to the HII which contains an EFI_HII_KEYBOARD_PACK will
+// wipe the previous set of overrides. A call to
+//
+typedef struct {
+ EFI_HII_PACK_HEADER Header;
+ EFI_KEY_DESCRIPTOR *Descriptor;
+ UINT8 DescriptorCount;
+} EFI_HII_KEYBOARD_PACK;
+
+//
+// The EFI_HII_PACKAGES can contain different types of packages just
+// after the structure as inline data.
+//
+typedef struct {
+ UINTN NumberOfPackages;
+ EFI_GUID *GuidId;
+ //
+ // EFI_HII_HANDLE_PACK *HandlePack; // Only one pack.
+ // EFI_HII_IFR_PACK *IfrPack; // Only one pack.
+ // EFI_HII_FONT_PACK *FontPack[]; // Multiple packs ok
+ // EFI_HII_STRING_PACK *StringPack[]; // Multiple packs ok
+ // EFI_HII_KEYBOARD_PACK *KeyboardPack[]; // Multiple packs ok
+ //
+} EFI_HII_PACKAGES;
+
+typedef struct _EFI_HII_VARIABLE_PACK_LIST {
+ struct _EFI_HII_VARIABLE_PACK_LIST *NextVariablePack;
+ EFI_HII_VARIABLE_PACK *VariablePack;
+} EFI_HII_VARIABLE_PACK_LIST;
+
+
+#pragma pack()
+
+/**
+ Registers the various packs that are passed in via the Packages parameter.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Packages A pointer to an EFI_HII_PACKAGES package instance.
+ @param Handle A pointer to the EFI_HII_HANDLE instance.
+
+ @retval EFI_SUCCESS Data was extracted from Packages, the database
+ was updated with the data, and Handle returned successfully.
+ @retval EFI_INVALID_PARAMETER The content of Packages was invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_NEW_PACK) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACKAGES *Packages,
+ OUT EFI_HII_HANDLE *Handle
+ );
+
+/**
+ Removes a package from the HII database.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The handle that was registered to the data that is requested
+ for removal.
+
+ @retval EFI_SUCCESS The data associated with the Handle was removed
+ from the HII database.
+ @retval EFI_INVALID_PARAMETER The Handle was not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_REMOVE_PACK) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+ );
+
+/**
+ Determines the handles that are currently active in the database.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param HandleBufferLength On input, a pointer to the length of the handle
+ buffer. On output, the length of the handle buffer that is required
+ for the handles found.
+ @param Handle An array of EFI_HII_HANDLE instances returned.
+
+ @retval EFI_SUCCESS Handle was updated successfully.
+ @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates
+ that Handle is too small to support the number of handles.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_FIND_HANDLES) (
+ IN EFI_HII_PROTOCOL *This,
+ IN OUT UINT16 *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle
+ );
+
+/**
+ Exports the contents of the database into a buffer.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle An EFI_HII_HANDLE that corresponds to the desired
+ handle to export. If the value is 0, the entire database will be exported.
+ In either case, the data will be exported in a format described by the
+ structure definition of EFI_HII_EXPORT_TABLE.
+ @param BufferSize
+ On input, a pointer to the length of the buffer. On output, the length
+ of the buffer that is required for the export data.
+ @param Buffer A pointer to a buffer that will contain the results of the export function.
+
+ @retval EFI_SUCCESS The buffer was successfully filled with BufferSize amount of data.
+ @retval EFI_BUFFER_TOO_SMALL The value in BufferSize was too small to contain the export data.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_EXPORT) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Remove any new strings that were added after the initial string export
+ for this handle.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The handle on which the string resides.
+
+ @retval EFI_SUCCESS Remove strings from the handle successfully.
+ @retval EFI_INVALID_PARAMETER The Handle was unknown.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_RESET_STRINGS) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+ );
+
+/**
+ Tests if all of the characters in a string have corresponding font characters.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param StringToTest A pointer to a Unicode string.
+ @param FirstMissing A pointer to an index into the string. On input,
+ the index of the first character in the StringToTest to examine. On exit,
+ the index of the first character encountered for which a glyph is unavailable.
+ If all glyphs in the string are available, the index is the index of the
+ terminator of the string.
+ @param GlyphBufferSize A pointer to a value. On output, if the function
+ returns EFI_SUCCESS, it contains the amount of memory that is required to
+ store the string's glyph equivalent.
+
+ @retval EFI_SUCCESS All glyphs are available. Note that an empty string
+ always returns this value.
+ @retval EFI_NOT_FOUND A glyph was not found for a character.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_TEST_STRING) (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *StringToTest,
+ IN OUT UINT32 *FirstMissing,
+ OUT UINT32 *GlyphBufferSize
+ );
+
+/**
+ Translates a Unicode character into the corresponding font glyph.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Source A pointer to a Unicode string.
+ @param Index On input, the offset into the string from which to fetch
+ the character.On successful completion, the index is updated to the first
+ character past the character(s) making up the just extracted glyph.
+ @param GlyphBuffer Pointer to an array where the glyphs corresponding
+ to the characters in the source may be stored. GlyphBuffer is assumed
+ to be wide enough to accept a wide glyph character.
+ @param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by
+ this value is filled with the length of the glyph in pixels. It is unchanged
+ if the call was unsuccessful.
+ @param InternalStatus The cell pointed to by this parameter must be
+ initialized to zero prior to invoking the call the first time for any string.
+
+ @retval EFI_SUCCESS It worked.
+ @retval EFI_NOT_FOUND A glyph for a character was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_GLYPH) (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Source,
+ IN OUT UINT16 *Index,
+ OUT UINT8 **GlyphBuffer,
+ OUT UINT16 *BitWidth,
+ IN OUT UINT32 *InternalStatus
+ );
+
+/**
+ Translates a glyph into the format required for input to the Universal
+ Graphics Adapter (UGA) Block Transfer (BLT) routines.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param GlyphBuffer A pointer to the buffer that contains glyph data.
+ @param Foreground The foreground setting requested to be used for the
+ generated BltBuffer data.
+ @param Background The background setting requested to be used for the
+ generated BltBuffer data.
+ @param Count The entry in the BltBuffer upon which to act.
+ @param Width The width in bits of the glyph being converted.
+ @param Height The height in bits of the glyph being converted
+ @param BltBuffer A pointer to the buffer that contains the data that is
+ ready to be used by the UGA BLT routines.
+
+ @retval EFI_SUCCESS It worked.
+ @retval EFI_NOT_FOUND A glyph for a character was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GLYPH_TO_BLT) (
+ IN EFI_HII_PROTOCOL *This,
+ IN UINT8 *GlyphBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
+ IN UINTN Count,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
+ );
+
+/**
+ Allows a new string to be added to an already existing string package.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Pointer to a NULL-terminated string containing a single ISO 639-2
+ language identifier, indicating the language in which the string is translated.
+ @param Handle The handle of the language pack to which the string is to be added.
+ @param Reference The identifier of the string to be added. If the reference
+ value is zero, then the string will be assigned a new identifier on that
+ handle for the language specified. Otherwise, the string will be updated
+ with the NewString Value.
+ @param NewString The string to be added.
+
+ @retval EFI_SUCCESS The string was effectively registered.
+ @retval EFI_INVALID_PARAMETER The Handle was unknown.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_NEW_STRING) (
+ IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Language,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT STRING_REF *Reference,
+ IN CHAR16 *NewString
+ );
+
+/**
+ Allows a program to determine the primary languages that are supported
+ on a given handle.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The handle on which the strings reside.
+ @param LanguageString A string allocated by GetPrimaryLanguages() that
+ contains a list of all primary languages registered on the handle.
+
+ @retval EFI_SUCCESS LanguageString was correctly returned.
+ @retval EFI_INVALID_PARAMETER The Handle was unknown.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_PRI_LANGUAGES) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ OUT EFI_STRING *LanguageString
+ );
+
+/**
+ Allows a program to determine which secondary languages are supported
+ on a given handle for a given primary language.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The handle on which the strings reside.
+ @param PrimaryLanguage Pointer to a NULL-terminated string containing a single
+ ISO 639-2 language identifier, indicating the primary language.
+ @param LanguageString A string allocated by GetSecondaryLanguages()
+ containing a list of all secondary languages registered on the handle.
+
+ @retval EFI_SUCCESS LanguageString was correctly returned.
+ @retval EFI_INVALID_PARAMETER The Handle was unknown.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_SEC_LANGUAGES) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CHAR16 *PrimaryLanguage,
+ OUT EFI_STRING *LanguageString
+ );
+
+/**
+ Extracts a string from a package already registered with the EFI HII database.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The handle on which the string resides.
+ @param Token The string token assigned to the string.
+ @param Raw If TRUE, the string is returned unedited in the internal
+ storage format described above. If false, the string returned is edited
+ by replacing <cr> with <space> and by removing special characters such
+ as the <wide> prefix.
+ @param LanguageString Pointer to a NULL-terminated string containing a
+ single ISO 639-2 language identifier, indicating the language to print.
+ If the LanguageString is empty (starts with a NULL), the default system
+ language will be used to determine the language.
+ @param BufferLength Length of the StringBuffer.
+ @param StringBuffer The buffer designed to receive the characters in the string.
+
+ @retval EFI_SUCCESS StringBuffer is filled with a NULL-terminated string.
+ @retval EFI_INVALID_PARAMETER The handle or string token is unknown.
+ @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to
+ allow the entire string to be stored.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_STRING) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN BOOLEAN Raw,
+ IN CHAR16 *LanguageString,
+ IN OUT UINTN *BufferLength,
+ OUT EFI_STRING StringBuffer
+ );
+
+/**
+ Allows a program to extract a part of a string of not more than a given width.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The handle on which the string resides.
+ @param Token The string token assigned to the string.
+ @param Index On input, the offset into the string where the line is to start.
+ On output, the index is updated to point to beyond the last character returned
+ in the call.
+ @param LineWidth The maximum width of the line in units of narrow glyphs.
+ @param LanguageString Pointer to a NULL-terminated string containing a
+ single ISO 639-2 language identifier, indicating the language to print.
+ @param BufferLength Pointer to the length of the StringBuffer.
+ @param StringBuffer The buffer designed to receive the characters in the string.
+
+ @retval EFI_SUCCESS StringBuffer filled with characters that will fit on the line.
+ @retval EFI_NOT_FOUND The font glyph for at least one of the characters in
+ the string is not in the font database.
+ @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough
+ to allow the entire string to be stored.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_LINE) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN OUT UINT16 *Index,
+ IN UINT16 LineWidth,
+ IN CHAR16 *LanguageString,
+ IN OUT UINT16 *BufferLength,
+ OUT EFI_STRING StringBuffer
+ );
+
+/**
+ Allows a program to extract a form or form package that has previously
+ been registered with the HII database.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle Handle on which the form resides.
+ @param FormId The ID of the form to return. If the ID is zero,
+ the entire form package is returned.
+ @param BufferLength On input, the length of the Buffer. On output,
+ the length of the returned buffer,
+ @param Buffer The buffer designed to receive the form(s).
+
+ @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength
+ was updated.
+ @retval EFI_INVALID_PARAMETER The handle is unknown.
+ @retval EFI_NOT_FOUND A form on the requested handle cannot be found with
+ the requested FormId.
+ @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough
+ to allow the form to be stored.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_FORMS) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormId,
+ IN OUT UINTN *BufferLength,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Extracts the defaults that are associated with a given handle in the HII database.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle The HII handle from which will have default data retrieved.
+ @param DefaultMask The mask used to specify some type of default override when extracting
+ the default image data.
+ @param VariablePackList A indirect pointer to the first entry of a link list with
+ type EFI_HII_VARIABLE_PACK_LIST.
+
+ @retval EFI_SUCCESS The VariablePackList was populated with the appropriate
+ default setting data.
+ @retval EFI_NOT_FOUND The IFR does not have any explicit or default map(s).
+ @retval EFI_INVALID_PARAMETER The HII database entry associated with Handle
+ contain invalid data.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_DEFAULT_IMAGE) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN UINTN DefaultMask,
+ OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
+ );
+
+/**
+ Allows the caller to update a form or form package that has previously been
+ registered with the EFI HII database.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param Handle Handle of the package where the form to be updated resides.
+ @param Label The label inside the form package where the update is to take place.
+ @param AddData If TRUE, adding data at a given Label; otherwise,
+ if FALSE, removing data at a given Label.
+ @param Data The buffer containing the new tags to insert after the Label
+
+ @retval EFI_SUCCESS The form was updated with the new tags.
+ @retval EFI_INVALID_PARAMETER The buffer for the buffer length does not
+ contain an integral number of tags.
+ @retval EFI_NOT_FOUND The Handle, Label, or FormId was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_UPDATE_FORM) (
+ IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_LABEL Label,
+ IN BOOLEAN AddData,
+ IN EFI_HII_UPDATE_DATA *Data
+ );
+
+/**
+ Retrieves the current keyboard layout.
+
+ @param This A pointer to the EFI_HII_PROTOCOL instance.
+ @param DescriptorCount A pointer to the number of Descriptor entries being
+ described in the keyboard layout being retrieved.
+ @param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR
+ entries. Each entry will reflect the definition of a specific physical key.
+
+ @retval EFI_SUCCESS The keyboard layout was retrieved successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT) (
+ IN EFI_HII_PROTOCOL *This,
+ OUT UINT16 *DescriptorCount,
+ OUT EFI_KEY_DESCRIPTOR *Descriptor
+ );
+
+/**
+ @par Protocol Description:
+ The HII Protocol manages the HII database, which is a repository for data
+ having to do with fonts, strings, forms, keyboards, and other future human
+ interface items.
+
+ @param NewPack
+ Extracts the various packs from a package list.
+
+ @param RemovePack
+ Removes a package from the HII database.
+
+ @param FindHandles
+ Determines the handles that are currently active in the database.
+
+ @param ExportDatabase
+ Export the entire contents of the database to a buffer.
+
+ @param TestString
+ Tests if all of the characters in a string have corresponding font characters.
+
+ @param GetGlyph
+ Translates a Unicode character into the corresponding font glyph.
+
+ @param GlyphToBlt
+ Converts a glyph value into a format that is ready for a UGA BLT command.
+
+ @param NewString
+ Allows a new string to be added to an already existing string package.
+
+ @param GetPrimaryLanguages
+ Allows a program to determine the primary languages that are supported
+ on a given handle.
+
+ @param GetSecondaryLanguages
+ Allows a program to determine which secondary languages are supported
+ on a given handle for a given primary language.
+
+ @param GetString
+ Extracts a string from a package that is already registered with the
+ EFI HII database.
+
+ @param ResetString
+ Remove any new strings that were added after the initial string export
+ for this handle.
+
+ @param GetLine
+ Allows a program to extract a part of a string of not more than a given width.
+
+ @param GetForms
+ Allows a program to extract a form or form package that has been previously registered.
+
+ @param GetDefaultImage
+ Allows a program to extract the nonvolatile image that represents the default storage image.
+
+ @param UpdateForm
+ Allows a program to update a previously registered form.
+
+ @param GetKeyboardLayout
+ Allows a program to extract the current keyboard layout.
+
+**/
+struct _EFI_HII_PROTOCOL {
+ EFI_HII_NEW_PACK NewPack;
+ EFI_HII_REMOVE_PACK RemovePack;
+ EFI_HII_FIND_HANDLES FindHandles;
+ EFI_HII_EXPORT ExportDatabase;
+
+ EFI_HII_TEST_STRING TestString;
+ EFI_HII_GET_GLYPH GetGlyph;
+ EFI_HII_GLYPH_TO_BLT GlyphToBlt;
+
+ EFI_HII_NEW_STRING NewString;
+ EFI_HII_GET_PRI_LANGUAGES GetPrimaryLanguages;
+ EFI_HII_GET_SEC_LANGUAGES GetSecondaryLanguages;
+ EFI_HII_GET_STRING GetString;
+ EFI_HII_RESET_STRINGS ResetStrings;
+ EFI_HII_GET_LINE GetLine;
+ EFI_HII_GET_FORMS GetForms;
+ EFI_HII_GET_DEFAULT_IMAGE GetDefaultImage;
+ EFI_HII_UPDATE_FORM UpdateForm;
+
+ EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout;
+};
+
+extern EFI_GUID gEfiHiiProtocolGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/UgaDraw.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/UgaDraw.h
new file mode 100644
index 00000000..6c58660e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/Protocol/UgaDraw.h
@@ -0,0 +1,161 @@
+/** @file
+ UGA Draw protocol from the EFI 1.1 specification.
+
+ Abstraction of a very simple graphics device.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __UGA_DRAW_H__
+#define __UGA_DRAW_H__
+
+#define EFI_UGA_DRAW_PROTOCOL_GUID \
+ { \
+ 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \
+ }
+
+typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL;
+
+/**
+ Return the current video mode information.
+
+ @param This Protocol instance pointer.
+ @param HorizontalResolution Current video horizontal resolution in pixels
+ @param VerticalResolution Current video vertical resolution in pixels
+ @param ColorDepth Current video color depth in bits per pixel
+ @param RefreshRate Current video refresh rate in Hz.
+
+ @retval EFI_SUCCESS Mode information returned.
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
+ @retval EFI_INVALID_PARAMETER One of the input args was NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE) (
+ IN EFI_UGA_DRAW_PROTOCOL *This,
+ OUT UINT32 *HorizontalResolution,
+ OUT UINT32 *VerticalResolution,
+ OUT UINT32 *ColorDepth,
+ OUT UINT32 *RefreshRate
+ )
+;
+
+/**
+ Return the current video mode information.
+
+ @param This Protocol instance pointer.
+ @param HorizontalResolution Current video horizontal resolution in pixels
+ @param VerticalResolution Current video vertical resolution in pixels
+ @param ColorDepth Current video color depth in bits per pixel
+ @param RefreshRate Current video refresh rate in Hz.
+
+ @retval EFI_SUCCESS Mode information returned.
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE) (
+ IN EFI_UGA_DRAW_PROTOCOL *This,
+ IN UINT32 HorizontalResolution,
+ IN UINT32 VerticalResolution,
+ IN UINT32 ColorDepth,
+ IN UINT32 RefreshRate
+ )
+;
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_UGA_PIXEL;
+
+typedef union {
+ EFI_UGA_PIXEL Pixel;
+ UINT32 Raw;
+} EFI_UGA_PIXEL_UNION;
+
+typedef enum {
+ EfiUgaVideoFill,
+ EfiUgaVideoToBltBuffer,
+ EfiUgaBltBufferToVideo,
+ EfiUgaVideoToVideo,
+ EfiUgaBltMax
+} EFI_UGA_BLT_OPERATION;
+
+/**
+ Type specifying a pointer to a function to perform an UGA Blt operation.
+
+ The following table defines actions for BltOperations:
+
+ <B>EfiUgaVideoFill</B> - Write data from the BltBuffer pixel (SourceX, SourceY)
+ directly to every pixel of the video display rectangle
+ (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+ Only one pixel will be used from the BltBuffer. Delta is NOT used.
+
+ <B>EfiUgaVideoToBltBuffer</B> - Read data from the video display rectangle
+ (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
+ the BltBuffer rectangle (DestinationX, DestinationY )
+ (DestinationX + Width, DestinationY + Height). If DestinationX or
+ DestinationY is not zero then Delta must be set to the length in bytes
+ of a row in the BltBuffer.
+
+ <B>EfiUgaBltBufferToVideo</B> - Write data from the BltBuffer rectangle
+ (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
+ video display rectangle (DestinationX, DestinationY)
+ (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
+ not zero then Delta must be set to the length in bytes of a row in the
+ BltBuffer.
+
+ <B>EfiUgaVideoToVideo</B> - Copy from the video display rectangle (SourceX, SourceY)
+ (SourceX + Width, SourceY + Height) .to the video display rectangle
+ (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+ The BltBuffer and Delta are not used in this mode.
+
+
+ @param[in] This - Protocol instance pointer.
+ @param[in] BltBuffer - Buffer containing data to blit into video buffer. This
+ buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
+ @param[in] BltOperation - Operation to perform on BlitBuffer and video memory
+ @param[in] SourceX - X coordinate of source for the BltBuffer.
+ @param[in] SourceY - Y coordinate of source for the BltBuffer.
+ @param[in] DestinationX - X coordinate of destination for the BltBuffer.
+ @param[in] DestinationY - Y coordinate of destination for the BltBuffer.
+ @param[in] Width - Width of rectangle in BltBuffer in pixels.
+ @param[in] Height - Height of rectangle in BltBuffer in pixels.
+ @param[in] Delta - OPTIONAL
+
+ @retval EFI_SUCCESS - The Blt operation completed.
+ @retval EFI_INVALID_PARAMETER - BltOperation is not valid.
+ @retval EFI_DEVICE_ERROR - A hardware error occurred writing to the video buffer.
+
+--*/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT) (
+ IN EFI_UGA_DRAW_PROTOCOL * This,
+ IN EFI_UGA_PIXEL * BltBuffer, OPTIONAL
+ IN EFI_UGA_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+ );
+
+struct _EFI_UGA_DRAW_PROTOCOL {
+ EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode;
+ EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode;
+ EFI_UGA_DRAW_PROTOCOL_BLT Blt;
+};
+
+extern EFI_GUID gEfiUgaDrawProtocolGuid;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/RiscV64/ProcessorBind.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/RiscV64/ProcessorBind.h
new file mode 100644
index 00000000..3446334d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/RiscV64/ProcessorBind.h
@@ -0,0 +1,85 @@
+/** @file
+ Processor or Compiler specific defines and types for RISC-V.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+//
+// Define the processor type so other code can make processor based choices
+//
+#define MDE_CPU_RISCV64
+
+//
+// Make sure we are using the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+//
+// Use ANSI C 2000 stdint.h integer width declarations
+//
+#include <stdint.h>
+typedef uint8_t BOOLEAN;
+typedef int8_t INT8;
+typedef uint8_t UINT8;
+typedef int16_t INT16;
+typedef uint16_t UINT16;
+typedef int32_t INT32;
+typedef uint32_t UINT32;
+typedef int64_t INT64;
+typedef uint64_t UINT64;
+typedef char CHAR8;
+typedef uint16_t CHAR16;
+
+//
+// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
+// 8 bytes on supported 64-bit processor instructions)
+//
+typedef UINT64 UINTN;
+
+//
+// Signed value of native width. (4 bytes on supported 32-bit processor instructions,
+// 8 bytes on supported 64-bit processor instructions)
+//
+typedef INT64 INTN;
+
+//
+// Processor specific defines
+//
+
+//
+// A value of native width with the highest bit set.
+//
+#define MAX_BIT 0x8000000000000000
+
+//
+// A value of native width with the two highest bits set.
+//
+#define MAX_2_BITS 0xC000000000000000
+
+//
+// The stack alignment required for RISC-V
+//
+#define CPU_STACK_ALIGNMENT 16
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#define EFIAPI
+
+#if defined(__GNUC__)
+ //
+ // For GNU assembly code, .global or .globl can declare global symbols.
+ // Define this macro to unify the usage.
+ //
+ #define ASM_GLOBAL .globl
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/X64/ProcessorBind.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/X64/ProcessorBind.h
new file mode 100644
index 00000000..31ce7bba
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Include/X64/ProcessorBind.h
@@ -0,0 +1,185 @@
+/** @file
+ Processor or Compiler specific defines and types x64 (Intel(r) EM64T, AMD64).
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+//
+// Define the processor type so other code can make processor based choices
+//
+#define MDE_CPU_X64
+
+
+//
+// Make sure we are useing the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+
+#if _MSC_EXTENSIONS
+
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning ( disable : 4214 )
+
+//
+// Disabling the unreferenced formal parameter warnings.
+//
+#pragma warning ( disable : 4100 )
+
+//
+// Disable slightly different base types warning as CHAR8 * can not be set
+// to a constant string.
+//
+#pragma warning ( disable : 4057 )
+
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning
+//
+#pragma warning ( disable : 4127 )
+
+
+#endif
+
+
+#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)
+ //
+ // No ANSI C 2000 stdint.h integer width declarations, so define equivalents
+ //
+
+ #if _MSC_EXTENSIONS
+
+
+ //
+ // use Microsoft C compiler dependent integer width types
+ //
+ typedef unsigned __int64 UINT64;
+ typedef __int64 INT64;
+ typedef unsigned __int32 UINT32;
+ typedef __int32 INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #else
+ #ifdef _EFI_P64
+ //
+ // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints
+ // are 32-bits
+ //
+ typedef unsigned long long UINT64;
+ typedef long long INT64;
+ typedef unsigned int UINT32;
+ typedef int INT32;
+ typedef unsigned short CHAR16;
+ typedef unsigned short UINT16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #else
+ //
+ // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit.
+ //
+ typedef unsigned long UINT64;
+ typedef long INT64;
+ typedef unsigned int UINT32;
+ typedef int INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #endif
+ #endif
+
+ #if !defined(UINT8_MAX) || !defined(VBOX) /* collides with iprt/stdint.h */
+ #define UINT8_MAX 0xff
+ #endif
+
+#else
+ //
+ // Use ANSI C 2000 stdint.h integer width declarations
+ //
+ #include <stdint.h>
+ typedef uint8_t BOOLEAN;
+ typedef int8_t INT8;
+ typedef uint8_t UINT8;
+ typedef int16_t INT16;
+ typedef uint16_t UINT16;
+ typedef int32_t INT32;
+ typedef uint32_t UINT32;
+ typedef int64_t INT64;
+ typedef uint64_t UINT64;
+ typedef char CHAR8;
+ typedef uint16_t CHAR16;
+
+#endif
+
+typedef UINT64 UINTN;
+typedef INT64 INTN;
+
+
+//
+// Processor specific defines
+//
+#define MAX_BIT 0x8000000000000000ULL
+#define MAX_2_BITS 0xC000000000000000ULL
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#if _MSC_EXTENSIONS
+ ///
+ /// Define the standard calling convention regardless of optimization level.
+ /// __cdecl is Microsoft* specific C extension.
+ ///
+ #define EFIAPI __cdecl
+#elif __GNUC__
+ ///
+ /// Define the standard calling convention regardless of optimization level.
+ /// efidecl is an extension to GCC that supports the differnece between x64
+ /// GCC ABI and x64 Microsoft* ABI. EFI is closer to the Microsoft* ABI and
+ /// EFIAPI makes sure the right ABI is used for public interfaces.
+ /// eficecl is a work in progress and we do not yet have the compiler
+ ///
+ #define EFIAPI
+#else
+ #define EFIAPI
+#endif
+
+//
+// The Microsoft* C compiler can removed references to unreferenced data items
+// if the /OPT:REF linker option is used. We defined a macro as this is a
+// a non standard extension
+//
+#if _MSC_EXTENSIONS
+ #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
+#else
+ #define GLOBAL_REMOVE_IF_UNREFERENCED
+#endif
+
+#endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/GNUmakefile
new file mode 100644
index 00000000..d8eb9cb4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/GNUmakefile
@@ -0,0 +1,27 @@
+## @file
+# GNU/Linux makefile for 'LzmaCompress' module build.
+#
+# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = LzmaCompress
+
+LIBS = -lCommon
+
+SDK_C = Sdk/C
+
+OBJECTS = \
+ LzmaCompress.o \
+ $(SDK_C)/Alloc.o \
+ $(SDK_C)/LzFind.o \
+ $(SDK_C)/LzmaDec.o \
+ $(SDK_C)/LzmaEnc.o \
+ $(SDK_C)/7zFile.o \
+ $(SDK_C)/7zStream.o \
+ $(SDK_C)/Bra86.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+BUILD_CFLAGS += -D_7ZIP_ST
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt
new file mode 100644
index 00000000..553eacea
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt
@@ -0,0 +1,3 @@
+LzmaCompress is based on the LZMA SDK 19.00. LZMA SDK 19.00
+was placed in the public domain on 2019-02-21. It was
+released on the http://www.7-zip.org/sdk.html website.
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaCompress.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaCompress.c
new file mode 100644
index 00000000..1ecc51c5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaCompress.c
@@ -0,0 +1,406 @@
+/** @file
+ LZMA Compress/Decompress tool (LzmaCompress)
+
+ Based on LZMA SDK 19.00:
+ LzmaUtil.c -- Test application for LZMA compression
+ 2019-02-21 : Igor Pavlov : Public domain
+
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Sdk/C/Alloc.h"
+#include "Sdk/C/7zFile.h"
+#include "Sdk/C/7zVersion.h"
+#include "Sdk/C/LzmaDec.h"
+#include "Sdk/C/LzmaEnc.h"
+#include "Sdk/C/Bra.h"
+#include "CommonLib.h"
+#include "ParseInf.h"
+
+#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
+
+typedef enum {
+ NoConverter,
+ X86Converter,
+ MaxConverter
+} CONVERTER_TYPE;
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+const char *kDataErrorMessage = "Data error";
+const char *kInvalidParamValMessage = "Invalid parameter value";
+
+static BoolInt mQuietMode = False;
+static CONVERTER_TYPE mConType = NoConverter;
+
+UINT64 mDictionarySize = 28;
+UINT64 mCompressionMode = 2;
+
+#define UTILITY_NAME "LzmaCompress"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 2
+#define INTEL_COPYRIGHT \
+ "Copyright (c) 2009-2018, Intel Corporation. All rights reserved."
+void PrintHelp(char *buffer)
+{
+ strcat(buffer,
+ "\n" UTILITY_NAME " - " INTEL_COPYRIGHT "\n"
+ "Based on LZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
+ "\nUsage: LzmaCompress -e|-d [options] <inputFile>\n"
+ " -e: encode file\n"
+ " -d: decode file\n"
+ " -o FileName, --output FileName: specify the output filename\n"
+ " --f86: enable converter for x86 code\n"
+ " -v, --verbose: increase output messages\n"
+ " -q, --quiet: reduce output messages\n"
+ " --debug [0-9]: set debug level\n"
+ " -a: set compression mode 0 = fast, 1 = normal, default: 1 (normal)\n"
+ " d: sets Dictionary size - [0, 27], default: 24 (16MB)\n"
+ " --version: display the program version and exit\n"
+ " -h, --help: display this help text\n"
+ );
+}
+
+int PrintError(char *buffer, const char *message)
+{
+ strcat(buffer, "\nError: ");
+ strcat(buffer, message);
+ strcat(buffer, "\n");
+ return 1;
+}
+
+int PrintErrorNumber(char *buffer, SRes val)
+{
+ sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
+ return 1;
+}
+
+int PrintUserError(char *buffer)
+{
+ return PrintError(buffer, "Incorrect command");
+}
+
+void PrintVersion(char *buffer)
+{
+ sprintf (buffer, "%s Version %d.%d %s ", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, CLzmaEncProps *props)
+{
+ SRes res;
+ size_t inSize = (size_t)fileSize;
+ Byte *inBuffer = 0;
+ Byte *outBuffer = 0;
+ Byte *filteredStream = 0;
+ size_t outSize;
+
+ if (inSize != 0) {
+ inBuffer = (Byte *)MyAlloc(inSize);
+ if (inBuffer == 0)
+ return SZ_ERROR_MEM;
+ } else {
+ return SZ_ERROR_INPUT_EOF;
+ }
+
+ if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {
+ res = SZ_ERROR_READ;
+ goto Done;
+ }
+
+ // we allocate 105% of original size + 64KB for output buffer
+ outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
+ outBuffer = (Byte *)MyAlloc(outSize);
+ if (outBuffer == 0) {
+ res = SZ_ERROR_MEM;
+ goto Done;
+ }
+
+ {
+ int i;
+ for (i = 0; i < 8; i++)
+ outBuffer[i + LZMA_PROPS_SIZE] = (Byte)(fileSize >> (8 * i));
+ }
+
+ if (mConType != NoConverter)
+ {
+ filteredStream = (Byte *)MyAlloc(inSize);
+ if (filteredStream == 0) {
+ res = SZ_ERROR_MEM;
+ goto Done;
+ }
+ memcpy(filteredStream, inBuffer, inSize);
+
+ if (mConType == X86Converter) {
+ {
+ UInt32 x86State;
+ x86_Convert_Init(x86State);
+ x86_Convert(filteredStream, (SizeT) inSize, 0, &x86State, 1);
+ }
+ }
+ }
+
+ {
+ size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE;
+ size_t outPropsSize = LZMA_PROPS_SIZE;
+
+ res = LzmaEncode(outBuffer + LZMA_HEADER_SIZE, &outSizeProcessed,
+ mConType != NoConverter ? filteredStream : inBuffer, inSize,
+ props, outBuffer, &outPropsSize, 0,
+ NULL, &g_Alloc, &g_Alloc);
+
+ if (res != SZ_OK)
+ goto Done;
+
+ outSize = LZMA_HEADER_SIZE + outSizeProcessed;
+ }
+
+ if (outStream->Write(outStream, outBuffer, outSize) != outSize)
+ res = SZ_ERROR_WRITE;
+
+Done:
+ MyFree(outBuffer);
+ MyFree(inBuffer);
+ MyFree(filteredStream);
+
+ return res;
+}
+
+static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize)
+{
+ SRes res;
+ size_t inSize = (size_t)fileSize;
+ Byte *inBuffer = 0;
+ Byte *outBuffer = 0;
+ size_t outSize = 0;
+ size_t inSizePure;
+ ELzmaStatus status;
+ UInt64 outSize64 = 0;
+
+ int i;
+
+ if (inSize < LZMA_HEADER_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+
+ inBuffer = (Byte *)MyAlloc(inSize);
+ if (inBuffer == 0)
+ return SZ_ERROR_MEM;
+
+ if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) {
+ res = SZ_ERROR_READ;
+ goto Done;
+ }
+
+ for (i = 0; i < 8; i++)
+ outSize64 += ((UInt64)inBuffer[LZMA_PROPS_SIZE + i]) << (i * 8);
+
+ outSize = (size_t)outSize64;
+ if (outSize != 0) {
+ outBuffer = (Byte *)MyAlloc(outSize);
+ if (outBuffer == 0) {
+ res = SZ_ERROR_MEM;
+ goto Done;
+ }
+ } else {
+ res = SZ_OK;
+ goto Done;
+ }
+
+ inSizePure = inSize - LZMA_HEADER_SIZE;
+ res = LzmaDecode(outBuffer, &outSize, inBuffer + LZMA_HEADER_SIZE, &inSizePure,
+ inBuffer, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc);
+
+ if (res != SZ_OK)
+ goto Done;
+
+ if (mConType == X86Converter)
+ {
+ UInt32 x86State;
+ x86_Convert_Init(x86State);
+ x86_Convert(outBuffer, (SizeT) outSize, 0, &x86State, 0);
+ }
+
+ if (outStream->Write(outStream, outBuffer, outSize) != outSize)
+ res = SZ_ERROR_WRITE;
+
+Done:
+ MyFree(outBuffer);
+ MyFree(inBuffer);
+
+ return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+ CFileSeqInStream inStream;
+ CFileOutStream outStream;
+ int res;
+ int encodeMode = 0;
+ BoolInt modeWasSet = False;
+ const char *inputFile = NULL;
+ const char *outputFile = "file.tmp";
+ int param;
+ UInt64 fileSize;
+ CLzmaEncProps props;
+
+ LzmaEncProps_Init(&props);
+ LzmaEncProps_Normalize(&props);
+
+ FileSeqInStream_CreateVTable(&inStream);
+ File_Construct(&inStream.file);
+
+ FileOutStream_CreateVTable(&outStream);
+ File_Construct(&outStream.file);
+
+ if (numArgs == 1)
+ {
+ PrintHelp(rs);
+ return 0;
+ }
+
+ for (param = 1; param < numArgs; param++) {
+ if (strcmp(args[param], "-e") == 0 || strcmp(args[param], "-d") == 0) {
+ encodeMode = (args[param][1] == 'e');
+ modeWasSet = True;
+#ifdef VBOX_LZMA_F86_COMPRESS
+ mConType = X86Converter;
+#endif
+ } else if (strcmp(args[param], "--f86") == 0) {
+ mConType = X86Converter;
+ } else if (strcmp(args[param], "-o") == 0 ||
+ strcmp(args[param], "--output") == 0) {
+ if (numArgs < (param + 2)) {
+ return PrintUserError(rs);
+ }
+ outputFile = args[++param];
+ } else if (strcmp(args[param], "--debug") == 0) {
+ if (numArgs < (param + 2)) {
+ return PrintUserError(rs);
+ }
+ //
+ // For now we silently ignore this parameter to achieve command line
+ // parameter compatibility with other build tools.
+ //
+ param++;
+ } else if (strcmp(args[param], "-a") == 0) {
+ AsciiStringToUint64(args[param + 1],FALSE,&mCompressionMode);
+ if ((mCompressionMode == 0)||(mCompressionMode == 1)){
+ props.algo = (int)mCompressionMode;
+ param++;
+ continue;
+ } else {
+ return PrintError(rs, kInvalidParamValMessage);
+ }
+ } else if (strcmp(args[param], "d") == 0) {
+ AsciiStringToUint64(args[param + 1],FALSE,&mDictionarySize);
+ if (mDictionarySize <= 27) {
+ if (mDictionarySize == 0) {
+ props.dictSize = 0;
+ } else {
+ props.dictSize = (1 << mDictionarySize);
+ }
+ param++;
+ continue;
+ } else {
+ return PrintError(rs, kInvalidParamValMessage);
+ }
+ } else if (
+ strcmp(args[param], "-h") == 0 ||
+ strcmp(args[param], "--help") == 0
+ ) {
+ PrintHelp(rs);
+ return 0;
+ } else if (
+ strcmp(args[param], "-v") == 0 ||
+ strcmp(args[param], "--verbose") == 0
+ ) {
+ //
+ // For now we silently ignore this parameter to achieve command line
+ // parameter compatibility with other build tools.
+ //
+ } else if (
+ strcmp(args[param], "-q") == 0 ||
+ strcmp(args[param], "--quiet") == 0
+ ) {
+ mQuietMode = True;
+ } else if (strcmp(args[param], "--version") == 0) {
+ PrintVersion(rs);
+ return 0;
+ } else if (inputFile == NULL) {
+ inputFile = args[param];
+ } else {
+ return PrintUserError(rs);
+ }
+ }
+
+ if ((inputFile == NULL) || !modeWasSet) {
+ return PrintUserError(rs);
+ }
+
+ {
+ size_t t4 = sizeof(UInt32);
+ size_t t8 = sizeof(UInt64);
+ if (t4 != 4 || t8 != 8)
+ return PrintError(rs, "Incorrect UInt32 or UInt64");
+ }
+
+ if (InFile_Open(&inStream.file, inputFile) != 0)
+ return PrintError(rs, "Can not open input file");
+
+ if (OutFile_Open(&outStream.file, outputFile) != 0) {
+ File_Close(&inStream.file);
+ return PrintError(rs, "Can not open output file");
+ }
+
+ File_GetLength(&inStream.file, &fileSize);
+
+ if (encodeMode)
+ {
+ if (!mQuietMode) {
+ printf("Encoding\n");
+ }
+ res = Encode(&outStream.vt, &inStream.vt, fileSize, &props);
+ }
+ else
+ {
+ if (!mQuietMode) {
+ printf("Decoding\n");
+ }
+ res = Decode(&outStream.vt, &inStream.vt, fileSize);
+ }
+
+ File_Close(&outStream.file);
+ File_Close(&inStream.file);
+
+ if (res != SZ_OK)
+ {
+ if (res == SZ_ERROR_MEM)
+ return PrintError(rs, kCantAllocateMessage);
+ else if (res == SZ_ERROR_DATA)
+ return PrintError(rs, kDataErrorMessage);
+ else if (res == SZ_ERROR_WRITE)
+ return PrintError(rs, kCantWriteMessage);
+ else if (res == SZ_ERROR_READ)
+ return PrintError(rs, kCantReadMessage);
+ return PrintErrorNumber(rs, res);
+ }
+ return 0;
+}
+
+int MY_CDECL main(int numArgs, const char *args[])
+{
+ char rs[2000] = { 0 };
+ int res = main2(numArgs, args, rs);
+ if (strlen(rs) > 0) {
+ puts(rs);
+ }
+ return res;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaF86Compress.bat b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaF86Compress.bat
new file mode 100644
index 00000000..95b96564
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/LzmaF86Compress.bat
@@ -0,0 +1,26 @@
+@REM @file
+@REM This script will exec LzmaCompress tool with --f86 option that enables
+@REM converter for x86 code.
+@REM
+@REM Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+@setlocal
+
+:Begin
+if "%1"=="" goto End
+if "%1"=="-e" (
+ set FLAG=--f86
+)
+if "%1"=="-d" (
+ set FLAG=--f86
+)
+set ARGS=%ARGS% %1
+shift
+goto Begin
+
+:End
+LzmaCompress %ARGS% %FLAG%
+@echo on
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile
new file mode 100644
index 00000000..2f410a1e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile
@@ -0,0 +1,37 @@
+## @file
+# Windows makefile for 'LzmaCompress' module build.
+#
+# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = LzmaCompress
+
+LIBS = $(LIB_PATH)\Common.lib
+
+SDK_C = Sdk\C
+
+OBJECTS = \
+ LzmaCompress.obj \
+ $(SDK_C)\Alloc.obj \
+ $(SDK_C)\LzFind.obj \
+ $(SDK_C)\LzmaDec.obj \
+ $(SDK_C)\LzmaEnc.obj \
+ $(SDK_C)\7zFile.obj \
+ $(SDK_C)\7zStream.obj \
+ $(SDK_C)\Bra86.obj \
+ $(SDK_C)\LzFindMt.obj \
+ $(SDK_C)\Threads.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
+all: $(BIN_PATH)\LzmaF86Compress.bat
+
+$(BIN_PATH)\LzmaF86Compress.bat: LzmaF86Compress.bat
+ copy LzmaF86Compress.bat $(BIN_PATH)\LzmaF86Compress.bat /Y
+
+cleanall: localCleanall
+
+localCleanall:
+ del /f /q $(BIN_PATH)\LzmaF86Compress.bat > nul
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile.kmk
new file mode 100644
index 00000000..846c9fab
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Makefile.kmk
@@ -0,0 +1,58 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI LzmaCompress build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += LzmaCompress
+LzmaCompress_TEMPLATE = VBoxEfiBldProg
+LzmaCompress_DEFS = _7ZIP_ST
+LzmaCompress_SOURCES = \
+ LzmaCompress.c \
+ Sdk/C/Alloc.c \
+ Sdk/C/LzFind.c \
+ Sdk/C/LzmaDec.c \
+ Sdk/C/LzmaEnc.c \
+ Sdk/C/7zFile.c \
+ Sdk/C/7zStream.c \
+ Sdk/C/Bra86.c
+
+BLDPROGS += LzmaF86Compress
+LzmaF86Compress_EXTENDS = LzmaCompress
+LzmaF86Compress_DEFS = VBOX_LZMA_F86_COMPRESS _7ZIP_ST
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
new file mode 100644
index 00000000..40aa2411
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
@@ -0,0 +1,286 @@
+/* 7zFile.c -- File IO
+2017-04-03 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "7zFile.h"
+
+#ifndef USE_WINDOWS_FILE
+
+#ifndef UNDER_CE
+#include <errno.h>
+#endif
+
+#else
+
+/*
+ ReadFile and WriteFile functions in Windows have BUG:
+ If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+ from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+ (Insufficient system resources exist to complete the requested service).
+ Probably in some version of Windows there are problems with other sizes:
+ for 32 MB (maybe also for 16 MB).
+ And message can be "Network connection was lost"
+*/
+
+#define kChunkSizeMax (1 << 22)
+
+#endif
+
+void File_Construct(CSzFile *p)
+{
+ #ifdef USE_WINDOWS_FILE
+ p->handle = INVALID_HANDLE_VALUE;
+ #else
+ p->file = NULL;
+ #endif
+}
+
+#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
+static WRes File_Open(CSzFile *p, const char *name, int writeMode)
+{
+ #ifdef USE_WINDOWS_FILE
+ p->handle = CreateFileA(name,
+ writeMode ? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ, NULL,
+ writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
+ #else
+ p->file = fopen(name, writeMode ? "wb+" : "rb");
+ return (p->file != 0) ? 0 :
+ #ifdef UNDER_CE
+ 2; /* ENOENT */
+ #else
+ errno;
+ #endif
+ #endif
+}
+
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
+#endif
+
+#ifdef USE_WINDOWS_FILE
+static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
+{
+ p->handle = CreateFileW(name,
+ writeMode ? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ, NULL,
+ writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
+}
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
+#endif
+
+WRes File_Close(CSzFile *p)
+{
+ #ifdef USE_WINDOWS_FILE
+ if (p->handle != INVALID_HANDLE_VALUE)
+ {
+ if (!CloseHandle(p->handle))
+ return GetLastError();
+ p->handle = INVALID_HANDLE_VALUE;
+ }
+ #else
+ if (p->file != NULL)
+ {
+ int res = fclose(p->file);
+ if (res != 0)
+ return res;
+ p->file = NULL;
+ }
+ #endif
+ return 0;
+}
+
+WRes File_Read(CSzFile *p, void *data, size_t *size)
+{
+ size_t originalSize = *size;
+ if (originalSize == 0)
+ return 0;
+
+ #ifdef USE_WINDOWS_FILE
+
+ *size = 0;
+ do
+ {
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
+ DWORD processed = 0;
+ BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
+ data = (void *)((Byte *)data + processed);
+ originalSize -= processed;
+ *size += processed;
+ if (!res)
+ return GetLastError();
+ if (processed == 0)
+ break;
+ }
+ while (originalSize > 0);
+ return 0;
+
+ #else
+
+ *size = fread(data, 1, originalSize, p->file);
+ if (*size == originalSize)
+ return 0;
+ return ferror(p->file);
+
+ #endif
+}
+
+WRes File_Write(CSzFile *p, const void *data, size_t *size)
+{
+ size_t originalSize = *size;
+ if (originalSize == 0)
+ return 0;
+
+ #ifdef USE_WINDOWS_FILE
+
+ *size = 0;
+ do
+ {
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
+ DWORD processed = 0;
+ BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
+ data = (void *)((Byte *)data + processed);
+ originalSize -= processed;
+ *size += processed;
+ if (!res)
+ return GetLastError();
+ if (processed == 0)
+ break;
+ }
+ while (originalSize > 0);
+ return 0;
+
+ #else
+
+ *size = fwrite(data, 1, originalSize, p->file);
+ if (*size == originalSize)
+ return 0;
+ return ferror(p->file);
+
+ #endif
+}
+
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
+{
+ #ifdef USE_WINDOWS_FILE
+
+ LARGE_INTEGER value;
+ DWORD moveMethod;
+ value.LowPart = (DWORD)*pos;
+ value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
+ switch (origin)
+ {
+ case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
+ case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
+ case SZ_SEEK_END: moveMethod = FILE_END; break;
+ default: return ERROR_INVALID_PARAMETER;
+ }
+ value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
+ if (value.LowPart == 0xFFFFFFFF)
+ {
+ WRes res = GetLastError();
+ if (res != NO_ERROR)
+ return res;
+ }
+ *pos = ((Int64)value.HighPart << 32) | value.LowPart;
+ return 0;
+
+ #else
+
+ int moveMethod;
+ int res;
+ switch (origin)
+ {
+ case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
+ case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
+ case SZ_SEEK_END: moveMethod = SEEK_END; break;
+ default: return 1;
+ }
+ res = fseek(p->file, (long)*pos, moveMethod);
+ *pos = ftell(p->file);
+ return res;
+
+ #endif
+}
+
+WRes File_GetLength(CSzFile *p, UInt64 *length)
+{
+ #ifdef USE_WINDOWS_FILE
+
+ DWORD sizeHigh;
+ DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
+ if (sizeLow == 0xFFFFFFFF)
+ {
+ DWORD res = GetLastError();
+ if (res != NO_ERROR)
+ return res;
+ }
+ *length = (((UInt64)sizeHigh) << 32) + sizeLow;
+ return 0;
+
+ #else
+
+ long pos = ftell(p->file);
+ int res = fseek(p->file, 0, SEEK_END);
+ *length = ftell(p->file);
+ fseek(p->file, pos, SEEK_SET);
+ return res;
+
+ #endif
+}
+
+
+/* ---------- FileSeqInStream ---------- */
+
+static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
+{
+ CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
+ return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
+}
+
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
+{
+ p->vt.Read = FileSeqInStream_Read;
+}
+
+
+/* ---------- FileInStream ---------- */
+
+static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
+{
+ CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
+ return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
+}
+
+static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
+{
+ CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
+ return File_Seek(&p->file, pos, origin);
+}
+
+void FileInStream_CreateVTable(CFileInStream *p)
+{
+ p->vt.Read = FileInStream_Read;
+ p->vt.Seek = FileInStream_Seek;
+}
+
+
+/* ---------- FileOutStream ---------- */
+
+static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
+{
+ CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
+ File_Write(&p->file, data, &size);
+ return size;
+}
+
+void FileOutStream_CreateVTable(CFileOutStream *p)
+{
+ p->vt.Write = FileOutStream_Write;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h
new file mode 100644
index 00000000..ee3b003a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h
@@ -0,0 +1,87 @@
+/* 7zFile.h -- File IO
+2017-04-03 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_FILE_H
+#define __7Z_FILE_H
+
+#ifdef _WIN32
+#define USE_WINDOWS_FILE
+#endif
+
+#ifdef USE_WINDOWS_FILE
+# ifdef VBOX
+# include <iprt/win/windows.h>
+# else
+#include <windows.h>
+# endif
+#else
+#include <stdio.h>
+#endif
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/* ---------- File ---------- */
+
+typedef struct
+{
+ #ifdef USE_WINDOWS_FILE
+ HANDLE handle;
+ #else
+ FILE *file;
+ #endif
+} CSzFile;
+
+void File_Construct(CSzFile *p);
+#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
+WRes InFile_Open(CSzFile *p, const char *name);
+WRes OutFile_Open(CSzFile *p, const char *name);
+#endif
+#ifdef USE_WINDOWS_FILE
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
+#endif
+WRes File_Close(CSzFile *p);
+
+/* reads max(*size, remain file's size) bytes */
+WRes File_Read(CSzFile *p, void *data, size_t *size);
+
+/* writes *size bytes */
+WRes File_Write(CSzFile *p, const void *data, size_t *size);
+
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
+WRes File_GetLength(CSzFile *p, UInt64 *length);
+
+
+/* ---------- FileInStream ---------- */
+
+typedef struct
+{
+ ISeqInStream vt;
+ CSzFile file;
+} CFileSeqInStream;
+
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
+
+
+typedef struct
+{
+ ISeekInStream vt;
+ CSzFile file;
+} CFileInStream;
+
+void FileInStream_CreateVTable(CFileInStream *p);
+
+
+typedef struct
+{
+ ISeqOutStream vt;
+ CSzFile file;
+} CFileOutStream;
+
+void FileOutStream_CreateVTable(CFileOutStream *p);
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c
new file mode 100644
index 00000000..6b5aa162
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c
@@ -0,0 +1,176 @@
+/* 7zStream.c -- 7z Stream functions
+2017-04-03 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+#include "7zTypes.h"
+
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+{
+ while (size != 0)
+ {
+ size_t processed = size;
+ RINOK(ISeqInStream_Read(stream, buf, &processed));
+ if (processed == 0)
+ return errorType;
+ buf = (void *)((Byte *)buf + processed);
+ size -= processed;
+ }
+ return SZ_OK;
+}
+
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
+{
+ return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
+{
+ size_t processed = 1;
+ RINOK(ISeqInStream_Read(stream, buf, &processed));
+ return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
+}
+
+
+
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
+{
+ Int64 t = offset;
+ return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
+}
+
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
+{
+ const void *lookBuf;
+ if (*size == 0)
+ return SZ_OK;
+ RINOK(ILookInStream_Look(stream, &lookBuf, size));
+ memcpy(buf, lookBuf, *size);
+ return ILookInStream_Skip(stream, *size);
+}
+
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
+{
+ while (size != 0)
+ {
+ size_t processed = size;
+ RINOK(ILookInStream_Read(stream, buf, &processed));
+ if (processed == 0)
+ return errorType;
+ buf = (void *)((Byte *)buf + processed);
+ size -= processed;
+ }
+ return SZ_OK;
+}
+
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
+{
+ return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+
+
+#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
+
+static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
+{
+ SRes res = SZ_OK;
+ GET_LookToRead2
+ size_t size2 = p->size - p->pos;
+ if (size2 == 0 && *size != 0)
+ {
+ p->pos = 0;
+ p->size = 0;
+ size2 = p->bufSize;
+ res = ISeekInStream_Read(p->realStream, p->buf, &size2);
+ p->size = size2;
+ }
+ if (*size > size2)
+ *size = size2;
+ *buf = p->buf + p->pos;
+ return res;
+}
+
+static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
+{
+ SRes res = SZ_OK;
+ GET_LookToRead2
+ size_t size2 = p->size - p->pos;
+ if (size2 == 0 && *size != 0)
+ {
+ p->pos = 0;
+ p->size = 0;
+ if (*size > p->bufSize)
+ *size = p->bufSize;
+ res = ISeekInStream_Read(p->realStream, p->buf, size);
+ size2 = p->size = *size;
+ }
+ if (*size > size2)
+ *size = size2;
+ *buf = p->buf + p->pos;
+ return res;
+}
+
+static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
+{
+ GET_LookToRead2
+ p->pos += offset;
+ return SZ_OK;
+}
+
+static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
+{
+ GET_LookToRead2
+ size_t rem = p->size - p->pos;
+ if (rem == 0)
+ return ISeekInStream_Read(p->realStream, buf, size);
+ if (rem > *size)
+ rem = *size;
+ memcpy(buf, p->buf + p->pos, rem);
+ p->pos += rem;
+ *size = rem;
+ return SZ_OK;
+}
+
+static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
+{
+ GET_LookToRead2
+ p->pos = p->size = 0;
+ return ISeekInStream_Seek(p->realStream, pos, origin);
+}
+
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
+{
+ p->vt.Look = lookahead ?
+ LookToRead2_Look_Lookahead :
+ LookToRead2_Look_Exact;
+ p->vt.Skip = LookToRead2_Skip;
+ p->vt.Read = LookToRead2_Read;
+ p->vt.Seek = LookToRead2_Seek;
+}
+
+
+
+static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
+{
+ CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
+ return LookInStream_LookRead(p->realStream, buf, size);
+}
+
+void SecToLook_CreateVTable(CSecToLook *p)
+{
+ p->vt.Read = SecToLook_Read;
+}
+
+static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
+{
+ CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
+ return ILookInStream_Read(p->realStream, buf, size);
+}
+
+void SecToRead_CreateVTable(CSecToRead *p)
+{
+ p->vt.Read = SecToRead_Read;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h
new file mode 100644
index 00000000..7a9cadb9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h
@@ -0,0 +1,375 @@
+/* 7zTypes.h -- Basic types
+2018-08-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#ifdef _WIN32
+/* #include <windows.h> */
+#endif
+
+#include <stddef.h>
+
+#ifndef EXTERN_C_BEGIN
+#ifdef __cplusplus
+#define EXTERN_C_BEGIN extern "C" {
+#define EXTERN_C_END }
+#else
+#define EXTERN_C_BEGIN
+#define EXTERN_C_END
+#endif
+#endif
+
+EXTERN_C_BEGIN
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+
+#ifdef _WIN32
+
+/* typedef DWORD WRes; */
+typedef unsigned WRes;
+#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
+
+#else
+
+typedef int WRes;
+#define MY__FACILITY_WIN32 7
+#define MY__FACILITY__WRes MY__FACILITY_WIN32
+#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
+
+#endif
+
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+ NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#define UINT64_CONST(n) n
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#define UINT64_CONST(n) n ## ULL
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int BoolInt;
+/* typedef BoolInt Bool; */
+#define True 1
+#define False 0
+
+
+#ifdef _WIN32
+#define MY_STD_CALL __stdcall
+#else
+#define MY_STD_CALL
+#endif
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_FORCE_INLINE __forceinline
+
+#define MY_CDECL __cdecl
+#define MY_FAST_CALL __fastcall
+
+#else
+
+#define MY_NO_INLINE
+#define MY_FORCE_INLINE
+#define MY_CDECL
+#define MY_FAST_CALL
+
+/* inline keyword : for C++ / C99 */
+
+/* GCC, clang: */
+/*
+#if defined (__GNUC__) && (__GNUC__ >= 4)
+#define MY_FORCE_INLINE __attribute__((always_inline))
+#define MY_NO_INLINE __attribute__((noinline))
+#endif
+*/
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct IByteIn IByteIn;
+struct IByteIn
+{
+ Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
+};
+#define IByteIn_Read(p) (p)->Read(p)
+
+
+typedef struct IByteOut IByteOut;
+struct IByteOut
+{
+ void (*Write)(const IByteOut *p, Byte b);
+};
+#define IByteOut_Write(p, b) (p)->Write(p, b)
+
+
+typedef struct ISeqInStream ISeqInStream;
+struct ISeqInStream
+{
+ SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) < input(*size)) is allowed */
+};
+#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
+
+
+typedef struct ISeqOutStream ISeqOutStream;
+struct ISeqOutStream
+{
+ size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
+ /* Returns: result - the number of actually written bytes.
+ (result < size) means error */
+};
+#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
+
+typedef enum
+{
+ SZ_SEEK_SET = 0,
+ SZ_SEEK_CUR = 1,
+ SZ_SEEK_END = 2
+} ESzSeek;
+
+
+typedef struct ISeekInStream ISeekInStream;
+struct ISeekInStream
+{
+ SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
+ SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
+};
+#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
+#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
+
+
+typedef struct ILookInStream ILookInStream;
+struct ILookInStream
+{
+ SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) > input(*size)) is not allowed
+ (output(*size) < input(*size)) is allowed */
+ SRes (*Skip)(const ILookInStream *p, size_t offset);
+ /* offset must be <= output(*size) of Look */
+
+ SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
+ SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
+};
+
+#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
+#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
+#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
+#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
+
+
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
+
+
+
+typedef struct
+{
+ ILookInStream vt;
+ const ISeekInStream *realStream;
+
+ size_t pos;
+ size_t size; /* it's data size */
+
+ /* the following variables must be set outside */
+ Byte *buf;
+ size_t bufSize;
+} CLookToRead2;
+
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
+
+#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
+
+
+typedef struct
+{
+ ISeqInStream vt;
+ const ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+
+
+typedef struct
+{
+ ISeqInStream vt;
+ const ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+
+typedef struct ICompressProgress ICompressProgress;
+
+struct ICompressProgress
+{
+ SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
+ /* Returns: result. (result != SZ_OK) means break.
+ Value (UInt64)(Int64)-1 for size means unknown value. */
+};
+#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
+
+
+
+typedef struct ISzAlloc ISzAlloc;
+typedef const ISzAlloc * ISzAllocPtr;
+
+struct ISzAlloc
+{
+ void *(*Alloc)(ISzAllocPtr p, size_t size);
+ void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
+};
+
+#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
+#define ISzAlloc_Free(p, a) (p)->Free(p, a)
+
+/* deprecated */
+#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
+#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
+
+
+
+
+
+#ifndef MY_offsetof
+ #ifdef offsetof
+ #define MY_offsetof(type, m) offsetof(type, m)
+ /*
+ #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
+ */
+ #else
+ #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
+ #endif
+#endif
+
+
+
+#ifndef MY_container_of
+
+/*
+#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
+#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
+#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
+#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
+*/
+
+/*
+ GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
+ GCC 3.4.4 : classes with constructor
+ GCC 4.8.1 : classes with non-public variable members"
+*/
+
+#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
+
+
+#endif
+
+#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
+
+/*
+#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+*/
+#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
+
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+/*
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
+*/
+
+
+
+#ifdef _WIN32
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#endif
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h
new file mode 100644
index 00000000..c176823a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h
@@ -0,0 +1,27 @@
+#define MY_VER_MAJOR 19
+#define MY_VER_MINOR 00
+#define MY_VER_BUILD 0
+#define MY_VERSION_NUMBERS "19.00"
+#define MY_VERSION MY_VERSION_NUMBERS
+
+#ifdef MY_CPU_NAME
+ #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
+#else
+ #define MY_VERSION_CPU MY_VERSION
+#endif
+
+#define MY_DATE "2019-02-21"
+#undef MY_COPYRIGHT
+#undef MY_VERSION_COPYRIGHT_DATE
+#define MY_AUTHOR_NAME "Igor Pavlov"
+#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
+
+#ifdef USE_COPYRIGHT_CR
+ #define MY_COPYRIGHT MY_COPYRIGHT_CR
+#else
+ #define MY_COPYRIGHT MY_COPYRIGHT_PD
+#endif
+
+#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c
new file mode 100644
index 00000000..a21de447
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c
@@ -0,0 +1,460 @@
+/* Alloc.c -- Memory allocation functions
+2018-04-27 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <stdio.h>
+
+#ifdef _WIN32
+# ifdef VBOX
+# include <iprt/win/windows.h>
+# else
+#include <windows.h>
+# endif
+#endif
+#include <stdlib.h>
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+
+
+#define CONVERT_INT_TO_STR(charType, tempSize) \
+ unsigned char temp[tempSize]; unsigned i = 0; \
+ while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
+ *s++ = (charType)('0' + (unsigned)val); \
+ while (i != 0) { i--; *s++ = temp[i]; } \
+ *s = 0;
+
+static void ConvertUInt64ToString(UInt64 val, char *s)
+{
+ CONVERT_INT_TO_STR(char, 24);
+}
+
+#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
+
+static void ConvertUInt64ToHex(UInt64 val, char *s)
+{
+ UInt64 v = val;
+ unsigned i;
+ for (i = 1;; i++)
+ {
+ v >>= 4;
+ if (v == 0)
+ break;
+ }
+ s[i] = 0;
+ do
+ {
+ unsigned t = (unsigned)(val & 0xF);
+ val >>= 4;
+ s[--i] = GET_HEX_CHAR(t);
+ }
+ while (i);
+}
+
+#define DEBUG_OUT_STREAM stderr
+
+static void Print(const char *s)
+{
+ fputs(s, DEBUG_OUT_STREAM);
+}
+
+static void PrintAligned(const char *s, size_t align)
+{
+ size_t len = strlen(s);
+ for(;;)
+ {
+ fputc(' ', DEBUG_OUT_STREAM);
+ if (len >= align)
+ break;
+ ++len;
+ }
+ Print(s);
+}
+
+static void PrintLn()
+{
+ Print("\n");
+}
+
+static void PrintHex(UInt64 v, size_t align)
+{
+ char s[32];
+ ConvertUInt64ToHex(v, s);
+ PrintAligned(s, align);
+}
+
+static void PrintDec(UInt64 v, size_t align)
+{
+ char s[32];
+ ConvertUInt64ToString(v, s);
+ PrintAligned(s, align);
+}
+
+static void PrintAddr(void *p)
+{
+ PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
+}
+
+
+#define PRINT_ALLOC(name, cnt, size, ptr) \
+ Print(name " "); \
+ PrintDec(cnt++, 10); \
+ PrintHex(size, 10); \
+ PrintAddr(ptr); \
+ PrintLn();
+
+#define PRINT_FREE(name, cnt, ptr) if (ptr) { \
+ Print(name " "); \
+ PrintDec(--cnt, 10); \
+ PrintAddr(ptr); \
+ PrintLn(); }
+
+#else
+
+#define PRINT_ALLOC(name, cnt, size, ptr)
+#define PRINT_FREE(name, cnt, ptr)
+#define Print(s)
+#define PrintLn()
+#define PrintHex(v, align)
+#define PrintDec(v, align)
+#define PrintAddr(p)
+
+#endif
+
+
+
+void *MyAlloc(size_t size)
+{
+ if (size == 0)
+ return NULL;
+ #ifdef _SZ_ALLOC_DEBUG
+ {
+ void *p = malloc(size);
+ PRINT_ALLOC("Alloc ", g_allocCount, size, p);
+ return p;
+ }
+ #else
+ return malloc(size);
+ #endif
+}
+
+void MyFree(void *address)
+{
+ PRINT_FREE("Free ", g_allocCount, address);
+
+ free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size)
+{
+ if (size == 0)
+ return NULL;
+
+ PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
+
+ return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address)
+{
+ PRINT_FREE("Free-Mid", g_allocCountMid, address);
+
+ if (!address)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#ifndef MEM_LARGE_PAGES
+#undef _7ZIP_LARGE_PAGES
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+SIZE_T g_LargePageSize = 0;
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+#endif
+
+void SetLargePageSize()
+{
+ #ifdef _7ZIP_LARGE_PAGES
+ SIZE_T size;
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (!largePageMinimum)
+ return;
+ size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return;
+ g_LargePageSize = size;
+ #endif
+}
+
+
+void *BigAlloc(size_t size)
+{
+ if (size == 0)
+ return NULL;
+
+ PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
+
+ #ifdef _7ZIP_LARGE_PAGES
+ {
+ SIZE_T ps = g_LargePageSize;
+ if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
+ {
+ size_t size2;
+ ps--;
+ size2 = (size + ps) & ~ps;
+ if (size2 >= size)
+ {
+ void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+ if (res)
+ return res;
+ }
+ }
+ }
+ #endif
+
+ return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address)
+{
+ PRINT_FREE("Free-Big", g_allocCountBig, address);
+
+ if (!address)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
+
+
+static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
+static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
+const ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
+static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
+const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
+
+static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
+static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
+const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
+
+
+/*
+ uintptr_t : <stdint.h> C99 (optional)
+ : unsupported in VS6
+*/
+
+#ifdef _WIN32
+ typedef UINT_PTR UIntPtr;
+#else
+ /*
+ typedef uintptr_t UIntPtr;
+ */
+ typedef ptrdiff_t UIntPtr;
+#endif
+
+
+#define ADJUST_ALLOC_SIZE 0
+/*
+#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
+*/
+/*
+ Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
+ MyAlloc() can return address that is NOT multiple of sizeof(void *).
+*/
+
+
+/*
+#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
+*/
+#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
+
+#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
+
+#if defined(VBOX) && defined(_POSIX_C_SOURCE)
+#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
+ #define USE_posix_memalign
+#endif
+#endif
+
+/*
+ This posix_memalign() is for test purposes only.
+ We also need special Free() function instead of free(),
+ if this posix_memalign() is used.
+*/
+
+/*
+static int posix_memalign(void **ptr, size_t align, size_t size)
+{
+ size_t newSize = size + align;
+ void *p;
+ void *pAligned;
+ *ptr = NULL;
+ if (newSize < size)
+ return 12; // ENOMEM
+ p = MyAlloc(newSize);
+ if (!p)
+ return 12; // ENOMEM
+ pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
+ ((void **)pAligned)[-1] = p;
+ *ptr = pAligned;
+ return 0;
+}
+*/
+
+/*
+ ALLOC_ALIGN_SIZE >= sizeof(void *)
+ ALLOC_ALIGN_SIZE >= cache_line_size
+*/
+
+#define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
+
+static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
+{
+ #ifndef USE_posix_memalign
+
+ void *p;
+ void *pAligned;
+ size_t newSize;
+ UNUSED_VAR(pp);
+
+ /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
+ block to prevent cache line sharing with another allocated blocks */
+
+ newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
+ if (newSize < size)
+ return NULL;
+
+ p = MyAlloc(newSize);
+
+ if (!p)
+ return NULL;
+ pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
+
+ Print(" size="); PrintHex(size, 8);
+ Print(" a_size="); PrintHex(newSize, 8);
+ Print(" ptr="); PrintAddr(p);
+ Print(" a_ptr="); PrintAddr(pAligned);
+ PrintLn();
+
+ ((void **)pAligned)[-1] = p;
+
+ return pAligned;
+
+ #else
+
+ void *p;
+ UNUSED_VAR(pp);
+ if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
+ return NULL;
+
+ Print(" posix_memalign="); PrintAddr(p);
+ PrintLn();
+
+ return p;
+
+ #endif
+}
+
+
+static void SzAlignedFree(ISzAllocPtr pp, void *address)
+{
+ UNUSED_VAR(pp);
+ #ifndef USE_posix_memalign
+ if (address)
+ MyFree(((void **)address)[-1]);
+ #else
+ free(address);
+ #endif
+}
+
+
+const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
+
+
+
+#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
+
+/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
+#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
+/*
+#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
+*/
+
+static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
+{
+ CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
+ void *adr;
+ void *pAligned;
+ size_t newSize;
+ size_t extra;
+ size_t alignSize = (size_t)1 << p->numAlignBits;
+
+ if (alignSize < sizeof(void *))
+ alignSize = sizeof(void *);
+
+ if (p->offset >= alignSize)
+ return NULL;
+
+ /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
+ block to prevent cache line sharing with another allocated blocks */
+ extra = p->offset & (sizeof(void *) - 1);
+ newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
+ if (newSize < size)
+ return NULL;
+
+ adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
+
+ if (!adr)
+ return NULL;
+
+ pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
+ alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
+
+ PrintLn();
+ Print("- Aligned: ");
+ Print(" size="); PrintHex(size, 8);
+ Print(" a_size="); PrintHex(newSize, 8);
+ Print(" ptr="); PrintAddr(adr);
+ Print(" a_ptr="); PrintAddr(pAligned);
+ PrintLn();
+
+ REAL_BLOCK_PTR_VAR(pAligned) = adr;
+
+ return pAligned;
+}
+
+
+static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
+{
+ if (address)
+ {
+ CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
+ PrintLn();
+ Print("- Aligned Free: ");
+ PrintLn();
+ ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
+ }
+}
+
+
+void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
+{
+ p->vt.Alloc = AlignOffsetAlloc_Alloc;
+ p->vt.Free = AlignOffsetAlloc_Free;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h
new file mode 100644
index 00000000..64823764
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h
@@ -0,0 +1,51 @@
+/* Alloc.h -- Memory allocation functions
+2018-02-19 : Igor Pavlov : Public domain */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+void *MyAlloc(size_t size);
+void MyFree(void *address);
+
+#ifdef _WIN32
+
+void SetLargePageSize();
+
+void *MidAlloc(size_t size);
+void MidFree(void *address);
+void *BigAlloc(size_t size);
+void BigFree(void *address);
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+extern const ISzAlloc g_Alloc;
+extern const ISzAlloc g_BigAlloc;
+extern const ISzAlloc g_MidAlloc;
+extern const ISzAlloc g_AlignedAlloc;
+
+
+typedef struct
+{
+ ISzAlloc vt;
+ ISzAllocPtr baseAlloc;
+ unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
+ size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
+} CAlignOffsetAlloc;
+
+void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
+
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra.h
new file mode 100644
index 00000000..184c291a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra.h
@@ -0,0 +1,64 @@
+/* Bra.h -- Branch converters for executables
+2013-01-18 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/*
+These functions convert relative addresses to absolute addresses
+in CALL instructions to increase the compression ratio.
+
+ In:
+ data - data buffer
+ size - size of data
+ ip - current virtual Instruction Pinter (IP) value
+ state - state variable for x86 converter
+ encoding - 0 (for decoding), 1 (for encoding)
+
+ Out:
+ state - state variable for x86 converter
+
+ Returns:
+ The number of processed bytes. If you call these functions with multiple calls,
+ you must start next call with first byte after block of processed bytes.
+
+ Type Endian Alignment LookAhead
+
+ x86 little 1 4
+ ARMT little 2 2
+ ARM little 4 0
+ PPC big 4 0
+ SPARC big 4 0
+ IA64 little 16 0
+
+ size must be >= Alignment + LookAhead, if it's not last block.
+ If (size < Alignment + LookAhead), converter returns 0.
+
+ Example:
+
+ UInt32 ip = 0;
+ for ()
+ {
+ ; size must be >= Alignment + LookAhead, if it's not last block
+ SizeT processed = Convert(data, size, ip, 1);
+ data += processed;
+ size -= processed;
+ ip += processed;
+ }
+*/
+
+#define x86_Convert_Init(state) { state = 0; }
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c
new file mode 100644
index 00000000..93ed4d76
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c
@@ -0,0 +1,82 @@
+/* Bra86.c -- Converter for x86 code (BCJ)
+2017-04-03 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "Bra.h"
+
+#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
+
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
+{
+ SizeT pos = 0;
+ UInt32 mask = *state & 7;
+ if (size < 5)
+ return 0;
+ size -= 4;
+ ip += 5;
+
+ for (;;)
+ {
+ Byte *p = data + pos;
+ const Byte *limit = data + size;
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+
+ {
+ SizeT d = (SizeT)(p - data - pos);
+ pos = (SizeT)(p - data);
+ if (p >= limit)
+ {
+ *state = (d > 2 ? 0 : mask >> (unsigned)d);
+ return pos;
+ }
+ if (d > 2)
+ mask = 0;
+ else
+ {
+ mask >>= (unsigned)d;
+ if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
+ {
+ mask = (mask >> 1) | 4;
+ pos++;
+ continue;
+ }
+ }
+ }
+
+ if (Test86MSByte(p[4]))
+ {
+ UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 cur = ip + (UInt32)pos;
+ pos += 5;
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ if (mask != 0)
+ {
+ unsigned sh = (mask & 6) << 2;
+ if (Test86MSByte((Byte)(v >> sh)))
+ {
+ v ^= (((UInt32)0x100 << sh) - 1);
+ if (encoding)
+ v += cur;
+ else
+ v -= cur;
+ }
+ mask = 0;
+ }
+ p[1] = (Byte)v;
+ p[2] = (Byte)(v >> 8);
+ p[3] = (Byte)(v >> 16);
+ p[4] = (Byte)(0 - ((v >> 24) & 1));
+ }
+ else
+ {
+ mask = (mask >> 1) | 4;
+ pos++;
+ }
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h
new file mode 100644
index 00000000..0cc409d8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h
@@ -0,0 +1,33 @@
+/* Compiler.h
+2017-04-03 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_COMPILER_H
+#define __7Z_COMPILER_H
+
+#ifdef _MSC_VER
+
+ #ifdef UNDER_CE
+ #define RPC_NO_WINDOWS_H
+ /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
+ #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
+ #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
+ #endif
+
+ #if _MSC_VER >= 1300
+ #pragma warning(disable : 4996) // This function or variable may be unsafe
+ #else
+ #pragma warning(disable : 4511) // copy constructor could not be generated
+ #pragma warning(disable : 4512) // assignment operator could not be generated
+ #pragma warning(disable : 4514) // unreferenced inline function has been removed
+ #pragma warning(disable : 4702) // unreachable code
+ #pragma warning(disable : 4710) // not inlined
+ #pragma warning(disable : 4714) // function marked as __forceinline not inlined
+ #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
+ #endif
+
+#endif
+
+#define UNUSED_VAR(x) (void)x;
+/* #define UNUSED_VAR(x) x=x; */
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h
new file mode 100644
index 00000000..bd429388
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h
@@ -0,0 +1,336 @@
+/* CpuArch.h -- CPU specific code
+2018-02-18 : Igor Pavlov : Public domain */
+
+#ifndef __CPU_ARCH_H
+#define __CPU_ARCH_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/*
+MY_CPU_LE means that CPU is LITTLE ENDIAN.
+MY_CPU_BE means that CPU is BIG ENDIAN.
+If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
+
+MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
+*/
+
+#if defined(_M_X64) \
+ || defined(_M_AMD64) \
+ || defined(__x86_64__) \
+ || defined(__AMD64__) \
+ || defined(__amd64__)
+ #define MY_CPU_AMD64
+ #ifdef __ILP32__
+ #define MY_CPU_NAME "x32"
+ #else
+ #define MY_CPU_NAME "x64"
+ #endif
+ #define MY_CPU_64BIT
+#endif
+
+
+#if defined(_M_IX86) \
+ || defined(__i386__)
+ #define MY_CPU_X86
+ #define MY_CPU_NAME "x86"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(_M_ARM64) \
+ || defined(__AARCH64EL__) \
+ || defined(__AARCH64EB__) \
+ || defined(__aarch64__)
+ #define MY_CPU_ARM64
+ #define MY_CPU_NAME "arm64"
+ #define MY_CPU_64BIT
+#endif
+
+
+#if defined(_M_ARM) \
+ || defined(_M_ARM_NT) \
+ || defined(_M_ARMT) \
+ || defined(__arm__) \
+ || defined(__thumb__) \
+ || defined(__ARMEL__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEL__) \
+ || defined(__THUMBEB__)
+ #define MY_CPU_ARM
+ #define MY_CPU_NAME "arm"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(_M_IA64) \
+ || defined(__ia64__)
+ #define MY_CPU_IA64
+ #define MY_CPU_NAME "ia64"
+ #define MY_CPU_64BIT
+#endif
+
+
+#if defined(__mips64) \
+ || defined(__mips64__) \
+ || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
+ #define MY_CPU_NAME "mips64"
+ #define MY_CPU_64BIT
+#elif defined(__mips__)
+ #define MY_CPU_NAME "mips"
+ /* #define MY_CPU_32BIT */
+#endif
+
+
+#if defined(__ppc64__) \
+ || defined(__powerpc64__)
+ #ifdef __ILP32__
+ #define MY_CPU_NAME "ppc64-32"
+ #else
+ #define MY_CPU_NAME "ppc64"
+ #endif
+ #define MY_CPU_64BIT
+#elif defined(__ppc__) \
+ || defined(__powerpc__)
+ #define MY_CPU_NAME "ppc"
+ #define MY_CPU_32BIT
+#endif
+
+
+#if defined(__sparc64__)
+ #define MY_CPU_NAME "sparc64"
+ #define MY_CPU_64BIT
+#elif defined(__sparc__)
+ #define MY_CPU_NAME "sparc"
+ /* #define MY_CPU_32BIT */
+#endif
+
+
+#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
+#define MY_CPU_X86_OR_AMD64
+#endif
+
+
+#ifdef _WIN32
+
+ #ifdef MY_CPU_ARM
+ #define MY_CPU_ARM_LE
+ #endif
+
+ #ifdef MY_CPU_ARM64
+ #define MY_CPU_ARM64_LE
+ #endif
+
+ #ifdef _M_IA64
+ #define MY_CPU_IA64_LE
+ #endif
+
+#endif
+
+
+#if defined(MY_CPU_X86_OR_AMD64) \
+ || defined(MY_CPU_ARM_LE) \
+ || defined(MY_CPU_ARM64_LE) \
+ || defined(MY_CPU_IA64_LE) \
+ || defined(__LITTLE_ENDIAN__) \
+ || defined(__ARMEL__) \
+ || defined(__THUMBEL__) \
+ || defined(__AARCH64EL__) \
+ || defined(__MIPSEL__) \
+ || defined(__MIPSEL) \
+ || defined(_MIPSEL) \
+ || defined(__BFIN__) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+ #define MY_CPU_LE
+#endif
+
+#if defined(__BIG_ENDIAN__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEB__) \
+ || defined(__AARCH64EB__) \
+ || defined(__MIPSEB__) \
+ || defined(__MIPSEB) \
+ || defined(_MIPSEB) \
+ || defined(__m68k__) \
+ || defined(__s390__) \
+ || defined(__s390x__) \
+ || defined(__zarch__) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
+ #define MY_CPU_BE
+#endif
+
+
+#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
+ #error Stop_Compiling_Bad_Endian
+#endif
+
+
+#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
+ #error Stop_Compiling_Bad_32_64_BIT
+#endif
+
+
+#ifndef MY_CPU_NAME
+ #ifdef MY_CPU_LE
+ #define MY_CPU_NAME "LE"
+ #elif defined(MY_CPU_BE)
+ #define MY_CPU_NAME "BE"
+ #else
+ /*
+ #define MY_CPU_NAME ""
+ */
+ #endif
+#endif
+
+
+
+
+
+#ifdef MY_CPU_LE
+ #if defined(MY_CPU_X86_OR_AMD64) \
+ || defined(MY_CPU_ARM64) \
+ || defined(__ARM_FEATURE_UNALIGNED)
+ #define MY_CPU_LE_UNALIGN
+ #endif
+#endif
+
+
+#ifdef MY_CPU_LE_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
+#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
+#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
+
+#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
+#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
+#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
+
+#else
+
+#define GetUi16(p) ( (UInt16) ( \
+ ((const Byte *)(p))[0] | \
+ ((UInt16)((const Byte *)(p))[1] << 8) ))
+
+#define GetUi32(p) ( \
+ ((const Byte *)(p))[0] | \
+ ((UInt32)((const Byte *)(p))[1] << 8) | \
+ ((UInt32)((const Byte *)(p))[2] << 16) | \
+ ((UInt32)((const Byte *)(p))[3] << 24))
+
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
+
+#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); }
+
+#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); \
+ _ppp_[2] = (Byte)(_vvv_ >> 16); \
+ _ppp_[3] = (Byte)(_vvv_ >> 24); }
+
+#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
+ SetUi32(_ppp2_ , (UInt32)_vvv2_); \
+ SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
+
+#endif
+
+#ifdef __has_builtin
+ #define MY__has_builtin(x) __has_builtin(x)
+#else
+ #define MY__has_builtin(x) 0
+#endif
+
+#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
+
+/* Note: we use bswap instruction, that is unsupported in 386 cpu */
+
+#include <stdlib.h>
+
+#pragma intrinsic(_byteswap_ushort)
+#pragma intrinsic(_byteswap_ulong)
+#pragma intrinsic(_byteswap_uint64)
+
+/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
+
+#elif defined(MY_CPU_LE_UNALIGN) && ( \
+ (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
+ || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
+
+/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
+#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
+
+#else
+
+#define GetBe32(p) ( \
+ ((UInt32)((const Byte *)(p))[0] << 24) | \
+ ((UInt32)((const Byte *)(p))[1] << 16) | \
+ ((UInt32)((const Byte *)(p))[2] << 8) | \
+ ((const Byte *)(p))[3] )
+
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+
+#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)(_vvv_ >> 24); \
+ _ppp_[1] = (Byte)(_vvv_ >> 16); \
+ _ppp_[2] = (Byte)(_vvv_ >> 8); \
+ _ppp_[3] = (Byte)_vvv_; }
+
+#endif
+
+
+#ifndef GetBe16
+
+#define GetBe16(p) ( (UInt16) ( \
+ ((UInt16)((const Byte *)(p))[0] << 8) | \
+ ((const Byte *)(p))[1] ))
+
+#endif
+
+
+
+#ifdef MY_CPU_X86_OR_AMD64
+
+typedef struct
+{
+ UInt32 maxFunc;
+ UInt32 vendor[3];
+ UInt32 ver;
+ UInt32 b;
+ UInt32 c;
+ UInt32 d;
+} Cx86cpuid;
+
+enum
+{
+ CPU_FIRM_INTEL,
+ CPU_FIRM_AMD,
+ CPU_FIRM_VIA
+};
+
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
+
+BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
+int x86cpuid_GetFirm(const Cx86cpuid *p);
+
+#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
+#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
+#define x86cpuid_GetStepping(ver) (ver & 0xF)
+
+BoolInt CPU_Is_InOrder();
+BoolInt CPU_Is_Aes_Supported();
+BoolInt CPU_IsSupported_PageGB();
+
+#endif
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c
new file mode 100644
index 00000000..92264c7a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c
@@ -0,0 +1,1127 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2018-07-08 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+#include "LzFind.h"
+#include "LzHash.h"
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
+#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)7 << 29)
+
+#define kStartMaxLen 3
+
+static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
+{
+ if (!p->directInput)
+ {
+ ISzAlloc_Free(alloc, p->bufferBase);
+ p->bufferBase = NULL;
+ }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
+{
+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+ if (p->directInput)
+ {
+ p->blockSize = blockSize;
+ return 1;
+ }
+ if (!p->bufferBase || p->blockSize != blockSize)
+ {
+ LzInWindow_Free(p, alloc);
+ p->blockSize = blockSize;
+ p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
+ }
+ return (p->bufferBase != NULL);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+ p->posLimit -= subValue;
+ p->pos -= subValue;
+ p->streamPos -= subValue;
+}
+
+static void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+ if (p->streamEndWasReached || p->result != SZ_OK)
+ return;
+
+ /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
+
+ if (p->directInput)
+ {
+ UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
+ if (curSize > p->directInputRem)
+ curSize = (UInt32)p->directInputRem;
+ p->directInputRem -= curSize;
+ p->streamPos += curSize;
+ if (p->directInputRem == 0)
+ p->streamEndWasReached = 1;
+ return;
+ }
+
+ for (;;)
+ {
+ Byte *dest = p->buffer + (p->streamPos - p->pos);
+ size_t size = (p->bufferBase + p->blockSize - dest);
+ if (size == 0)
+ return;
+
+ p->result = ISeqInStream_Read(p->stream, dest, &size);
+ if (p->result != SZ_OK)
+ return;
+ if (size == 0)
+ {
+ p->streamEndWasReached = 1;
+ return;
+ }
+ p->streamPos += (UInt32)size;
+ if (p->streamPos - p->pos > p->keepSizeAfter)
+ return;
+ }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+ memmove(p->bufferBase,
+ p->buffer - p->keepSizeBefore,
+ (size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
+ p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+ if (p->directInput)
+ return 0;
+ /* if (p->streamEndWasReached) return 0; */
+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+ if (p->streamEndWasReached)
+ return;
+ if (p->keepSizeAfter >= p->streamPos - p->pos)
+ MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+ if (MatchFinder_NeedMove(p))
+ MatchFinder_MoveBlock(p);
+ MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+ p->cutValue = 32;
+ p->btMode = 1;
+ p->numHashBytes = 4;
+ p->bigHash = 0;
+}
+
+#define kCrcPoly 0xEDB88320
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+ unsigned i;
+ p->bufferBase = NULL;
+ p->directInput = 0;
+ p->hash = NULL;
+ p->expectedDataSize = (UInt64)(Int64)-1;
+ MatchFinder_SetDefaultSettings(p);
+
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = (UInt32)i;
+ unsigned j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
+ p->crc[i] = r;
+ }
+}
+
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
+{
+ ISzAlloc_Free(alloc, p->hash);
+ p->hash = NULL;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
+{
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ LzInWindow_Free(p, alloc);
+}
+
+static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
+{
+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+ if (sizeInBytes / sizeof(CLzRef) != num)
+ return NULL;
+ return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAllocPtr alloc)
+{
+ UInt32 sizeReserv;
+
+ if (historySize > kMaxHistorySize)
+ {
+ MatchFinder_Free(p, alloc);
+ return 0;
+ }
+
+ sizeReserv = historySize >> 1;
+ if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
+ else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
+
+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+
+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+
+ if (LzInWindow_Create(p, sizeReserv, alloc))
+ {
+ UInt32 newCyclicBufferSize = historySize + 1;
+ UInt32 hs;
+ p->matchMaxLen = matchMaxLen;
+ {
+ p->fixedHashSize = 0;
+ if (p->numHashBytes == 2)
+ hs = (1 << 16) - 1;
+ else
+ {
+ hs = historySize;
+ if (hs > p->expectedDataSize)
+ hs = (UInt32)p->expectedDataSize;
+ if (hs != 0)
+ hs--;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+ if (hs > (1 << 24))
+ {
+ if (p->numHashBytes == 3)
+ hs = (1 << 24) - 1;
+ else
+ hs >>= 1;
+ /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
+ }
+ }
+ p->hashMask = hs;
+ hs++;
+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+ hs += p->fixedHashSize;
+ }
+
+ {
+ size_t newSize;
+ size_t numSons;
+ p->historySize = historySize;
+ p->hashSizeSum = hs;
+ p->cyclicBufferSize = newCyclicBufferSize;
+
+ numSons = newCyclicBufferSize;
+ if (p->btMode)
+ numSons <<= 1;
+ newSize = hs + numSons;
+
+ if (p->hash && p->numRefs == newSize)
+ return 1;
+
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ p->numRefs = newSize;
+ p->hash = AllocRefs(newSize, alloc);
+
+ if (p->hash)
+ {
+ p->son = p->hash + p->hashSizeSum;
+ return 1;
+ }
+ }
+ }
+
+ MatchFinder_Free(p, alloc);
+ return 0;
+}
+
+static void MatchFinder_SetLimits(CMatchFinder *p)
+{
+ UInt32 limit = kMaxValForNormalize - p->pos;
+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+
+ if (limit2 < limit)
+ limit = limit2;
+ limit2 = p->streamPos - p->pos;
+
+ if (limit2 <= p->keepSizeAfter)
+ {
+ if (limit2 > 0)
+ limit2 = 1;
+ }
+ else
+ limit2 -= p->keepSizeAfter;
+
+ if (limit2 < limit)
+ limit = limit2;
+
+ {
+ UInt32 lenLimit = p->streamPos - p->pos;
+ if (lenLimit > p->matchMaxLen)
+ lenLimit = p->matchMaxLen;
+ p->lenLimit = lenLimit;
+ }
+ p->posLimit = p->pos + limit;
+}
+
+
+void MatchFinder_Init_LowHash(CMatchFinder *p)
+{
+ size_t i;
+ CLzRef *items = p->hash;
+ size_t numItems = p->fixedHashSize;
+ for (i = 0; i < numItems; i++)
+ items[i] = kEmptyHashValue;
+}
+
+
+void MatchFinder_Init_HighHash(CMatchFinder *p)
+{
+ size_t i;
+ CLzRef *items = p->hash + p->fixedHashSize;
+ size_t numItems = (size_t)p->hashMask + 1;
+ for (i = 0; i < numItems; i++)
+ items[i] = kEmptyHashValue;
+}
+
+
+void MatchFinder_Init_3(CMatchFinder *p, int readData)
+{
+ p->cyclicBufferPos = 0;
+ p->buffer = p->bufferBase;
+ p->pos =
+ p->streamPos = p->cyclicBufferSize;
+ p->result = SZ_OK;
+ p->streamEndWasReached = 0;
+
+ if (readData)
+ MatchFinder_ReadBlock(p);
+
+ MatchFinder_SetLimits(p);
+}
+
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+ MatchFinder_Init_HighHash(p);
+ MatchFinder_Init_LowHash(p);
+ MatchFinder_Init_3(p, True);
+}
+
+
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+ return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems)
+{
+ size_t i;
+ for (i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+}
+
+static void MatchFinder_Normalize(CMatchFinder *p)
+{
+ UInt32 subValue = MatchFinder_GetSubValue(p);
+ MatchFinder_Normalize3(subValue, p->hash, p->numRefs);
+ MatchFinder_ReduceOffsets(p, subValue);
+}
+
+
+MY_NO_INLINE
+static void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+ if (p->pos == kMaxValForNormalize)
+ MatchFinder_Normalize(p);
+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+ MatchFinder_CheckAndMoveAndRead(p);
+ if (p->cyclicBufferPos == p->cyclicBufferSize)
+ p->cyclicBufferPos = 0;
+ MatchFinder_SetLimits(p);
+}
+
+
+/*
+ (lenLimit > maxLen)
+*/
+MY_FORCE_INLINE
+static UInt32 * Hc_GetMatchesSpec(unsigned lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, unsigned maxLen)
+{
+ /*
+ son[_cyclicBufferPos] = curMatch;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ return distances;
+ {
+ const Byte *pb = cur - delta;
+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+ {
+ UInt32 len = 0;
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ maxLen = len;
+ *distances++ = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ return distances;
+ }
+ }
+ }
+ }
+ */
+
+ const Byte *lim = cur + lenLimit;
+ son[_cyclicBufferPos] = curMatch;
+ do
+ {
+ UInt32 delta = pos - curMatch;
+ if (delta >= _cyclicBufferSize)
+ break;
+ {
+ ptrdiff_t diff;
+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+ diff = (ptrdiff_t)0 - delta;
+ if (cur[maxLen] == cur[maxLen + diff])
+ {
+ const Byte *c = cur;
+ while (*c == c[diff])
+ {
+ if (++c == lim)
+ {
+ distances[0] = (UInt32)(lim - cur);
+ distances[1] = delta - 1;
+ return distances + 2;
+ }
+ }
+ {
+ unsigned len = (unsigned)(c - cur);
+ if (maxLen < len)
+ {
+ maxLen = len;
+ distances[0] = (UInt32)len;
+ distances[1] = delta - 1;
+ distances += 2;
+ }
+ }
+ }
+ }
+ }
+ while (--cutValue);
+
+ return distances;
+}
+
+
+MY_FORCE_INLINE
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
+ unsigned len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return distances;
+ }
+ {
+ CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ unsigned len = (len0 < len1 ? len0 : len1);
+ UInt32 pair0 = pair[0];
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ maxLen = (UInt32)len;
+ *distances++ = (UInt32)len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair0;
+ *ptr0 = pair[1];
+ return distances;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+ CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
+ unsigned len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return;
+ }
+ {
+ CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ unsigned len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ {
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+#define MOVE_POS \
+ ++p->cyclicBufferPos; \
+ p->buffer++; \
+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return (UInt32)offset;
+
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+ unsigned lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
+ lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+ cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+ offset = (unsigned)(GetMatchesSpec1((UInt32)lenLimit, curMatch, MF_PARAMS(p), \
+ distances + offset, (UInt32)maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+ SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+#define UPDATE_maxLen { \
+ ptrdiff_t diff = (ptrdiff_t)0 - d2; \
+ const Byte *c = cur + maxLen; \
+ const Byte *lim = cur + lenLimit; \
+ for (; c != lim; c++) if (*(c + diff) != *c) break; \
+ maxLen = (unsigned)(c - cur); }
+
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ unsigned offset;
+ GET_MATCHES_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ unsigned offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 2)
+}
+
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, d2, pos;
+ unsigned maxLen, offset;
+ UInt32 *hash;
+ GET_MATCHES_HEADER(3)
+
+ HASH3_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[h2];
+
+ curMatch = (hash + kFix3HashSize)[hv];
+
+ hash[h2] = pos;
+ (hash + kFix3HashSize)[hv] = pos;
+
+ maxLen = 2;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ UPDATE_maxLen
+ distances[0] = (UInt32)maxLen;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, d2, d3, pos;
+ unsigned maxLen, offset;
+ UInt32 *hash;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash [h2];
+ d3 = pos - (hash + kFix3HashSize)[h3];
+
+ curMatch = (hash + kFix4HashSize)[hv];
+
+ hash [h2] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ maxLen = 2;
+ distances[0] = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ }
+
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ maxLen = 3;
+ distances[(size_t)offset + 1] = d3 - 1;
+ offset += 2;
+ d2 = d3;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[(size_t)offset - 2] = (UInt32)maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 3)
+ maxLen = 3;
+
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+/*
+static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos;
+ UInt32 *hash;
+ GET_MATCHES_HEADER(5)
+
+ HASH5_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash [h2];
+ d3 = pos - (hash + kFix3HashSize)[h3];
+ d4 = pos - (hash + kFix4HashSize)[h4];
+
+ curMatch = (hash + kFix5HashSize)[hv];
+
+ hash [h2] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[h4] = pos;
+ (hash + kFix5HashSize)[hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (*(cur - d2 + 2) == cur[2])
+ distances[0] = maxLen = 3;
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[2] = maxLen = 3;
+ distances[3] = d3 - 1;
+ offset = 4;
+ d2 = d3;
+ }
+ }
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[0] = maxLen = 3;
+ distances[1] = d3 - 1;
+ offset = 2;
+ d2 = d3;
+ }
+
+ if (d2 != d4 && d4 < p->cyclicBufferSize
+ && *(cur - d4) == *cur
+ && *(cur - d4 + 3) == *(cur + 3))
+ {
+ maxLen = 4;
+ distances[(size_t)offset + 1] = d4 - 1;
+ offset += 2;
+ d2 = d4;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[(size_t)offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 4)
+ maxLen = 4;
+
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+*/
+
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, d2, d3, pos;
+ unsigned maxLen, offset;
+ UInt32 *hash;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash [h2];
+ d3 = pos - (hash + kFix3HashSize)[h3];
+ curMatch = (hash + kFix4HashSize)[hv];
+
+ hash [h2] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ maxLen = 2;
+ distances[0] = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ }
+
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ maxLen = 3;
+ distances[(size_t)offset + 1] = d3 - 1;
+ offset += 2;
+ d2 = d3;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[(size_t)offset - 2] = (UInt32)maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 3)
+ maxLen = 3;
+
+ offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+
+/*
+static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos
+ UInt32 *hash;
+ GET_MATCHES_HEADER(5)
+
+ HASH5_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash [h2];
+ d3 = pos - (hash + kFix3HashSize)[h3];
+ d4 = pos - (hash + kFix4HashSize)[h4];
+
+ curMatch = (hash + kFix5HashSize)[hv];
+
+ hash [h2] = pos;
+ (hash + kFix3HashSize)[h3] = pos;
+ (hash + kFix4HashSize)[h4] = pos;
+ (hash + kFix5HashSize)[hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (*(cur - d2 + 2) == cur[2])
+ distances[0] = maxLen = 3;
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[2] = maxLen = 3;
+ distances[3] = d3 - 1;
+ offset = 4;
+ d2 = d3;
+ }
+ }
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[0] = maxLen = 3;
+ distances[1] = d3 - 1;
+ offset = 2;
+ d2 = d3;
+ }
+
+ if (d2 != d4 && d4 < p->cyclicBufferSize
+ && *(cur - d4) == *cur
+ && *(cur - d4 + 3) == *(cur + 3))
+ {
+ maxLen = 4;
+ distances[(size_t)offset + 1] = d4 - 1;
+ offset += 2;
+ d2 = d4;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[(size_t)offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 4)
+ maxLen = 4;
+
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+*/
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ unsigned offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
+ offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances, 2) - (distances));
+ MOVE_POS_RET
+}
+
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2;
+ UInt32 *hash;
+ SKIP_HEADER(3)
+ HASH3_CALC;
+ hash = p->hash;
+ curMatch = (hash + kFix3HashSize)[hv];
+ hash[h2] =
+ (hash + kFix3HashSize)[hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3;
+ UInt32 *hash;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ hash = p->hash;
+ curMatch = (hash + kFix4HashSize)[hv];
+ hash [h2] =
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+/*
+static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3, h4;
+ UInt32 *hash;
+ SKIP_HEADER(5)
+ HASH5_CALC;
+ hash = p->hash;
+ curMatch = (hash + kFix5HashSize)[hv];
+ hash [h2] =
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[h4] =
+ (hash + kFix5HashSize)[hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+*/
+
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3;
+ UInt32 *hash;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ hash = p->hash;
+ curMatch = (hash + kFix4HashSize)[hv];
+ hash [h2] =
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[hv] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+/*
+static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3, h4;
+ UInt32 *hash;
+ SKIP_HEADER(5)
+ HASH5_CALC;
+ hash = p->hash;
+ curMatch = hash + kFix5HashSize)[hv];
+ hash [h2] =
+ (hash + kFix3HashSize)[h3] =
+ (hash + kFix4HashSize)[h4] =
+ (hash + kFix5HashSize)[hv] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+*/
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+ if (!p->btMode)
+ {
+ /* if (p->numHashBytes <= 4) */
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ }
+ /*
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
+ }
+ */
+ }
+ else if (p->numHashBytes == 2)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 3)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+ }
+ else /* if (p->numHashBytes == 4) */
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+ }
+ /*
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
+ }
+ */
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h
new file mode 100644
index 00000000..f2c8519b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h
@@ -0,0 +1,121 @@
+/* LzFind.h -- Match finder for LZ algorithms
+2017-06-10 : Igor Pavlov : Public domain */
+
+#ifndef __LZ_FIND_H
+#define __LZ_FIND_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+ Byte *buffer;
+ UInt32 pos;
+ UInt32 posLimit;
+ UInt32 streamPos;
+ UInt32 lenLimit;
+
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+ Byte streamEndWasReached;
+ Byte btMode;
+ Byte bigHash;
+ Byte directInput;
+
+ UInt32 matchMaxLen;
+ CLzRef *hash;
+ CLzRef *son;
+ UInt32 hashMask;
+ UInt32 cutValue;
+
+ Byte *bufferBase;
+ ISeqInStream *stream;
+
+ UInt32 blockSize;
+ UInt32 keepSizeBefore;
+ UInt32 keepSizeAfter;
+
+ UInt32 numHashBytes;
+ size_t directInputRem;
+ UInt32 historySize;
+ UInt32 fixedHashSize;
+ UInt32 hashSizeSum;
+ SRes result;
+ UInt32 crc[256];
+ size_t numRefs;
+
+ UInt64 expectedDataSize;
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+#define Inline_MatchFinder_IsFinishedOK(p) \
+ ((p)->streamEndWasReached \
+ && (p)->streamPos == (p)->pos \
+ && (!(p)->directInput || (p)->directInputRem == 0))
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+ historySize <= 3 GB
+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAllocPtr alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+ Mf_Init_Func Init;
+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+ Mf_GetMatches_Func GetMatches;
+ Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init_LowHash(CMatchFinder *p);
+void MatchFinder_Init_HighHash(CMatchFinder *p);
+void MatchFinder_Init_3(CMatchFinder *p, int readData);
+void MatchFinder_Init(CMatchFinder *p);
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c
new file mode 100644
index 00000000..2d170d66
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c
@@ -0,0 +1,853 @@
+/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
+2018-12-29 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include "LzHash.h"
+
+#include "LzFindMt.h"
+
+static void MtSync_Construct(CMtSync *p)
+{
+ p->wasCreated = False;
+ p->csWasInitialized = False;
+ p->csWasEntered = False;
+ Thread_Construct(&p->thread);
+ Event_Construct(&p->canStart);
+ Event_Construct(&p->wasStarted);
+ Event_Construct(&p->wasStopped);
+ Semaphore_Construct(&p->freeSemaphore);
+ Semaphore_Construct(&p->filledSemaphore);
+}
+
+static void MtSync_GetNextBlock(CMtSync *p)
+{
+ if (p->needStart)
+ {
+ p->numProcessedBlocks = 1;
+ p->needStart = False;
+ p->stopWriting = False;
+ p->exit = False;
+ Event_Reset(&p->wasStarted);
+ Event_Reset(&p->wasStopped);
+
+ Event_Set(&p->canStart);
+ Event_Wait(&p->wasStarted);
+
+ // if (mt) MatchFinder_Init_LowHash(mt->MatchFinder);
+ }
+ else
+ {
+ CriticalSection_Leave(&p->cs);
+ p->csWasEntered = False;
+ p->numProcessedBlocks++;
+ Semaphore_Release1(&p->freeSemaphore);
+ }
+ Semaphore_Wait(&p->filledSemaphore);
+ CriticalSection_Enter(&p->cs);
+ p->csWasEntered = True;
+}
+
+/* MtSync_StopWriting must be called if Writing was started */
+
+static void MtSync_StopWriting(CMtSync *p)
+{
+ UInt32 myNumBlocks = p->numProcessedBlocks;
+ if (!Thread_WasCreated(&p->thread) || p->needStart)
+ return;
+ p->stopWriting = True;
+ if (p->csWasEntered)
+ {
+ CriticalSection_Leave(&p->cs);
+ p->csWasEntered = False;
+ }
+ Semaphore_Release1(&p->freeSemaphore);
+
+ Event_Wait(&p->wasStopped);
+
+ while (myNumBlocks++ != p->numProcessedBlocks)
+ {
+ Semaphore_Wait(&p->filledSemaphore);
+ Semaphore_Release1(&p->freeSemaphore);
+ }
+ p->needStart = True;
+}
+
+static void MtSync_Destruct(CMtSync *p)
+{
+ if (Thread_WasCreated(&p->thread))
+ {
+ MtSync_StopWriting(p);
+ p->exit = True;
+ if (p->needStart)
+ Event_Set(&p->canStart);
+ Thread_Wait(&p->thread);
+ Thread_Close(&p->thread);
+ }
+ if (p->csWasInitialized)
+ {
+ CriticalSection_Delete(&p->cs);
+ p->csWasInitialized = False;
+ }
+
+ Event_Close(&p->canStart);
+ Event_Close(&p->wasStarted);
+ Event_Close(&p->wasStopped);
+ Semaphore_Close(&p->freeSemaphore);
+ Semaphore_Close(&p->filledSemaphore);
+
+ p->wasCreated = False;
+}
+
+#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
+
+static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
+{
+ if (p->wasCreated)
+ return SZ_OK;
+
+ RINOK_THREAD(CriticalSection_Init(&p->cs));
+ p->csWasInitialized = True;
+
+ RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
+ RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
+ RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
+
+ RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
+ RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
+
+ p->needStart = True;
+
+ RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
+ p->wasCreated = True;
+ return SZ_OK;
+}
+
+static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
+{
+ SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
+ if (res != SZ_OK)
+ MtSync_Destruct(p);
+ return res;
+}
+
+void MtSync_Init(CMtSync *p) { p->needStart = True; }
+
+#define kMtMaxValForNormalize 0xFFFFFFFF
+
+#define DEF_GetHeads2(name, v, action) \
+ static void GetHeads ## name(const Byte *p, UInt32 pos, \
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
+ { action; for (; numHeads != 0; numHeads--) { \
+ const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
+
+#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
+
+DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), UNUSED_VAR(hashMask); UNUSED_VAR(crc); )
+DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
+DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
+DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
+/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
+
+static void HashThreadFunc(CMatchFinderMt *mt)
+{
+ CMtSync *p = &mt->hashSync;
+ for (;;)
+ {
+ UInt32 numProcessedBlocks = 0;
+ Event_Wait(&p->canStart);
+ Event_Set(&p->wasStarted);
+
+ MatchFinder_Init_HighHash(mt->MatchFinder);
+
+ for (;;)
+ {
+ if (p->exit)
+ return;
+ if (p->stopWriting)
+ {
+ p->numProcessedBlocks = numProcessedBlocks;
+ Event_Set(&p->wasStopped);
+ break;
+ }
+
+ {
+ CMatchFinder *mf = mt->MatchFinder;
+ if (MatchFinder_NeedMove(mf))
+ {
+ CriticalSection_Enter(&mt->btSync.cs);
+ CriticalSection_Enter(&mt->hashSync.cs);
+ {
+ const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ ptrdiff_t offset;
+ MatchFinder_MoveBlock(mf);
+ offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ mt->pointerToCurPos -= offset;
+ mt->buffer -= offset;
+ }
+ CriticalSection_Leave(&mt->btSync.cs);
+ CriticalSection_Leave(&mt->hashSync.cs);
+ continue;
+ }
+
+ Semaphore_Wait(&p->freeSemaphore);
+
+ MatchFinder_ReadIfRequired(mf);
+ if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
+ {
+ UInt32 subValue = (mf->pos - mf->historySize - 1);
+ MatchFinder_ReduceOffsets(mf, subValue);
+ MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1);
+ }
+ {
+ UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+ UInt32 num = mf->streamPos - mf->pos;
+ heads[0] = 2;
+ heads[1] = num;
+ if (num >= mf->numHashBytes)
+ {
+ num = num - mf->numHashBytes + 1;
+ if (num > kMtHashBlockSize - 2)
+ num = kMtHashBlockSize - 2;
+ mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
+ heads[0] = 2 + num;
+ }
+ mf->pos += num;
+ mf->buffer += num;
+ }
+ }
+
+ Semaphore_Release1(&p->filledSemaphore);
+ }
+ }
+}
+
+static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
+{
+ MtSync_GetNextBlock(&p->hashSync);
+ p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+ p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
+ p->hashNumAvail = p->hashBuf[p->hashBufPos++];
+}
+
+#define kEmptyHashValue 0
+
+#define MFMT_GM_INLINE
+
+#ifdef MFMT_GM_INLINE
+
+/*
+ we use size_t for _cyclicBufferPos instead of UInt32
+ to eliminate "movsx" BUG in old MSVC x64 compiler.
+*/
+
+MY_NO_INLINE
+static UInt32 *GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
+ size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *distances, UInt32 _maxLen, const UInt32 *hash, const UInt32 *limit, UInt32 size, UInt32 *posRes)
+{
+ do
+ {
+ UInt32 *_distances = ++distances;
+ UInt32 delta = *hash++;
+
+ CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
+ unsigned len0 = 0, len1 = 0;
+ UInt32 cutValue = _cutValue;
+ unsigned maxLen = (unsigned)_maxLen;
+
+ /*
+ if (size > 1)
+ {
+ UInt32 delta = *hash;
+ if (delta < _cyclicBufferSize)
+ {
+ UInt32 cyc1 = _cyclicBufferPos + 1;
+ CLzRef *pair = son + ((size_t)(cyc1 - delta + ((delta > cyc1) ? _cyclicBufferSize : 0)) << 1);
+ Byte b = *(cur + 1 - delta);
+ _distances[0] = pair[0];
+ _distances[1] = b;
+ }
+ }
+ */
+ if (cutValue == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ }
+ else
+ for(;;)
+ {
+ {
+ CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((_cyclicBufferPos < delta) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ unsigned len = (len0 < len1 ? len0 : len1);
+ UInt32 pair0 = *pair;
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ maxLen = len;
+ *distances++ = (UInt32)len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ UInt32 pair1 = pair[1];
+ *ptr1 = pair0;
+ *ptr0 = pair1;
+ break;
+ }
+ }
+ }
+ {
+ UInt32 curMatch = pos - delta;
+ // delta = pos - *pair;
+ // delta = pos - pair[((UInt32)pb[len] - (UInt32)cur[len]) >> 31];
+ if (pb[len] < cur[len])
+ {
+ delta = pos - pair[1];
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ len1 = len;
+ }
+ else
+ {
+ delta = pos - *pair;
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ len0 = len;
+ }
+ }
+ }
+ if (--cutValue == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ break;
+ }
+ }
+ pos++;
+ _cyclicBufferPos++;
+ cur++;
+ {
+ UInt32 num = (UInt32)(distances - _distances);
+ _distances[-1] = num;
+ }
+ }
+ while (distances < limit && --size != 0);
+ *posRes = pos;
+ return distances;
+}
+
+#endif
+
+
+
+static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ UInt32 numProcessed = 0;
+ UInt32 curPos = 2;
+ UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); // * 2
+
+ distances[1] = p->hashNumAvail;
+
+ while (curPos < limit)
+ {
+ if (p->hashBufPos == p->hashBufPosLimit)
+ {
+ MatchFinderMt_GetNextBlock_Hash(p);
+ distances[1] = numProcessed + p->hashNumAvail;
+ if (p->hashNumAvail >= p->numHashBytes)
+ continue;
+ distances[0] = curPos + p->hashNumAvail;
+ distances += curPos;
+ for (; p->hashNumAvail != 0; p->hashNumAvail--)
+ *distances++ = 0;
+ return;
+ }
+ {
+ UInt32 size = p->hashBufPosLimit - p->hashBufPos;
+ UInt32 lenLimit = p->matchMaxLen;
+ UInt32 pos = p->pos;
+ UInt32 cyclicBufferPos = p->cyclicBufferPos;
+ if (lenLimit >= p->hashNumAvail)
+ lenLimit = p->hashNumAvail;
+ {
+ UInt32 size2 = p->hashNumAvail - lenLimit + 1;
+ if (size2 < size)
+ size = size2;
+ size2 = p->cyclicBufferSize - cyclicBufferPos;
+ if (size2 < size)
+ size = size2;
+ }
+
+ #ifndef MFMT_GM_INLINE
+ while (curPos < limit && size-- != 0)
+ {
+ UInt32 *startDistances = distances + curPos;
+ UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
+ pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ startDistances + 1, p->numHashBytes - 1) - startDistances);
+ *startDistances = num - 1;
+ curPos += num;
+ cyclicBufferPos++;
+ pos++;
+ p->buffer++;
+ }
+ #else
+ {
+ UInt32 posRes;
+ curPos = (UInt32)(GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos,
+ distances + limit,
+ size, &posRes) - distances);
+ p->hashBufPos += posRes - pos;
+ cyclicBufferPos += posRes - pos;
+ p->buffer += posRes - pos;
+ pos = posRes;
+ }
+ #endif
+
+ numProcessed += pos - p->pos;
+ p->hashNumAvail -= pos - p->pos;
+ p->pos = pos;
+ if (cyclicBufferPos == p->cyclicBufferSize)
+ cyclicBufferPos = 0;
+ p->cyclicBufferPos = cyclicBufferPos;
+ }
+ }
+
+ distances[0] = curPos;
+}
+
+static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
+{
+ CMtSync *sync = &p->hashSync;
+ if (!sync->needStart)
+ {
+ CriticalSection_Enter(&sync->cs);
+ sync->csWasEntered = True;
+ }
+
+ BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
+
+ if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
+ {
+ UInt32 subValue = p->pos - p->cyclicBufferSize;
+ MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2);
+ p->pos -= subValue;
+ }
+
+ if (!sync->needStart)
+ {
+ CriticalSection_Leave(&sync->cs);
+ sync->csWasEntered = False;
+ }
+}
+
+void BtThreadFunc(CMatchFinderMt *mt)
+{
+ CMtSync *p = &mt->btSync;
+ for (;;)
+ {
+ UInt32 blockIndex = 0;
+ Event_Wait(&p->canStart);
+ Event_Set(&p->wasStarted);
+ for (;;)
+ {
+ if (p->exit)
+ return;
+ if (p->stopWriting)
+ {
+ p->numProcessedBlocks = blockIndex;
+ MtSync_StopWriting(&mt->hashSync);
+ Event_Set(&p->wasStopped);
+ break;
+ }
+ Semaphore_Wait(&p->freeSemaphore);
+ BtFillBlock(mt, blockIndex++);
+ Semaphore_Release1(&p->filledSemaphore);
+ }
+ }
+}
+
+void MatchFinderMt_Construct(CMatchFinderMt *p)
+{
+ p->hashBuf = NULL;
+ MtSync_Construct(&p->hashSync);
+ MtSync_Construct(&p->btSync);
+}
+
+static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc)
+{
+ ISzAlloc_Free(alloc, p->hashBuf);
+ p->hashBuf = NULL;
+}
+
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
+{
+ MtSync_Destruct(&p->hashSync);
+ MtSync_Destruct(&p->btSync);
+ MatchFinderMt_FreeMem(p, alloc);
+}
+
+#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
+#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
+
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
+{
+ Byte allocaDummy[0x180];
+ unsigned i = 0;
+ for (i = 0; i < 16; i++)
+ allocaDummy[i] = (Byte)0;
+ if (allocaDummy[0] == 0)
+ BtThreadFunc((CMatchFinderMt *)p);
+ return 0;
+}
+
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
+{
+ CMatchFinder *mf = p->MatchFinder;
+ p->historySize = historySize;
+ if (kMtBtBlockSize <= matchMaxLen * 4)
+ return SZ_ERROR_PARAM;
+ if (!p->hashBuf)
+ {
+ p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
+ if (!p->hashBuf)
+ return SZ_ERROR_MEM;
+ p->btBuf = p->hashBuf + kHashBufferSize;
+ }
+ keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
+ keepAddBufferAfter += kMtHashBlockSize;
+ if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
+ return SZ_ERROR_MEM;
+
+ RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
+ RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
+ return SZ_OK;
+}
+
+/* Call it after ReleaseStream / SetStream */
+static void MatchFinderMt_Init(CMatchFinderMt *p)
+{
+ CMatchFinder *mf = p->MatchFinder;
+
+ p->btBufPos =
+ p->btBufPosLimit = 0;
+ p->hashBufPos =
+ p->hashBufPosLimit = 0;
+
+ /* Init without data reading. We don't want to read data in this thread */
+ MatchFinder_Init_3(mf, False);
+ MatchFinder_Init_LowHash(mf);
+
+ p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ p->btNumAvailBytes = 0;
+ p->lzPos = p->historySize + 1;
+
+ p->hash = mf->hash;
+ p->fixedHashSize = mf->fixedHashSize;
+ p->crc = mf->crc;
+
+ p->son = mf->son;
+ p->matchMaxLen = mf->matchMaxLen;
+ p->numHashBytes = mf->numHashBytes;
+ p->pos = mf->pos;
+ p->buffer = mf->buffer;
+ p->cyclicBufferPos = mf->cyclicBufferPos;
+ p->cyclicBufferSize = mf->cyclicBufferSize;
+ p->cutValue = mf->cutValue;
+}
+
+/* ReleaseStream is required to finish multithreading */
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
+{
+ MtSync_StopWriting(&p->btSync);
+ /* p->MatchFinder->ReleaseStream(); */
+}
+
+static void MatchFinderMt_Normalize(CMatchFinderMt *p)
+{
+ MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
+ p->lzPos = p->historySize + 1;
+}
+
+static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
+{
+ UInt32 blockIndex;
+ MtSync_GetNextBlock(&p->btSync);
+ blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
+ p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
+ p->btBufPosLimit += p->btBuf[p->btBufPos++];
+ p->btNumAvailBytes = p->btBuf[p->btBufPos++];
+ if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
+ MatchFinderMt_Normalize(p);
+}
+
+static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+{
+ return p->pointerToCurPos;
+}
+
+#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
+
+static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
+{
+ GET_NEXT_BLOCK_IF_REQUIRED;
+ return p->btNumAvailBytes;
+}
+
+static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 h2, curMatch2;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH2_CALC
+
+ curMatch2 = hash[h2];
+ hash[h2] = lzPos;
+
+ if (curMatch2 >= matchMinPos)
+ if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ *distances++ = 2;
+ *distances++ = lzPos - curMatch2 - 1;
+ }
+
+ return distances;
+}
+
+static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 h2, h3, curMatch2, curMatch3;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH3_CALC
+
+ curMatch2 = hash[ h2];
+ curMatch3 = (hash + kFix3HashSize)[h3];
+
+ hash[ h2] = lzPos;
+ (hash + kFix3HashSize)[h3] = lzPos;
+
+ if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch2 - 1;
+ if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+ {
+ distances[0] = 3;
+ return distances + 2;
+ }
+ distances[0] = 2;
+ distances += 2;
+ }
+
+ if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+ {
+ *distances++ = 3;
+ *distances++ = lzPos - curMatch3 - 1;
+ }
+
+ return distances;
+}
+
+/*
+static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, curMatch2, curMatch3, curMatch4;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH4_CALC
+
+ curMatch2 = hash[ h2];
+ curMatch3 = (hash + kFix3HashSize)[h3];
+ curMatch4 = (hash + kFix4HashSize)[h4];
+
+ hash[ h2] = lzPos;
+ (hash + kFix3HashSize)[h3] = lzPos;
+ (hash + kFix4HashSize)[h4] = lzPos;
+
+ if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch2 - 1;
+ if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+ {
+ distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
+ return distances + 2;
+ }
+ distances[0] = 2;
+ distances += 2;
+ }
+
+ if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch3 - 1;
+ if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
+ {
+ distances[0] = 4;
+ return distances + 2;
+ }
+ distances[0] = 3;
+ distances += 2;
+ }
+
+ if (curMatch4 >= matchMinPos)
+ if (
+ cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
+ cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
+ )
+ {
+ *distances++ = 4;
+ *distances++ = lzPos - curMatch4 - 1;
+ }
+
+ return distances;
+}
+*/
+
+#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
+
+static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ const UInt32 *btBuf = p->btBuf + p->btBufPos;
+ UInt32 len = *btBuf++;
+ p->btBufPos += 1 + len;
+ p->btNumAvailBytes--;
+ {
+ UInt32 i;
+ for (i = 0; i < len; i += 2)
+ {
+ UInt32 v0 = btBuf[0];
+ UInt32 v1 = btBuf[1];
+ btBuf += 2;
+ distances[0] = v0;
+ distances[1] = v1;
+ distances += 2;
+ }
+ }
+ INCREASE_LZ_POS
+ return len;
+}
+
+static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ const UInt32 *btBuf = p->btBuf + p->btBufPos;
+ UInt32 len = *btBuf++;
+ p->btBufPos += 1 + len;
+
+ if (len == 0)
+ {
+ /* change for bt5 ! */
+ if (p->btNumAvailBytes-- >= 4)
+ len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
+ }
+ else
+ {
+ /* Condition: there are matches in btBuf with length < p->numHashBytes */
+ UInt32 *distances2;
+ p->btNumAvailBytes--;
+ distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
+ do
+ {
+ UInt32 v0 = btBuf[0];
+ UInt32 v1 = btBuf[1];
+ btBuf += 2;
+ distances2[0] = v0;
+ distances2[1] = v1;
+ distances2 += 2;
+ }
+ while ((len -= 2) != 0);
+ len = (UInt32)(distances2 - (distances));
+ }
+ INCREASE_LZ_POS
+ return len;
+}
+
+#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED
+#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
+#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
+
+static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER2_MT { p->btNumAvailBytes--;
+ SKIP_FOOTER_MT
+}
+
+static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER_MT(2)
+ UInt32 h2;
+ MT_HASH2_CALC
+ hash[h2] = p->lzPos;
+ SKIP_FOOTER_MT
+}
+
+static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER_MT(3)
+ UInt32 h2, h3;
+ MT_HASH3_CALC
+ (hash + kFix3HashSize)[h3] =
+ hash[ h2] =
+ p->lzPos;
+ SKIP_FOOTER_MT
+}
+
+/*
+static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER_MT(4)
+ UInt32 h2, h3, h4;
+ MT_HASH4_CALC
+ (hash + kFix4HashSize)[h4] =
+ (hash + kFix3HashSize)[h3] =
+ hash[ h2] =
+ p->lzPos;
+ SKIP_FOOTER_MT
+}
+*/
+
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
+ vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
+
+ switch (p->MatchFinder->numHashBytes)
+ {
+ case 2:
+ p->GetHeadsFunc = GetHeads2;
+ p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
+ vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
+ break;
+ case 3:
+ p->GetHeadsFunc = GetHeads3;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
+ break;
+ default:
+ /* case 4: */
+ p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
+ break;
+ /*
+ default:
+ p->GetHeadsFunc = GetHeads5;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
+ break;
+ */
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h
new file mode 100644
index 00000000..708157ec
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h
@@ -0,0 +1,101 @@
+/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
+2018-07-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZ_FIND_MT_H
+#define __LZ_FIND_MT_H
+
+#include "LzFind.h"
+#include "Threads.h"
+
+EXTERN_C_BEGIN
+
+#define kMtHashBlockSize (1 << 13)
+#define kMtHashNumBlocks (1 << 3)
+#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
+
+#define kMtBtBlockSize (1 << 14)
+#define kMtBtNumBlocks (1 << 6)
+#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
+
+typedef struct _CMtSync
+{
+ BoolInt wasCreated;
+ BoolInt needStart;
+ BoolInt exit;
+ BoolInt stopWriting;
+
+ CThread thread;
+ CAutoResetEvent canStart;
+ CAutoResetEvent wasStarted;
+ CAutoResetEvent wasStopped;
+ CSemaphore freeSemaphore;
+ CSemaphore filledSemaphore;
+ BoolInt csWasInitialized;
+ BoolInt csWasEntered;
+ CCriticalSection cs;
+ UInt32 numProcessedBlocks;
+} CMtSync;
+
+typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
+
+/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
+#define kMtCacheLineDummy 128
+
+typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
+
+typedef struct _CMatchFinderMt
+{
+ /* LZ */
+ const Byte *pointerToCurPos;
+ UInt32 *btBuf;
+ UInt32 btBufPos;
+ UInt32 btBufPosLimit;
+ UInt32 lzPos;
+ UInt32 btNumAvailBytes;
+
+ UInt32 *hash;
+ UInt32 fixedHashSize;
+ UInt32 historySize;
+ const UInt32 *crc;
+
+ Mf_Mix_Matches MixMatchesFunc;
+
+ /* LZ + BT */
+ CMtSync btSync;
+ Byte btDummy[kMtCacheLineDummy];
+
+ /* BT */
+ UInt32 *hashBuf;
+ UInt32 hashBufPos;
+ UInt32 hashBufPosLimit;
+ UInt32 hashNumAvail;
+
+ CLzRef *son;
+ UInt32 matchMaxLen;
+ UInt32 numHashBytes;
+ UInt32 pos;
+ const Byte *buffer;
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be historySize + 1 */
+ UInt32 cutValue;
+
+ /* BT + Hash */
+ CMtSync hashSync;
+ /* Byte hashDummy[kMtCacheLineDummy]; */
+
+ /* Hash */
+ Mf_GetHeads GetHeadsFunc;
+ CMatchFinder *MatchFinder;
+} CMatchFinderMt;
+
+void MatchFinderMt_Construct(CMatchFinderMt *p);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzHash.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzHash.h
new file mode 100644
index 00000000..e7c94230
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzHash.h
@@ -0,0 +1,57 @@
+/* LzHash.h -- HASH functions for LZ algorithms
+2015-04-12 : Igor Pavlov : Public domain */
+
+#ifndef __LZ_HASH_H
+#define __LZ_HASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ h2 = temp & (kHash2Size - 1); \
+ hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ temp ^= (p->crc[cur[3]] << 5); \
+ h4 = temp & (kHash4Size - 1); \
+ hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; }
+
+/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+ h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ h2 = temp & (kHash2Size - 1); \
+ h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c
new file mode 100644
index 00000000..9749efe9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c
@@ -0,0 +1,1185 @@
+/* LzmaDec.c -- LZMA Decoder
+2018-07-04 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+/* #include "CpuArch.h" */
+#include "LzmaDec.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+ { UPDATE_0(p); i = (i + i); A0; } else \
+ { UPDATE_1(p); i = (i + i) + 1; A1; }
+
+#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
+
+#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
+ { UPDATE_0(p + i); A0; } else \
+ { UPDATE_1(p + i); A1; }
+#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
+#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
+#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
+
+#define TREE_DECODE(probs, limit, i) \
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+ { i = 1; \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ i -= 0x40; }
+#endif
+
+#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
+#define MATCHED_LITER_DEC \
+ matchByte += matchByte; \
+ bit = offs; \
+ offs &= matchByte; \
+ probLit = prob + (offs + bit + symbol); \
+ GET_BIT2(probLit, symbol, offs ^= bit; , ;)
+
+
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
+ { UPDATE_0_CHECK; i += m; m += m; } else \
+ { UPDATE_1_CHECK; m += m; i += m; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenLow 0
+#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+#define LenChoice LenLow
+#define LenChoice2 (LenLow + (1 << kLenNumLowBits))
+
+#define kNumStates 12
+#define kNumStates2 16
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
+
+/* External ASM code needs same CLzmaProb array layout. So don't change it. */
+
+/* (probs_1664) is faster and better for code size at some platforms */
+/*
+#ifdef MY_CPU_X86_OR_AMD64
+*/
+#define kStartOffset 1664
+#define GET_PROBS p->probs_1664
+/*
+#define GET_PROBS p->probs + kStartOffset
+#else
+#define kStartOffset 0
+#define GET_PROBS p->probs
+#endif
+*/
+
+#define SpecPos (-kStartOffset)
+#define IsRep0Long (SpecPos + kNumFullDistances)
+#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))
+#define LenCoder (RepLenCoder + kNumLenProbs)
+#define IsMatch (LenCoder + kNumLenProbs)
+#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))
+#define IsRep (Align + kAlignTableSize)
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define PosSlot (IsRepG2 + kNumStates)
+#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define NUM_BASE_PROBS (Literal + kStartOffset)
+
+#if Align != 0 && kStartOffset != 0
+ #error Stop_Compiling_Bad_LZMA_kAlign
+#endif
+
+#if NUM_BASE_PROBS != 1984
+ #error Stop_Compiling_Bad_LZMA_PROBS
+#endif
+
+
+#define LZMA_LIT_SIZE 0x300
+
+#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+
+#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
+#define COMBINED_PS_STATE (posState + state)
+#define GET_LEN_STATE (posState)
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/*
+p->remainLen : shows status of LZMA decoder:
+ < kMatchSpecLenStart : normal remain
+ = kMatchSpecLenStart : finished
+ = kMatchSpecLenStart + 1 : need init range coder
+ = kMatchSpecLenStart + 2 : need init range coder and state
+*/
+
+/* ---------- LZMA_DECODE_REAL ---------- */
+/*
+LzmaDec_DecodeReal_3() can be implemented in external ASM file.
+3 - is the code compatibility version of that function for check at link time.
+*/
+
+#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
+
+/*
+LZMA_DECODE_REAL()
+In:
+ RangeCoder is normalized
+ if (p->dicPos == limit)
+ {
+ LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
+ So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
+ is not END_OF_PAYALOAD_MARKER, then function returns error code.
+ }
+
+Processing:
+ first LZMA symbol will be decoded in any case
+ All checks for limits are at the end of main loop,
+ It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
+ RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
+
+Out:
+ RangeCoder is normalized
+ Result:
+ SZ_OK - OK
+ SZ_ERROR_DATA - Error
+ p->remainLen:
+ < kMatchSpecLenStart : normal remain
+ = kMatchSpecLenStart : finished
+*/
+
+
+#ifdef _LZMA_DEC_OPT
+
+int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);
+
+#else
+
+static
+int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ CLzmaProb *probs = GET_PROBS;
+ unsigned state = (unsigned)p->state;
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+ unsigned lc = p->prop.lc;
+ unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);
+
+ Byte *dic = p->dic;
+ SizeT dicBufSize = p->dicBufSize;
+ SizeT dicPos = p->dicPos;
+
+ UInt32 processedPos = p->processedPos;
+ UInt32 checkDicSize = p->checkDicSize;
+ unsigned len = 0;
+
+ const Byte *buf = p->buf;
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+
+ do
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = CALC_POS_STATE(processedPos, pbMask);
+
+ prob = probs + IsMatch + COMBINED_PS_STATE;
+ IF_BIT_0(prob)
+ {
+ unsigned symbol;
+ UPDATE_0(prob);
+ prob = probs + Literal;
+ if (processedPos != 0 || checkDicSize != 0)
+ prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
+ processedPos++;
+
+ if (state < kNumLitStates)
+ {
+ state -= (state < 4) ? state : 3;
+ symbol = 1;
+ #ifdef _LZMA_SIZE_OPT
+ do { NORMAL_LITER_DEC } while (symbol < 0x100);
+ #else
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ NORMAL_LITER_DEC
+ #endif
+ }
+ else
+ {
+ unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
+ unsigned offs = 0x100;
+ state -= (state < 10) ? 3 : 6;
+ symbol = 1;
+ #ifdef _LZMA_SIZE_OPT
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ MATCHED_LITER_DEC
+ }
+ while (symbol < 0x100);
+ #else
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ MATCHED_LITER_DEC
+ }
+ #endif
+ }
+
+ dic[dicPos++] = (Byte)symbol;
+ continue;
+ }
+
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRep + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ state += kNumStates;
+ prob = probs + LenCoder;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ /*
+ // that case was checked before with kBadRepCode
+ if (checkDicSize == 0 && processedPos == 0)
+ return SZ_ERROR_DATA;
+ */
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ prob = probs + IsRep0Long + COMBINED_PS_STATE;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
+ dicPos++;
+ processedPos++;
+ state = state < kNumLitStates ? 9 : 11;
+ continue;
+ }
+ UPDATE_1(prob);
+ }
+ else
+ {
+ UInt32 distance;
+ UPDATE_1(prob);
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = probs + RepLenCoder;
+ }
+
+ #ifdef _LZMA_SIZE_OPT
+ {
+ unsigned lim, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + GET_LEN_STATE;
+ offset = 0;
+ lim = (1 << kLenNumLowBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
+ offset = kLenNumLowSymbols;
+ lim = (1 << kLenNumLowBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols * 2;
+ lim = (1 << kLenNumHighBits);
+ }
+ }
+ TREE_DECODE(probLen, lim, len);
+ len += offset;
+ }
+ #else
+ {
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + GET_LEN_STATE;
+ len = 1;
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ len -= 8;
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
+ len = 1;
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
+ len += kLenNumLowSymbols * 2;
+ }
+ }
+ }
+ #endif
+
+ if (state >= kNumStates)
+ {
+ UInt32 distance;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+ TREE_6_DECODE(prob, distance);
+ if (distance >= kStartPosModelIndex)
+ {
+ unsigned posSlot = (unsigned)distance;
+ unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
+ distance = (2 | (distance & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ distance <<= numDirectBits;
+ prob = probs + SpecPos;
+ {
+ UInt32 m = 1;
+ distance++;
+ do
+ {
+ REV_BIT_VAR(prob, distance, m);
+ }
+ while (--numDirectBits);
+ distance -= m;
+ }
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE
+ range >>= 1;
+
+ {
+ UInt32 t;
+ code -= range;
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+ distance = (distance << 1) + (t + 1);
+ code += range & t;
+ }
+ /*
+ distance <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ distance |= 1;
+ }
+ */
+ }
+ while (--numDirectBits);
+ prob = probs + Align;
+ distance <<= kNumAlignBits;
+ {
+ unsigned i = 1;
+ REV_BIT_CONST(prob, i, 1);
+ REV_BIT_CONST(prob, i, 2);
+ REV_BIT_CONST(prob, i, 4);
+ REV_BIT_LAST (prob, i, 8);
+ distance |= i;
+ }
+ if (distance == (UInt32)0xFFFFFFFF)
+ {
+ len = kMatchSpecLenStart;
+ state -= kNumStates;
+ break;
+ }
+ }
+ }
+
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = distance + 1;
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+ if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
+ {
+ p->dicPos = dicPos;
+ return SZ_ERROR_DATA;
+ }
+ }
+
+ len += kMatchMinLen;
+
+ {
+ SizeT rem;
+ unsigned curLen;
+ SizeT pos;
+
+ if ((rem = limit - dicPos) == 0)
+ {
+ p->dicPos = dicPos;
+ return SZ_ERROR_DATA;
+ }
+
+ curLen = ((rem < len) ? (unsigned)rem : len);
+ pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
+
+ processedPos += (UInt32)curLen;
+
+ len -= curLen;
+ if (curLen <= dicBufSize - pos)
+ {
+ Byte *dest = dic + dicPos;
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+ const Byte *lim = dest + curLen;
+ dicPos += (SizeT)curLen;
+ do
+ *(dest) = (Byte)*(dest + src);
+ while (++dest != lim);
+ }
+ else
+ {
+ do
+ {
+ dic[dicPos++] = dic[pos];
+ if (++pos == dicBufSize)
+ pos = 0;
+ }
+ while (--curLen != 0);
+ }
+ }
+ }
+ }
+ while (dicPos < limit && buf < bufLimit);
+
+ NORMALIZE;
+
+ p->buf = buf;
+ p->range = range;
+ p->code = code;
+ p->remainLen = (UInt32)len;
+ p->dicPos = dicPos;
+ p->processedPos = processedPos;
+ p->reps[0] = rep0;
+ p->reps[1] = rep1;
+ p->reps[2] = rep2;
+ p->reps[3] = rep3;
+ p->state = (UInt32)state;
+
+ return SZ_OK;
+}
+#endif
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+ {
+ Byte *dic = p->dic;
+ SizeT dicPos = p->dicPos;
+ SizeT dicBufSize = p->dicBufSize;
+ unsigned len = (unsigned)p->remainLen;
+ SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
+ SizeT rem = limit - dicPos;
+ if (rem < len)
+ len = (unsigned)(rem);
+
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+ p->checkDicSize = p->prop.dicSize;
+
+ p->processedPos += (UInt32)len;
+ p->remainLen -= (UInt32)len;
+ while (len != 0)
+ {
+ len--;
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
+ dicPos++;
+ }
+ p->dicPos = dicPos;
+ }
+}
+
+
+#define kRange0 0xFFFFFFFF
+#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
+#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
+#if kBadRepCode != (0xC0000000 - 0x400)
+ #error Stop_Compiling_Bad_LZMA_Check
+#endif
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ do
+ {
+ SizeT limit2 = limit;
+ if (p->checkDicSize == 0)
+ {
+ UInt32 rem = p->prop.dicSize - p->processedPos;
+ if (limit - p->dicPos > rem)
+ limit2 = p->dicPos + rem;
+
+ if (p->processedPos == 0)
+ if (p->code >= kBadRepCode)
+ return SZ_ERROR_DATA;
+ }
+
+ RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit));
+
+ if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
+ p->checkDicSize = p->prop.dicSize;
+
+ LzmaDec_WriteRem(p, limit);
+ }
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+ return 0;
+}
+
+typedef enum
+{
+ DUMMY_ERROR, /* unexpected end of input stream */
+ DUMMY_LIT,
+ DUMMY_MATCH,
+ DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+ const Byte *bufLimit = buf + inSize;
+ const CLzmaProb *probs = GET_PROBS;
+ unsigned state = (unsigned)p->state;
+ ELzmaDummy res;
+
+ {
+ const CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1);
+
+ prob = probs + IsMatch + COMBINED_PS_STATE;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK
+
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+ prob = probs + Literal;
+ if (p->checkDicSize != 0 || p->processedPos != 0)
+ prob += ((UInt32)LZMA_LIT_SIZE *
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+ if (state < kNumLitStates)
+ {
+ unsigned symbol = 1;
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+ (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
+ unsigned offs = 0x100;
+ unsigned symbol = 1;
+ do
+ {
+ unsigned bit;
+ const CLzmaProb *probLit;
+ matchByte += matchByte;
+ bit = offs;
+ offs &= matchByte;
+ probLit = prob + (offs + bit + symbol);
+ GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )
+ }
+ while (symbol < 0x100);
+ }
+ res = DUMMY_LIT;
+ }
+ else
+ {
+ unsigned len;
+ UPDATE_1_CHECK;
+
+ prob = probs + IsRep + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ state = 0;
+ prob = probs + LenCoder;
+ res = DUMMY_MATCH;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ res = DUMMY_REP;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ prob = probs + IsRep0Long + COMBINED_PS_STATE;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ NORMALIZE_CHECK;
+ return DUMMY_REP;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ }
+ state = kNumStates;
+ prob = probs + RepLenCoder;
+ }
+ {
+ unsigned limit, offset;
+ const CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenLow + GET_LEN_STATE;
+ offset = 0;
+ limit = 1 << kLenNumLowBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenChoice2;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
+ offset = kLenNumLowSymbols;
+ limit = 1 << kLenNumLowBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols * 2;
+ limit = 1 << kLenNumHighBits;
+ }
+ }
+ TREE_DECODE_CHECK(probLen, limit, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ unsigned posSlot;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ unsigned numDirectBits = ((posSlot >> 1) - 1);
+
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+ if (posSlot < kEndPosModelIndex)
+ {
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE_CHECK
+ range >>= 1;
+ code -= range & (((code - range) >> 31) - 1);
+ /* if (code >= range) code -= range; */
+ }
+ while (--numDirectBits);
+ prob = probs + Align;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ unsigned i = 1;
+ unsigned m = 1;
+ do
+ {
+ REV_BIT_CHECK(prob, i, m);
+ }
+ while (--numDirectBits);
+ }
+ }
+ }
+ }
+ }
+ NORMALIZE_CHECK;
+ return res;
+}
+
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState)
+{
+ p->remainLen = kMatchSpecLenStart + 1;
+ p->tempBufSize = 0;
+
+ if (initDic)
+ {
+ p->processedPos = 0;
+ p->checkDicSize = 0;
+ p->remainLen = kMatchSpecLenStart + 2;
+ }
+ if (initState)
+ p->remainLen = kMatchSpecLenStart + 2;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+ p->dicPos = 0;
+ LzmaDec_InitDicAndState(p, True, True);
+}
+
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+ ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT inSize = *srcLen;
+ (*srcLen) = 0;
+
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+
+ if (p->remainLen > kMatchSpecLenStart)
+ {
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+ p->tempBuf[p->tempBufSize++] = *src++;
+ if (p->tempBufSize != 0 && p->tempBuf[0] != 0)
+ return SZ_ERROR_DATA;
+ if (p->tempBufSize < RC_INIT_SIZE)
+ {
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ p->code =
+ ((UInt32)p->tempBuf[1] << 24)
+ | ((UInt32)p->tempBuf[2] << 16)
+ | ((UInt32)p->tempBuf[3] << 8)
+ | ((UInt32)p->tempBuf[4]);
+ p->range = 0xFFFFFFFF;
+ p->tempBufSize = 0;
+
+ if (p->remainLen > kMatchSpecLenStart + 1)
+ {
+ SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
+ SizeT i;
+ CLzmaProb *probs = p->probs;
+ for (i = 0; i < numProbs; i++)
+ probs[i] = kBitModelTotal >> 1;
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+ p->state = 0;
+ }
+
+ p->remainLen = 0;
+ }
+
+ LzmaDec_WriteRem(p, dicLimit);
+
+ while (p->remainLen != kMatchSpecLenStart)
+ {
+ int checkEndMarkNow = 0;
+
+ if (p->dicPos >= dicLimit)
+ {
+ if (p->remainLen == 0 && p->code == 0)
+ {
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+ return SZ_OK;
+ }
+ if (finishMode == LZMA_FINISH_ANY)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_OK;
+ }
+ if (p->remainLen != 0)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ checkEndMarkNow = 1;
+ }
+
+ if (p->tempBufSize == 0)
+ {
+ SizeT processed;
+ const Byte *bufLimit;
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ memcpy(p->tempBuf, src, inSize);
+ p->tempBufSize = (unsigned)inSize;
+ (*srcLen) += inSize;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ bufLimit = src;
+ }
+ else
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+ p->buf = src;
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+ return SZ_ERROR_DATA;
+ processed = (SizeT)(p->buf - src);
+ (*srcLen) += processed;
+ src += processed;
+ inSize -= processed;
+ }
+ else
+ {
+ unsigned rem = p->tempBufSize, lookAhead = 0;
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+ p->tempBuf[rem++] = src[lookAhead++];
+ p->tempBufSize = rem;
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, (SizeT)rem);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ (*srcLen) += (SizeT)lookAhead;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ }
+ p->buf = p->tempBuf;
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+ return SZ_ERROR_DATA;
+
+ {
+ unsigned kkk = (unsigned)(p->buf - p->tempBuf);
+ if (rem < kkk)
+ return SZ_ERROR_FAIL; /* some internal error */
+ rem -= kkk;
+ if (lookAhead < rem)
+ return SZ_ERROR_FAIL; /* some internal error */
+ lookAhead -= rem;
+ }
+ (*srcLen) += (SizeT)lookAhead;
+ src += lookAhead;
+ inSize -= (SizeT)lookAhead;
+ p->tempBufSize = 0;
+ }
+ }
+
+ if (p->code != 0)
+ return SZ_ERROR_DATA;
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
+ return SZ_OK;
+}
+
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT outSize = *destLen;
+ SizeT inSize = *srcLen;
+ *srcLen = *destLen = 0;
+ for (;;)
+ {
+ SizeT inSizeCur = inSize, outSizeCur, dicPos;
+ ELzmaFinishMode curFinishMode;
+ SRes res;
+ if (p->dicPos == p->dicBufSize)
+ p->dicPos = 0;
+ dicPos = p->dicPos;
+ if (outSize > p->dicBufSize - dicPos)
+ {
+ outSizeCur = p->dicBufSize;
+ curFinishMode = LZMA_FINISH_ANY;
+ }
+ else
+ {
+ outSizeCur = dicPos + outSize;
+ curFinishMode = finishMode;
+ }
+
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+ src += inSizeCur;
+ inSize -= inSizeCur;
+ *srcLen += inSizeCur;
+ outSizeCur = p->dicPos - dicPos;
+ memcpy(dest, p->dic + dicPos, outSizeCur);
+ dest += outSizeCur;
+ outSize -= outSizeCur;
+ *destLen += outSizeCur;
+ if (res != 0)
+ return res;
+ if (outSizeCur == 0 || outSize == 0)
+ return SZ_OK;
+ }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
+{
+ ISzAlloc_Free(alloc, p->probs);
+ p->probs = NULL;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
+{
+ ISzAlloc_Free(alloc, p->dic);
+ p->dic = NULL;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
+{
+ LzmaDec_FreeProbs(p, alloc);
+ LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+ UInt32 dicSize;
+ Byte d;
+
+ if (size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_UNSUPPORTED;
+ else
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+
+ if (dicSize < LZMA_DIC_MIN)
+ dicSize = LZMA_DIC_MIN;
+ p->dicSize = dicSize;
+
+ d = data[0];
+ if (d >= (9 * 5 * 5))
+ return SZ_ERROR_UNSUPPORTED;
+
+ p->lc = (Byte)(d % 9);
+ d /= 9;
+ p->pb = (Byte)(d / 5);
+ p->lp = (Byte)(d % 5);
+
+ return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
+{
+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+ if (!p->probs || numProbs != p->numProbs)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
+ if (!p->probs)
+ return SZ_ERROR_MEM;
+ p->probs_1664 = p->probs + 1664;
+ p->numProbs = numProbs;
+ }
+ return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
+{
+ CLzmaProps propNew;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
+{
+ CLzmaProps propNew;
+ SizeT dicBufSize;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+
+ {
+ UInt32 dictSize = propNew.dicSize;
+ SizeT mask = ((UInt32)1 << 12) - 1;
+ if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
+ else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
+ dicBufSize = ((SizeT)dictSize + mask) & ~mask;
+ if (dicBufSize < dictSize)
+ dicBufSize = dictSize;
+ }
+
+ if (!p->dic || dicBufSize != p->dicBufSize)
+ {
+ LzmaDec_FreeDict(p, alloc);
+ p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
+ if (!p->dic)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ }
+ p->dicBufSize = dicBufSize;
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAllocPtr alloc)
+{
+ CLzmaDec p;
+ SRes res;
+ SizeT outSize = *destLen, inSize = *srcLen;
+ *destLen = *srcLen = 0;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+ if (inSize < RC_INIT_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+ LzmaDec_Construct(&p);
+ RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
+ p.dic = dest;
+ p.dicBufSize = outSize;
+ LzmaDec_Init(&p);
+ *srcLen = inSize;
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+ *destLen = p.dicPos;
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ res = SZ_ERROR_INPUT_EOF;
+ LzmaDec_FreeProbs(&p, alloc);
+ return res;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h
new file mode 100644
index 00000000..f3702f5c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h
@@ -0,0 +1,234 @@
+/* LzmaDec.h -- LZMA Decoder
+2018-04-21 : Igor Pavlov : Public domain */
+
+#ifndef __LZMA_DEC_H
+#define __LZMA_DEC_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+ but memory usage for CLzmaDec::probs will be doubled in that case */
+
+typedef
+#ifdef _LZMA_PROB32
+ UInt32
+#else
+ UInt16
+#endif
+ CLzmaProb;
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+ Byte lc;
+ Byte lp;
+ Byte pb;
+ Byte _pad_;
+ UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+ SZ_OK
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+ /* Don't change this structure. ASM code can use it. */
+ CLzmaProps prop;
+ CLzmaProb *probs;
+ CLzmaProb *probs_1664;
+ Byte *dic;
+ SizeT dicBufSize;
+ SizeT dicPos;
+ const Byte *buf;
+ UInt32 range;
+ UInt32 code;
+ UInt32 processedPos;
+ UInt32 checkDicSize;
+ UInt32 reps[4];
+ UInt32 state;
+ UInt32 remainLen;
+
+ UInt32 numProbs;
+ unsigned tempBufSize;
+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+ - Stream with end mark. That end mark adds about 6 bytes to compressed size.
+ - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+ LZMA_FINISH_ANY, /* finish at any point */
+ LZMA_FINISH_END /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+ You must use LZMA_FINISH_END, when you know that current output buffer
+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+ and output value of destLen will be less than output buffer size limit.
+ You can check status result also.
+
+ You can use multiple checks to test data integrity after full decompression:
+ 1) Check Result and "status" variable.
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+ You must use correct finish mode in that case. */
+
+typedef enum
+{
+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+ 1) Dictionary Interface
+ 2) Buffer Interface
+ 3) One Call Interface
+ You can select any of these interfaces, but don't mix functions from different
+ groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+ 1) LzmaDec_Allocate / LzmaDec_Free
+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+ You can use variant 2, if you set dictionary buffer manually.
+ For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+ SZ_OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+ dictionary to some other external buffer.
+ You must work with CLzmaDec variables directly in this interface.
+
+ STEPS:
+ LzmaDec_Construct()
+ LzmaDec_Allocate()
+ for (each new stream)
+ {
+ LzmaDec_Init()
+ while (it needs more decompression)
+ {
+ LzmaDec_DecodeToDic()
+ use data from CLzmaDec::dic and update CLzmaDec::dicPos
+ }
+ }
+ LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+
+ The decoding to internal dictionary buffer (CLzmaDec::dic).
+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (dicLimit).
+ LZMA_FINISH_ANY - Decode just dicLimit bytes.
+ LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_NEEDS_MORE_INPUT
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+ See LzmaDec_DecodeToDic description for information about STEPS and return results,
+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+ to work with CLzmaDec variables manually.
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAllocPtr alloc);
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
new file mode 100644
index 00000000..68e97c95
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
@@ -0,0 +1,2976 @@
+/* LzmaEnc.c -- LZMA Encoder
+2019-01-10: Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#include <string.h>
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
+#include <stdio.h>
+#endif
+
+#include "LzmaEnc.h"
+
+#include "LzFind.h"
+#ifndef _7ZIP_ST
+#include "LzFindMt.h"
+#endif
+
+#ifdef SHOW_STAT
+static unsigned g_STAT_OFFSET = 0;
+#endif
+
+#define kLzmaMaxHistorySize ((UInt32)3 << 29)
+/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+#define kProbInitValue (kBitModelTotal >> 1)
+
+#define kNumMoveReducingBits 4
+#define kNumBitPriceShiftBits 4
+#define kBitPrice (1 << kNumBitPriceShiftBits)
+
+#define REP_LEN_COUNT 64
+
+void LzmaEncProps_Init(CLzmaEncProps *p)
+{
+ p->level = 5;
+ p->dictSize = p->mc = 0;
+ p->reduceSize = (UInt64)(Int64)-1;
+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
+ p->writeEndMark = 0;
+}
+
+void LzmaEncProps_Normalize(CLzmaEncProps *p)
+{
+ int level = p->level;
+ if (level < 0) level = 5;
+ p->level = level;
+
+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26)));
+ if (p->dictSize > p->reduceSize)
+ {
+ unsigned i;
+ UInt32 reduceSize = (UInt32)p->reduceSize;
+ for (i = 11; i <= 30; i++)
+ {
+ if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
+ if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
+ }
+ }
+
+ if (p->lc < 0) p->lc = 3;
+ if (p->lp < 0) p->lp = 0;
+ if (p->pb < 0) p->pb = 2;
+
+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
+ if (p->numHashBytes < 0) p->numHashBytes = 4;
+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+
+ if (p->numThreads < 0)
+ p->numThreads =
+ #ifndef _7ZIP_ST
+ ((p->btMode && p->algo) ? 2 : 1);
+ #else
+ 1;
+ #endif
+}
+
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+{
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+ return props.dictSize;
+}
+
+#if (_MSC_VER >= 1400)
+/* BSR code is fast for some new CPUs */
+/* #define LZMA_LOG_BSR */
+#endif
+
+#ifdef LZMA_LOG_BSR
+
+#define kDicLogSizeMaxCompress 32
+
+#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
+
+static unsigned GetPosSlot1(UInt32 pos)
+{
+ unsigned res;
+ BSR2_RET(pos, res);
+ return res;
+}
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+
+#else
+
+#define kNumLogBits (9 + sizeof(size_t) / 2)
+/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
+
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+ unsigned slot;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+ g_FastPos += 2;
+
+ for (slot = 2; slot < kNumLogBits * 2; slot++)
+ {
+ size_t k = ((size_t)1 << ((slot >> 1) - 1));
+ size_t j;
+ for (j = 0; j < k; j++)
+ g_FastPos[j] = (Byte)slot;
+ g_FastPos += k;
+ }
+}
+
+/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
+/*
+#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
+ res = p->g_FastPos[pos >> zz] + (zz * 2); }
+*/
+
+/*
+#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
+ res = p->g_FastPos[pos >> zz] + (zz * 2); }
+*/
+
+#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
+ res = p->g_FastPos[pos >> zz] + (zz * 2); }
+
+/*
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
+ p->g_FastPos[pos >> 6] + 12 : \
+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
+*/
+
+#define GetPosSlot1(pos) p->g_FastPos[pos]
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }
+
+#endif
+
+
+#define LZMA_NUM_REPS 4
+
+typedef UInt16 CState;
+typedef UInt16 CExtra;
+
+typedef struct
+{
+ UInt32 price;
+ CState state;
+ CExtra extra;
+ // 0 : normal
+ // 1 : LIT : MATCH
+ // > 1 : MATCH (extra-1) : LIT : REP0 (len)
+ UInt32 len;
+ UInt32 dist;
+ UInt32 reps[LZMA_NUM_REPS];
+} COptimal;
+
+
+// 18.06
+#define kNumOpts (1 << 11)
+#define kPackReserve (kNumOpts * 8)
+// #define kNumOpts (1 << 12)
+// #define kPackReserve (1 + kNumOpts * 2)
+
+#define kNumLenToPosStates 4
+#define kNumPosSlotBits 6
+#define kDicLogSizeMin 0
+#define kDicLogSizeMax 32
+#define kDistTableSizeMax (kDicLogSizeMax * 2)
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+#define kAlignMask (kAlignTableSize - 1)
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+typedef
+#ifdef _LZMA_PROB32
+ UInt32
+#else
+ UInt16
+#endif
+ CLzmaProb;
+
+#define LZMA_PB_MAX 4
+#define LZMA_LC_MAX 8
+#define LZMA_LP_MAX 4
+
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols)
+
+#define LZMA_MATCH_LEN_MIN 2
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
+
+#define kNumStates 12
+
+
+typedef struct
+{
+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)];
+ CLzmaProb high[kLenNumHighSymbols];
+} CLenEnc;
+
+
+typedef struct
+{
+ unsigned tableSize;
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
+ // UInt32 prices1[LZMA_NUM_PB_STATES_MAX][kLenNumLowSymbols * 2];
+ // UInt32 prices2[kLenNumSymbolsTotal];
+} CLenPriceEnc;
+
+#define GET_PRICE_LEN(p, posState, len) \
+ ((p)->prices[posState][(size_t)(len) - LZMA_MATCH_LEN_MIN])
+
+/*
+#define GET_PRICE_LEN(p, posState, len) \
+ ((p)->prices2[(size_t)(len) - 2] + ((p)->prices1[posState][((len) - 2) & (kLenNumLowSymbols * 2 - 1)] & (((len) - 2 - kLenNumLowSymbols * 2) >> 9)))
+*/
+
+typedef struct
+{
+ UInt32 range;
+ unsigned cache;
+ UInt64 low;
+ UInt64 cacheSize;
+ Byte *buf;
+ Byte *bufLim;
+ Byte *bufBase;
+ ISeqOutStream *outStream;
+ UInt64 processed;
+ SRes res;
+} CRangeEnc;
+
+
+typedef struct
+{
+ CLzmaProb *litProbs;
+
+ unsigned state;
+ UInt32 reps[LZMA_NUM_REPS];
+
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances];
+
+ CLenEnc lenProbs;
+ CLenEnc repLenProbs;
+
+} CSaveState;
+
+
+typedef UInt32 CProbPrice;
+
+
+typedef struct
+{
+ void *matchFinderObj;
+ IMatchFinder matchFinder;
+
+ unsigned optCur;
+ unsigned optEnd;
+
+ unsigned longestMatchLen;
+ unsigned numPairs;
+ UInt32 numAvail;
+
+ unsigned state;
+ unsigned numFastBytes;
+ unsigned additionalOffset;
+ UInt32 reps[LZMA_NUM_REPS];
+ unsigned lpMask, pbMask;
+ CLzmaProb *litProbs;
+ CRangeEnc rc;
+
+ UInt32 backRes;
+
+ unsigned lc, lp, pb;
+ unsigned lclp;
+
+ BoolInt fastMode;
+ BoolInt writeEndMark;
+ BoolInt finished;
+ BoolInt multiThread;
+ BoolInt needInit;
+ // BoolInt _maxMode;
+
+ UInt64 nowPos64;
+
+ unsigned matchPriceCount;
+ // unsigned alignPriceCount;
+ int repLenEncCounter;
+
+ unsigned distTableSize;
+
+ UInt32 dictSize;
+ SRes result;
+
+ #ifndef _7ZIP_ST
+ BoolInt mtMode;
+ // begin of CMatchFinderMt is used in LZ thread
+ CMatchFinderMt matchFinderMt;
+ // end of CMatchFinderMt is used in BT and HASH threads
+ #endif
+
+ CMatchFinder matchFinderBase;
+
+ #ifndef _7ZIP_ST
+ Byte pad[128];
+ #endif
+
+ // LZ thread
+ CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+
+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+
+ UInt32 alignPrices[kAlignTableSize];
+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances];
+
+ CLenEnc lenProbs;
+ CLenEnc repLenProbs;
+
+ #ifndef LZMA_LOG_BSR
+ Byte g_FastPos[1 << kNumLogBits];
+ #endif
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ COptimal opt[kNumOpts];
+
+ CSaveState saveState;
+
+ #ifndef _7ZIP_ST
+ Byte pad2[128];
+ #endif
+} CLzmaEnc;
+
+
+
+#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr));
+
+void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CSaveState *dest = &p->saveState;
+
+ dest->state = p->state;
+
+ dest->lenProbs = p->lenProbs;
+ dest->repLenProbs = p->repLenProbs;
+
+ COPY_ARR(dest, p, reps);
+
+ COPY_ARR(dest, p, posAlignEncoder);
+ COPY_ARR(dest, p, isRep);
+ COPY_ARR(dest, p, isRepG0);
+ COPY_ARR(dest, p, isRepG1);
+ COPY_ARR(dest, p, isRepG2);
+ COPY_ARR(dest, p, isMatch);
+ COPY_ARR(dest, p, isRep0Long);
+ COPY_ARR(dest, p, posSlotEncoder);
+ COPY_ARR(dest, p, posEncoders);
+
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
+
+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *dest = (CLzmaEnc *)pp;
+ const CSaveState *p = &dest->saveState;
+
+ dest->state = p->state;
+
+ dest->lenProbs = p->lenProbs;
+ dest->repLenProbs = p->repLenProbs;
+
+ COPY_ARR(dest, p, reps);
+
+ COPY_ARR(dest, p, posAlignEncoder);
+ COPY_ARR(dest, p, isRep);
+ COPY_ARR(dest, p, isRepG0);
+ COPY_ARR(dest, p, isRepG1);
+ COPY_ARR(dest, p, isRepG2);
+ COPY_ARR(dest, p, isMatch);
+ COPY_ARR(dest, p, isRep0Long);
+ COPY_ARR(dest, p, posSlotEncoder);
+ COPY_ARR(dest, p, posEncoders);
+
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
+}
+
+
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+
+ if (props.lc > LZMA_LC_MAX
+ || props.lp > LZMA_LP_MAX
+ || props.pb > LZMA_PB_MAX
+ || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
+ || props.dictSize > kLzmaMaxHistorySize)
+ return SZ_ERROR_PARAM;
+
+ p->dictSize = props.dictSize;
+ {
+ unsigned fb = props.fb;
+ if (fb < 5)
+ fb = 5;
+ if (fb > LZMA_MATCH_LEN_MAX)
+ fb = LZMA_MATCH_LEN_MAX;
+ p->numFastBytes = fb;
+ }
+ p->lc = props.lc;
+ p->lp = props.lp;
+ p->pb = props.pb;
+ p->fastMode = (props.algo == 0);
+ // p->_maxMode = True;
+ p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
+ {
+ unsigned numHashBytes = 4;
+ if (props.btMode)
+ {
+ if (props.numHashBytes < 2)
+ numHashBytes = 2;
+ else if (props.numHashBytes < 4)
+ numHashBytes = props.numHashBytes;
+ }
+ p->matchFinderBase.numHashBytes = numHashBytes;
+ }
+
+ p->matchFinderBase.cutValue = props.mc;
+
+ p->writeEndMark = props.writeEndMark;
+
+ #ifndef _7ZIP_ST
+ /*
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ */
+ p->multiThread = (props.numThreads > 1);
+ #endif
+
+ return SZ_OK;
+}
+
+
+void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->matchFinderBase.expectedDataSize = expectedDataSiize;
+}
+
+
+#define kState_Start 0
+#define kState_LitAfterMatch 4
+#define kState_LitAfterRep 5
+#define kState_MatchAfterLit 7
+#define kState_RepAfterLit 8
+
+static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+#define IsLitState(s) ((s) < 7)
+#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1)
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
+
+#define kInfinityPrice (1 << 30)
+
+static void RangeEnc_Construct(CRangeEnc *p)
+{
+ p->outStream = NULL;
+ p->bufBase = NULL;
+}
+
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + ((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize)
+
+#define RC_BUF_SIZE (1 << 16)
+
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
+{
+ if (!p->bufBase)
+ {
+ p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
+ if (!p->bufBase)
+ return 0;
+ p->bufLim = p->bufBase + RC_BUF_SIZE;
+ }
+ return 1;
+}
+
+static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
+{
+ ISzAlloc_Free(alloc, p->bufBase);
+ p->bufBase = 0;
+}
+
+static void RangeEnc_Init(CRangeEnc *p)
+{
+ /* Stream.Init(); */
+ p->range = 0xFFFFFFFF;
+ p->cache = 0;
+ p->low = 0;
+ p->cacheSize = 0;
+
+ p->buf = p->bufBase;
+
+ p->processed = 0;
+ p->res = SZ_OK;
+}
+
+MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)
+{
+ size_t num;
+ if (p->res != SZ_OK)
+ return;
+ num = p->buf - p->bufBase;
+ if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
+ p->res = SZ_ERROR_WRITE;
+ p->processed += num;
+ p->buf = p->bufBase;
+}
+
+MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+{
+ UInt32 low = (UInt32)p->low;
+ unsigned high = (unsigned)(p->low >> 32);
+ p->low = (UInt32)(low << 8);
+ if (low < (UInt32)0xFF000000 || high != 0)
+ {
+ {
+ Byte *buf = p->buf;
+ *buf++ = (Byte)(p->cache + high);
+ p->cache = (unsigned)(low >> 24);
+ p->buf = buf;
+ if (buf == p->bufLim)
+ RangeEnc_FlushStream(p);
+ if (p->cacheSize == 0)
+ return;
+ }
+ high += 0xFF;
+ for (;;)
+ {
+ Byte *buf = p->buf;
+ *buf++ = (Byte)(high);
+ p->buf = buf;
+ if (buf == p->bufLim)
+ RangeEnc_FlushStream(p);
+ if (--p->cacheSize == 0)
+ return;
+ }
+ }
+ p->cacheSize++;
+}
+
+static void RangeEnc_FlushData(CRangeEnc *p)
+{
+ int i;
+ for (i = 0; i < 5; i++)
+ RangeEnc_ShiftLow(p);
+}
+
+#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); }
+
+#define RC_BIT_PRE(p, prob) \
+ ttt = *(prob); \
+ newBound = (range >> kNumBitModelTotalBits) * ttt;
+
+// #define _LZMA_ENC_USE_BRANCH
+
+#ifdef _LZMA_ENC_USE_BRANCH
+
+#define RC_BIT(p, prob, bit) { \
+ RC_BIT_PRE(p, prob) \
+ if (bit == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \
+ else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \
+ *(prob) = (CLzmaProb)ttt; \
+ RC_NORM(p) \
+ }
+
+#else
+
+#define RC_BIT(p, prob, bit) { \
+ UInt32 mask; \
+ RC_BIT_PRE(p, prob) \
+ mask = 0 - (UInt32)bit; \
+ range &= mask; \
+ mask &= newBound; \
+ range -= mask; \
+ (p)->low += mask; \
+ mask = (UInt32)bit - 1; \
+ range += newBound & mask; \
+ mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \
+ mask += ((1 << kNumMoveBits) - 1); \
+ ttt += (Int32)(mask - ttt) >> kNumMoveBits; \
+ *(prob) = (CLzmaProb)ttt; \
+ RC_NORM(p) \
+ }
+
+#endif
+
+
+
+
+#define RC_BIT_0_BASE(p, prob) \
+ range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+
+#define RC_BIT_1_BASE(p, prob) \
+ range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \
+
+#define RC_BIT_0(p, prob) \
+ RC_BIT_0_BASE(p, prob) \
+ RC_NORM(p)
+
+#define RC_BIT_1(p, prob) \
+ RC_BIT_1_BASE(p, prob) \
+ RC_NORM(p)
+
+static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob)
+{
+ UInt32 range, ttt, newBound;
+ range = p->range;
+ RC_BIT_PRE(p, prob)
+ RC_BIT_0(p, prob)
+ p->range = range;
+}
+
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym)
+{
+ UInt32 range = p->range;
+ sym |= 0x100;
+ do
+ {
+ UInt32 ttt, newBound;
+ // RangeEnc_EncodeBit(p, probs + (sym >> 8), (sym >> 7) & 1);
+ CLzmaProb *prob = probs + (sym >> 8);
+ UInt32 bit = (sym >> 7) & 1;
+ sym <<= 1;
+ RC_BIT(p, prob, bit);
+ }
+ while (sym < 0x10000);
+ p->range = range;
+}
+
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UInt32 matchByte)
+{
+ UInt32 range = p->range;
+ UInt32 offs = 0x100;
+ sym |= 0x100;
+ do
+ {
+ UInt32 ttt, newBound;
+ CLzmaProb *prob;
+ UInt32 bit;
+ matchByte <<= 1;
+ // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (sym >> 8)), (sym >> 7) & 1);
+ prob = probs + (offs + (matchByte & offs) + (sym >> 8));
+ bit = (sym >> 7) & 1;
+ sym <<= 1;
+ offs &= ~(matchByte ^ sym);
+ RC_BIT(p, prob, bit);
+ }
+ while (sym < 0x10000);
+ p->range = range;
+}
+
+
+
+static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices)
+{
+ UInt32 i;
+ for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++)
+ {
+ const unsigned kCyclesBits = kNumBitPriceShiftBits;
+ UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1));
+ unsigned bitCount = 0;
+ unsigned j;
+ for (j = 0; j < kCyclesBits; j++)
+ {
+ w = w * w;
+ bitCount <<= 1;
+ while (w >= ((UInt32)1 << 16))
+ {
+ w >>= 1;
+ bitCount++;
+ }
+ }
+ ProbPrices[i] = (CProbPrice)((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+ // printf("\n%3d: %5d", i, ProbPrices[i]);
+ }
+}
+
+
+#define GET_PRICE(prob, bit) \
+ p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICEa(prob, bit) \
+ ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 sym, const CProbPrice *ProbPrices)
+{
+ UInt32 price = 0;
+ sym |= 0x100;
+ do
+ {
+ unsigned bit = sym & 1;
+ sym >>= 1;
+ price += GET_PRICEa(probs[sym], bit);
+ }
+ while (sym >= 2);
+ return price;
+}
+
+
+static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 sym, UInt32 matchByte, const CProbPrice *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 offs = 0x100;
+ sym |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (sym >> 8)], (sym >> 7) & 1);
+ sym <<= 1;
+ offs &= ~(matchByte ^ sym);
+ }
+ while (sym < 0x10000);
+ return price;
+}
+
+
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, unsigned sym)
+{
+ UInt32 range = rc->range;
+ unsigned m = 1;
+ do
+ {
+ UInt32 ttt, newBound;
+ unsigned bit = sym & 1;
+ // RangeEnc_EncodeBit(rc, probs + m, bit);
+ sym >>= 1;
+ RC_BIT(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ }
+ while (--numBits);
+ rc->range = range;
+}
+
+
+
+static void LenEnc_Init(CLenEnc *p)
+{
+ unsigned i;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++)
+ p->low[i] = kProbInitValue;
+ for (i = 0; i < kLenNumHighSymbols; i++)
+ p->high[i] = kProbInitValue;
+}
+
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posState)
+{
+ UInt32 range, ttt, newBound;
+ CLzmaProb *probs = p->low;
+ range = rc->range;
+ RC_BIT_PRE(rc, probs);
+ if (sym >= kLenNumLowSymbols)
+ {
+ RC_BIT_1(rc, probs);
+ probs += kLenNumLowSymbols;
+ RC_BIT_PRE(rc, probs);
+ if (sym >= kLenNumLowSymbols * 2)
+ {
+ RC_BIT_1(rc, probs);
+ rc->range = range;
+ // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2);
+ LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2);
+ return;
+ }
+ sym -= kLenNumLowSymbols;
+ }
+
+ // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, sym);
+ {
+ unsigned m;
+ unsigned bit;
+ RC_BIT_0(rc, probs);
+ probs += (posState << (1 + kLenNumLowBits));
+ bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit;
+ bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit;
+ bit = sym & 1; RC_BIT(rc, probs + m, bit);
+ rc->range = range;
+ }
+}
+
+static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices)
+{
+ unsigned i;
+ for (i = 0; i < 8; i += 2)
+ {
+ UInt32 price = startPrice;
+ UInt32 prob;
+ price += GET_PRICEa(probs[1 ], (i >> 2));
+ price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1);
+ prob = probs[4 + (i >> 1)];
+ prices[i ] = price + GET_PRICEa_0(prob);
+ prices[i + 1] = price + GET_PRICEa_1(prob);
+ }
+}
+
+
+MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTables(
+ CLenPriceEnc *p,
+ unsigned numPosStates,
+ const CLenEnc *enc,
+ const CProbPrice *ProbPrices)
+{
+ UInt32 b;
+
+ {
+ unsigned prob = enc->low[0];
+ UInt32 a, c;
+ unsigned posState;
+ b = GET_PRICEa_1(prob);
+ a = GET_PRICEa_0(prob);
+ c = b + GET_PRICEa_0(enc->low[kLenNumLowSymbols]);
+ for (posState = 0; posState < numPosStates; posState++)
+ {
+ UInt32 *prices = p->prices[posState];
+ const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits));
+ SetPrices_3(probs, a, prices, ProbPrices);
+ SetPrices_3(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols, ProbPrices);
+ }
+ }
+
+ /*
+ {
+ unsigned i;
+ UInt32 b;
+ a = GET_PRICEa_0(enc->low[0]);
+ for (i = 0; i < kLenNumLowSymbols; i++)
+ p->prices2[i] = a;
+ a = GET_PRICEa_1(enc->low[0]);
+ b = a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]);
+ for (i = kLenNumLowSymbols; i < kLenNumLowSymbols * 2; i++)
+ p->prices2[i] = b;
+ a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
+ }
+ */
+
+ // p->counter = numSymbols;
+ // p->counter = 64;
+
+ {
+ unsigned i = p->tableSize;
+
+ if (i > kLenNumLowSymbols * 2)
+ {
+ const CLzmaProb *probs = enc->high;
+ UInt32 *prices = p->prices[0] + kLenNumLowSymbols * 2;
+ i -= kLenNumLowSymbols * 2 - 1;
+ i >>= 1;
+ b += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
+ do
+ {
+ /*
+ p->prices2[i] = a +
+ // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices);
+ LitEnc_GetPrice(probs, i - kLenNumLowSymbols * 2, ProbPrices);
+ */
+ // UInt32 price = a + RcTree_GetPrice(probs, kLenNumHighBits - 1, sym, ProbPrices);
+ unsigned sym = --i + (1 << (kLenNumHighBits - 1));
+ UInt32 price = b;
+ do
+ {
+ unsigned bit = sym & 1;
+ sym >>= 1;
+ price += GET_PRICEa(probs[sym], bit);
+ }
+ while (sym >= 2);
+
+ {
+ unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))];
+ prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob);
+ prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob);
+ }
+ }
+ while (i);
+
+ {
+ unsigned posState;
+ size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]);
+ for (posState = 1; posState < numPosStates; posState++)
+ memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num);
+ }
+ }
+ }
+}
+
+/*
+ #ifdef SHOW_STAT
+ g_STAT_OFFSET += num;
+ printf("\n MovePos %u", num);
+ #endif
+*/
+
+#define MOVE_POS(p, num) { \
+ p->additionalOffset += (num); \
+ p->matchFinder.Skip(p->matchFinderObj, (UInt32)(num)); }
+
+
+static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
+{
+ unsigned numPairs;
+
+ p->additionalOffset++;
+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+ *numPairsRes = numPairs;
+
+ #ifdef SHOW_STAT
+ printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
+ g_STAT_OFFSET++;
+ {
+ unsigned i;
+ for (i = 0; i < numPairs; i += 2)
+ printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
+ }
+ #endif
+
+ if (numPairs == 0)
+ return 0;
+ {
+ unsigned len = p->matches[(size_t)numPairs - 2];
+ if (len != p->numFastBytes)
+ return len;
+ {
+ UInt32 numAvail = p->numAvail;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ {
+ const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ const Byte *p2 = p1 + len;
+ ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
+ const Byte *lim = p1 + numAvail;
+ for (; p2 != lim && *p2 == p2[dif]; p2++)
+ {}
+ return (unsigned)(p2 - p1);
+ }
+ }
+ }
+}
+
+#define MARK_LIT ((UInt32)(Int32)-1)
+
+#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; }
+#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; }
+#define IsShortRep(p) ((p)->dist == 0)
+
+
+#define GetPrice_ShortRep(p, state, posState) \
+ ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState]))
+
+#define GetPrice_Rep_0(p, state, posState) ( \
+ GET_PRICE_1(p->isMatch[state][posState]) \
+ + GET_PRICE_1(p->isRep0Long[state][posState])) \
+ + GET_PRICE_1(p->isRep[state]) \
+ + GET_PRICE_0(p->isRepG0[state])
+
+MY_FORCE_INLINE
+static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState)
+{
+ UInt32 price;
+ UInt32 prob = p->isRepG0[state];
+ if (repIndex == 0)
+ {
+ price = GET_PRICE_0(prob);
+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
+ }
+ else
+ {
+ price = GET_PRICE_1(prob);
+ prob = p->isRepG1[state];
+ if (repIndex == 1)
+ price += GET_PRICE_0(prob);
+ else
+ {
+ price += GET_PRICE_1(prob);
+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
+ }
+ }
+ return price;
+}
+
+
+static unsigned Backward(CLzmaEnc *p, unsigned cur)
+{
+ unsigned wr = cur + 1;
+ p->optEnd = wr;
+
+ for (;;)
+ {
+ UInt32 dist = p->opt[cur].dist;
+ unsigned len = (unsigned)p->opt[cur].len;
+ unsigned extra = (unsigned)p->opt[cur].extra;
+ cur -= len;
+
+ if (extra)
+ {
+ wr--;
+ p->opt[wr].len = (UInt32)len;
+ cur -= extra;
+ len = extra;
+ if (extra == 1)
+ {
+ p->opt[wr].dist = dist;
+ dist = MARK_LIT;
+ }
+ else
+ {
+ p->opt[wr].dist = 0;
+ len--;
+ wr--;
+ p->opt[wr].dist = MARK_LIT;
+ p->opt[wr].len = 1;
+ }
+ }
+
+ if (cur == 0)
+ {
+ p->backRes = dist;
+ p->optCur = wr;
+ return len;
+ }
+
+ wr--;
+ p->opt[wr].dist = dist;
+ p->opt[wr].len = (UInt32)len;
+ }
+}
+
+
+
+#define LIT_PROBS(pos, prevByte) \
+ (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc))
+
+
+static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
+{
+ unsigned last, cur;
+ UInt32 reps[LZMA_NUM_REPS];
+ unsigned repLens[LZMA_NUM_REPS];
+ UInt32 *matches;
+
+ {
+ UInt32 numAvail;
+ unsigned numPairs, mainLen, repMaxIndex, i, posState;
+ UInt32 matchPrice, repMatchPrice;
+ const Byte *data;
+ Byte curByte, matchByte;
+
+ p->optCur = p->optEnd = 0;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLen;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ if (numAvail < 2)
+ {
+ p->backRes = MARK_LIT;
+ return 1;
+ }
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ repMaxIndex = 0;
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ unsigned len;
+ const Byte *data2;
+ reps[i] = p->reps[i];
+ data2 = data - reps[i];
+ if (data[0] != data2[0] || data[1] != data2[1])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++)
+ {}
+ repLens[i] = len;
+ if (len > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+
+ if (repLens[repMaxIndex] >= p->numFastBytes)
+ {
+ unsigned len;
+ p->backRes = (UInt32)repMaxIndex;
+ len = repLens[repMaxIndex];
+ MOVE_POS(p, len - 1)
+ return len;
+ }
+
+ matches = p->matches;
+
+ if (mainLen >= p->numFastBytes)
+ {
+ p->backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
+ MOVE_POS(p, mainLen - 1)
+ return mainLen;
+ }
+
+ curByte = *data;
+ matchByte = *(data - reps[0]);
+
+ last = repLens[repMaxIndex];
+ if (last <= mainLen)
+ last = mainLen;
+
+ if (last < 2 && curByte != matchByte)
+ {
+ p->backRes = MARK_LIT;
+ return 1;
+ }
+
+ p->opt[0].state = (CState)p->state;
+
+ posState = (position & p->pbMask);
+
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
+ (!IsLitState(p->state) ?
+ LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ MakeAs_Lit(&p->opt[1]);
+
+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
+
+ // 18.06
+ if (matchByte == curByte && repLens[0] == 0)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState);
+ if (shortRepPrice < p->opt[1].price)
+ {
+ p->opt[1].price = shortRepPrice;
+ MakeAs_ShortRep(&p->opt[1]);
+ }
+ if (last < 2)
+ {
+ p->backRes = p->opt[1].dist;
+ return 1;
+ }
+ }
+
+ p->opt[1].len = 1;
+
+ p->opt[0].reps[0] = reps[0];
+ p->opt[0].reps[1] = reps[1];
+ p->opt[0].reps[2] = reps[2];
+ p->opt[0].reps[3] = reps[3];
+
+ // ---------- REP ----------
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ unsigned repLen = repLens[i];
+ UInt32 price;
+ if (repLen < 2)
+ continue;
+ price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState);
+ do
+ {
+ UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, repLen);
+ COptimal *opt = &p->opt[repLen];
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = (UInt32)repLen;
+ opt->dist = (UInt32)i;
+ opt->extra = 0;
+ }
+ }
+ while (--repLen >= 2);
+ }
+
+
+ // ---------- MATCH ----------
+ {
+ unsigned len = repLens[0] + 1;
+ if (len <= mainLen)
+ {
+ unsigned offs = 0;
+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
+
+ if (len < 2)
+ len = 2;
+ else
+ while (len > matches[offs])
+ offs += 2;
+
+ for (; ; len++)
+ {
+ COptimal *opt;
+ UInt32 dist = matches[(size_t)offs + 1];
+ UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
+ unsigned lenToPosState = GetLenToPosState(len);
+
+ if (dist < kNumFullDistances)
+ price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
+ else
+ {
+ unsigned slot;
+ GetPosSlot2(dist, slot);
+ price += p->alignPrices[dist & kAlignMask];
+ price += p->posSlotPrices[lenToPosState][slot];
+ }
+
+ opt = &p->opt[len];
+
+ if (price < opt->price)
+ {
+ opt->price = price;
+ opt->len = (UInt32)len;
+ opt->dist = dist + LZMA_NUM_REPS;
+ opt->extra = 0;
+ }
+
+ if (len == matches[offs])
+ {
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ }
+ }
+ }
+ }
+
+
+ cur = 0;
+
+ #ifdef SHOW_STAT2
+ /* if (position >= 0) */
+ {
+ unsigned i;
+ printf("\n pos = %4X", position);
+ for (i = cur; i <= last; i++)
+ printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
+ }
+ #endif
+ }
+
+
+
+ // ---------- Optimal Parsing ----------
+
+ for (;;)
+ {
+ unsigned numAvail;
+ UInt32 numAvailFull;
+ unsigned newLen, numPairs, prev, state, posState, startLen;
+ UInt32 litPrice, matchPrice, repMatchPrice;
+ BoolInt nextIsLit;
+ Byte curByte, matchByte;
+ const Byte *data;
+ COptimal *curOpt, *nextOpt;
+
+ if (++cur == last)
+ break;
+
+ // 18.06
+ if (cur >= kNumOpts - 64)
+ {
+ unsigned j, best;
+ UInt32 price = p->opt[cur].price;
+ best = cur;
+ for (j = cur + 1; j <= last; j++)
+ {
+ UInt32 price2 = p->opt[j].price;
+ if (price >= price2)
+ {
+ price = price2;
+ best = j;
+ }
+ }
+ {
+ unsigned delta = best - cur;
+ if (delta != 0)
+ {
+ MOVE_POS(p, delta);
+ }
+ }
+ cur = best;
+ break;
+ }
+
+ newLen = ReadMatchDistances(p, &numPairs);
+
+ if (newLen >= p->numFastBytes)
+ {
+ p->numPairs = numPairs;
+ p->longestMatchLen = newLen;
+ break;
+ }
+
+ curOpt = &p->opt[cur];
+
+ position++;
+
+ // we need that check here, if skip_items in p->opt are possible
+ /*
+ if (curOpt->price >= kInfinityPrice)
+ continue;
+ */
+
+ prev = cur - curOpt->len;
+
+ if (curOpt->len == 1)
+ {
+ state = (unsigned)p->opt[prev].state;
+ if (IsShortRep(curOpt))
+ state = kShortRepNextStates[state];
+ else
+ state = kLiteralNextStates[state];
+ }
+ else
+ {
+ const COptimal *prevOpt;
+ UInt32 b0;
+ UInt32 dist = curOpt->dist;
+
+ if (curOpt->extra)
+ {
+ prev -= (unsigned)curOpt->extra;
+ state = kState_RepAfterLit;
+ if (curOpt->extra == 1)
+ state = (dist < LZMA_NUM_REPS ? kState_RepAfterLit : kState_MatchAfterLit);
+ }
+ else
+ {
+ state = (unsigned)p->opt[prev].state;
+ if (dist < LZMA_NUM_REPS)
+ state = kRepNextStates[state];
+ else
+ state = kMatchNextStates[state];
+ }
+
+ prevOpt = &p->opt[prev];
+ b0 = prevOpt->reps[0];
+
+ if (dist < LZMA_NUM_REPS)
+ {
+ if (dist == 0)
+ {
+ reps[0] = b0;
+ reps[1] = prevOpt->reps[1];
+ reps[2] = prevOpt->reps[2];
+ reps[3] = prevOpt->reps[3];
+ }
+ else
+ {
+ reps[1] = b0;
+ b0 = prevOpt->reps[1];
+ if (dist == 1)
+ {
+ reps[0] = b0;
+ reps[2] = prevOpt->reps[2];
+ reps[3] = prevOpt->reps[3];
+ }
+ else
+ {
+ reps[2] = b0;
+ reps[0] = prevOpt->reps[dist];
+ reps[3] = prevOpt->reps[dist ^ 1];
+ }
+ }
+ }
+ else
+ {
+ reps[0] = (dist - LZMA_NUM_REPS + 1);
+ reps[1] = b0;
+ reps[2] = prevOpt->reps[1];
+ reps[3] = prevOpt->reps[2];
+ }
+ }
+
+ curOpt->state = (CState)state;
+ curOpt->reps[0] = reps[0];
+ curOpt->reps[1] = reps[1];
+ curOpt->reps[2] = reps[2];
+ curOpt->reps[3] = reps[3];
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ curByte = *data;
+ matchByte = *(data - reps[0]);
+
+ posState = (position & p->pbMask);
+
+ /*
+ The order of Price checks:
+ < LIT
+ <= SHORT_REP
+ < LIT : REP_0
+ < REP [ : LIT : REP_0 ]
+ < MATCH [ : LIT : REP_0 ]
+ */
+
+ {
+ UInt32 curPrice = curOpt->price;
+ unsigned prob = p->isMatch[state][posState];
+ matchPrice = curPrice + GET_PRICE_1(prob);
+ litPrice = curPrice + GET_PRICE_0(prob);
+ }
+
+ nextOpt = &p->opt[(size_t)cur + 1];
+ nextIsLit = False;
+
+ // here we can allow skip_items in p->opt, if we don't check (nextOpt->price < kInfinityPrice)
+ // 18.new.06
+ if ((nextOpt->price < kInfinityPrice
+ // && !IsLitState(state)
+ && matchByte == curByte)
+ || litPrice > nextOpt->price
+ )
+ litPrice = 0;
+ else
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ litPrice += (!IsLitState(state) ?
+ LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+
+ if (litPrice < nextOpt->price)
+ {
+ nextOpt->price = litPrice;
+ nextOpt->len = 1;
+ MakeAs_Lit(nextOpt);
+ nextIsLit = True;
+ }
+ }
+
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
+
+ numAvailFull = p->numAvail;
+ {
+ unsigned temp = kNumOpts - 1 - cur;
+ if (numAvailFull > temp)
+ numAvailFull = (UInt32)temp;
+ }
+
+ // 18.06
+ // ---------- SHORT_REP ----------
+ if (IsLitState(state)) // 18.new
+ if (matchByte == curByte)
+ if (repMatchPrice < nextOpt->price) // 18.new
+ // if (numAvailFull < 2 || data[1] != *(data - reps[0] + 1))
+ if (
+ // nextOpt->price >= kInfinityPrice ||
+ nextOpt->len < 2 // we can check nextOpt->len, if skip items are not allowed in p->opt
+ || (nextOpt->dist != 0
+ // && nextOpt->extra <= 1 // 17.old
+ )
+ )
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState);
+ // if (shortRepPrice <= nextOpt->price) // 17.old
+ if (shortRepPrice < nextOpt->price) // 18.new
+ {
+ nextOpt->price = shortRepPrice;
+ nextOpt->len = 1;
+ MakeAs_ShortRep(nextOpt);
+ nextIsLit = False;
+ }
+ }
+
+ if (numAvailFull < 2)
+ continue;
+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
+
+ // numAvail <= p->numFastBytes
+
+ // ---------- LIT : REP_0 ----------
+
+ if (!nextIsLit
+ && litPrice != 0 // 18.new
+ && matchByte != curByte
+ && numAvailFull > 2)
+ {
+ const Byte *data2 = data - reps[0];
+ if (data[1] == data2[1] && data[2] == data2[2])
+ {
+ unsigned len;
+ unsigned limit = p->numFastBytes + 1;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (len = 3; len < limit && data[len] == data2[len]; len++)
+ {}
+
+ {
+ unsigned state2 = kLiteralNextStates[state];
+ unsigned posState2 = (position + 1) & p->pbMask;
+ UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2);
+ {
+ unsigned offset = cur + len;
+
+ if (last < offset)
+ last = offset;
+
+ // do
+ {
+ UInt32 price2;
+ COptimal *opt;
+ len--;
+ // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2);
+ price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len);
+
+ opt = &p->opt[offset];
+ // offset--;
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = (UInt32)len;
+ opt->dist = 0;
+ opt->extra = 1;
+ }
+ }
+ // while (len >= 3);
+ }
+ }
+ }
+ }
+
+ startLen = 2; /* speed optimization */
+
+ {
+ // ---------- REP ----------
+ unsigned repIndex = 0; // 17.old
+ // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused
+ for (; repIndex < LZMA_NUM_REPS; repIndex++)
+ {
+ unsigned len;
+ UInt32 price;
+ const Byte *data2 = data - reps[repIndex];
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++)
+ {}
+
+ // if (len < startLen) continue; // 18.new: speed optimization
+
+ {
+ unsigned offset = cur + len;
+ if (last < offset)
+ last = offset;
+ }
+ {
+ unsigned len2 = len;
+ price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState);
+ do
+ {
+ UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, len2);
+ COptimal *opt = &p->opt[cur + len2];
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = (UInt32)len2;
+ opt->dist = (UInt32)repIndex;
+ opt->extra = 0;
+ }
+ }
+ while (--len2 >= 2);
+ }
+
+ if (repIndex == 0) startLen = len + 1; // 17.old
+ // startLen = len + 1; // 18.new
+
+ /* if (_maxMode) */
+ {
+ // ---------- REP : LIT : REP_0 ----------
+ // numFastBytes + 1 + numFastBytes
+
+ unsigned len2 = len + 1;
+ unsigned limit = len2 + p->numFastBytes;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+
+ len2 += 2;
+ if (len2 <= limit)
+ if (data[len2 - 2] == data2[len2 - 2])
+ if (data[len2 - 1] == data2[len2 - 1])
+ {
+ unsigned state2 = kRepNextStates[state];
+ unsigned posState2 = (position + len) & p->pbMask;
+ price += GET_PRICE_LEN(&p->repLenEnc, posState, len)
+ + GET_PRICE_0(p->isMatch[state2][posState2])
+ + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
+ data[len], data2[len], p->ProbPrices);
+
+ // state2 = kLiteralNextStates[state2];
+ state2 = kState_LitAfterRep;
+ posState2 = (posState2 + 1) & p->pbMask;
+
+
+ price += GetPrice_Rep_0(p, state2, posState2);
+
+ for (; len2 < limit && data[len2] == data2[len2]; len2++)
+ {}
+
+ len2 -= len;
+ // if (len2 >= 3)
+ {
+ {
+ unsigned offset = cur + len + len2;
+
+ if (last < offset)
+ last = offset;
+ // do
+ {
+ UInt32 price2;
+ COptimal *opt;
+ len2--;
+ // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
+ price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2);
+
+ opt = &p->opt[offset];
+ // offset--;
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = (UInt32)len2;
+ opt->extra = (CExtra)(len + 1);
+ opt->dist = (UInt32)repIndex;
+ }
+ }
+ // while (len2 >= 3);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ // ---------- MATCH ----------
+ /* for (unsigned len = 2; len <= newLen; len++) */
+ if (newLen > numAvail)
+ {
+ newLen = numAvail;
+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
+ matches[numPairs] = (UInt32)newLen;
+ numPairs += 2;
+ }
+
+ // startLen = 2; /* speed optimization */
+
+ if (newLen >= startLen)
+ {
+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
+ UInt32 dist;
+ unsigned offs, posSlot, len;
+
+ {
+ unsigned offset = cur + newLen;
+ if (last < offset)
+ last = offset;
+ }
+
+ offs = 0;
+ while (startLen > matches[offs])
+ offs += 2;
+ dist = matches[(size_t)offs + 1];
+
+ // if (dist >= kNumFullDistances)
+ GetPosSlot2(dist, posSlot);
+
+ for (len = /*2*/ startLen; ; len++)
+ {
+ UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
+ {
+ COptimal *opt;
+ unsigned lenNorm = len - 2;
+ lenNorm = GetLenToPosState2(lenNorm);
+ if (dist < kNumFullDistances)
+ price += p->distancesPrices[lenNorm][dist & (kNumFullDistances - 1)];
+ else
+ price += p->posSlotPrices[lenNorm][posSlot] + p->alignPrices[dist & kAlignMask];
+
+ opt = &p->opt[cur + len];
+ if (price < opt->price)
+ {
+ opt->price = price;
+ opt->len = (UInt32)len;
+ opt->dist = dist + LZMA_NUM_REPS;
+ opt->extra = 0;
+ }
+ }
+
+ if (len == matches[offs])
+ {
+ // if (p->_maxMode) {
+ // MATCH : LIT : REP_0
+
+ const Byte *data2 = data - dist - 1;
+ unsigned len2 = len + 1;
+ unsigned limit = len2 + p->numFastBytes;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+
+ len2 += 2;
+ if (len2 <= limit)
+ if (data[len2 - 2] == data2[len2 - 2])
+ if (data[len2 - 1] == data2[len2 - 1])
+ {
+ for (; len2 < limit && data[len2] == data2[len2]; len2++)
+ {}
+
+ len2 -= len;
+
+ // if (len2 >= 3)
+ {
+ unsigned state2 = kMatchNextStates[state];
+ unsigned posState2 = (position + len) & p->pbMask;
+ unsigned offset;
+ price += GET_PRICE_0(p->isMatch[state2][posState2]);
+ price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
+ data[len], data2[len], p->ProbPrices);
+
+ // state2 = kLiteralNextStates[state2];
+ state2 = kState_LitAfterMatch;
+
+ posState2 = (posState2 + 1) & p->pbMask;
+ price += GetPrice_Rep_0(p, state2, posState2);
+
+ offset = cur + len + len2;
+
+ if (last < offset)
+ last = offset;
+ // do
+ {
+ UInt32 price2;
+ COptimal *opt;
+ len2--;
+ // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
+ price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2);
+ opt = &p->opt[offset];
+ // offset--;
+ if (price2 < opt->price)
+ {
+ opt->price = price2;
+ opt->len = (UInt32)len2;
+ opt->extra = (CExtra)(len + 1);
+ opt->dist = dist + LZMA_NUM_REPS;
+ }
+ }
+ // while (len2 >= 3);
+ }
+
+ }
+
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ dist = matches[(size_t)offs + 1];
+ // if (dist >= kNumFullDistances)
+ GetPosSlot2(dist, posSlot);
+ }
+ }
+ }
+ }
+
+ do
+ p->opt[last].price = kInfinityPrice;
+ while (--last);
+
+ return Backward(p, cur);
+}
+
+
+
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
+
+
+
+static unsigned GetOptimumFast(CLzmaEnc *p)
+{
+ UInt32 numAvail, mainDist;
+ unsigned mainLen, numPairs, repIndex, repLen, i;
+ const Byte *data;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLen;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ p->backRes = MARK_LIT;
+ if (numAvail < 2)
+ return 1;
+ // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ repLen = repIndex = 0;
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ unsigned len;
+ const Byte *data2 = data - p->reps[i];
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++)
+ {}
+ if (len >= p->numFastBytes)
+ {
+ p->backRes = (UInt32)i;
+ MOVE_POS(p, len - 1)
+ return len;
+ }
+ if (len > repLen)
+ {
+ repIndex = i;
+ repLen = len;
+ }
+ }
+
+ if (mainLen >= p->numFastBytes)
+ {
+ p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
+ MOVE_POS(p, mainLen - 1)
+ return mainLen;
+ }
+
+ mainDist = 0; /* for GCC */
+
+ if (mainLen >= 2)
+ {
+ mainDist = p->matches[(size_t)numPairs - 1];
+ while (numPairs > 2)
+ {
+ UInt32 dist2;
+ if (mainLen != p->matches[(size_t)numPairs - 4] + 1)
+ break;
+ dist2 = p->matches[(size_t)numPairs - 3];
+ if (!ChangePair(dist2, mainDist))
+ break;
+ numPairs -= 2;
+ mainLen--;
+ mainDist = dist2;
+ }
+ if (mainLen == 2 && mainDist >= 0x80)
+ mainLen = 1;
+ }
+
+ if (repLen >= 2)
+ if ( repLen + 1 >= mainLen
+ || (repLen + 2 >= mainLen && mainDist >= (1 << 9))
+ || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))
+ {
+ p->backRes = (UInt32)repIndex;
+ MOVE_POS(p, repLen - 1)
+ return repLen;
+ }
+
+ if (mainLen < 2 || numAvail <= 2)
+ return 1;
+
+ {
+ unsigned len1 = ReadMatchDistances(p, &p->numPairs);
+ p->longestMatchLen = len1;
+
+ if (len1 >= 2)
+ {
+ UInt32 newDist = p->matches[(size_t)p->numPairs - 1];
+ if ( (len1 >= mainLen && newDist < mainDist)
+ || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))
+ || (len1 > mainLen + 1)
+ || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))
+ return 1;
+ }
+ }
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ unsigned len, limit;
+ const Byte *data2 = data - p->reps[i];
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ limit = mainLen - 1;
+ for (len = 2;; len++)
+ {
+ if (len >= limit)
+ return 1;
+ if (data[len] != data2[len])
+ break;
+ }
+ }
+
+ p->backRes = mainDist + LZMA_NUM_REPS;
+ if (mainLen != 2)
+ {
+ MOVE_POS(p, mainLen - 2)
+ }
+ return mainLen;
+}
+
+
+
+
+static void WriteEndMarker(CLzmaEnc *p, unsigned posState)
+{
+ UInt32 range;
+ range = p->rc.range;
+ {
+ UInt32 ttt, newBound;
+ CLzmaProb *prob = &p->isMatch[p->state][posState];
+ RC_BIT_PRE(&p->rc, prob)
+ RC_BIT_1(&p->rc, prob)
+ prob = &p->isRep[p->state];
+ RC_BIT_PRE(&p->rc, prob)
+ RC_BIT_0(&p->rc, prob)
+ }
+ p->state = kMatchNextStates[p->state];
+
+ p->rc.range = range;
+ LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState);
+ range = p->rc.range;
+
+ {
+ // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1);
+ CLzmaProb *probs = p->posSlotEncoder[0];
+ unsigned m = 1;
+ do
+ {
+ UInt32 ttt, newBound;
+ RC_BIT_PRE(p, probs + m)
+ RC_BIT_1(&p->rc, probs + m);
+ m = (m << 1) + 1;
+ }
+ while (m < (1 << kNumPosSlotBits));
+ }
+ {
+ // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range;
+ unsigned numBits = 30 - kNumAlignBits;
+ do
+ {
+ range >>= 1;
+ p->rc.low += range;
+ RC_NORM(&p->rc)
+ }
+ while (--numBits);
+ }
+
+ {
+ // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+ CLzmaProb *probs = p->posAlignEncoder;
+ unsigned m = 1;
+ do
+ {
+ UInt32 ttt, newBound;
+ RC_BIT_PRE(p, probs + m)
+ RC_BIT_1(&p->rc, probs + m);
+ m = (m << 1) + 1;
+ }
+ while (m < kAlignTableSize);
+ }
+ p->rc.range = range;
+}
+
+
+static SRes CheckErrors(CLzmaEnc *p)
+{
+ if (p->result != SZ_OK)
+ return p->result;
+ if (p->rc.res != SZ_OK)
+ p->result = SZ_ERROR_WRITE;
+ if (p->matchFinderBase.result != SZ_OK)
+ p->result = SZ_ERROR_READ;
+ if (p->result != SZ_OK)
+ p->finished = True;
+ return p->result;
+}
+
+
+MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+{
+ /* ReleaseMFStream(); */
+ p->finished = True;
+ if (p->writeEndMark)
+ WriteEndMarker(p, nowPos & p->pbMask);
+ RangeEnc_FlushData(&p->rc);
+ RangeEnc_FlushStream(&p->rc);
+ return CheckErrors(p);
+}
+
+
+MY_NO_INLINE static void FillAlignPrices(CLzmaEnc *p)
+{
+ unsigned i;
+ const CProbPrice *ProbPrices = p->ProbPrices;
+ const CLzmaProb *probs = p->posAlignEncoder;
+ // p->alignPriceCount = 0;
+ for (i = 0; i < kAlignTableSize / 2; i++)
+ {
+ UInt32 price = 0;
+ unsigned sym = i;
+ unsigned m = 1;
+ unsigned bit;
+ UInt32 prob;
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
+ prob = probs[m];
+ p->alignPrices[i ] = price + GET_PRICEa_0(prob);
+ p->alignPrices[i + 8] = price + GET_PRICEa_1(prob);
+ // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+ }
+}
+
+
+MY_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p)
+{
+ // int y; for (y = 0; y < 100; y++) {
+
+ UInt32 tempPrices[kNumFullDistances];
+ unsigned i, lps;
+
+ const CProbPrice *ProbPrices = p->ProbPrices;
+ p->matchPriceCount = 0;
+
+ for (i = kStartPosModelIndex / 2; i < kNumFullDistances / 2; i++)
+ {
+ unsigned posSlot = GetPosSlot1(i);
+ unsigned footerBits = (posSlot >> 1) - 1;
+ unsigned base = ((2 | (posSlot & 1)) << footerBits);
+ const CLzmaProb *probs = p->posEncoders + (size_t)base * 2;
+ // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices);
+ UInt32 price = 0;
+ unsigned m = 1;
+ unsigned sym = i;
+ unsigned offset = (unsigned)1 << footerBits;
+ base += i;
+
+ if (footerBits)
+ do
+ {
+ unsigned bit = sym & 1;
+ sym >>= 1;
+ price += GET_PRICEa(probs[m], bit);
+ m = (m << 1) + bit;
+ }
+ while (--footerBits);
+
+ {
+ unsigned prob = probs[m];
+ tempPrices[base ] = price + GET_PRICEa_0(prob);
+ tempPrices[base + offset] = price + GET_PRICEa_1(prob);
+ }
+ }
+
+ for (lps = 0; lps < kNumLenToPosStates; lps++)
+ {
+ unsigned slot;
+ unsigned distTableSize2 = (p->distTableSize + 1) >> 1;
+ UInt32 *posSlotPrices = p->posSlotPrices[lps];
+ const CLzmaProb *probs = p->posSlotEncoder[lps];
+
+ for (slot = 0; slot < distTableSize2; slot++)
+ {
+ // posSlotPrices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices);
+ UInt32 price;
+ unsigned bit;
+ unsigned sym = slot + (1 << (kNumPosSlotBits - 1));
+ unsigned prob;
+ bit = sym & 1; sym >>= 1; price = GET_PRICEa(probs[sym], bit);
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
+ bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
+ prob = probs[(size_t)slot + (1 << (kNumPosSlotBits - 1))];
+ posSlotPrices[(size_t)slot * 2 ] = price + GET_PRICEa_0(prob);
+ posSlotPrices[(size_t)slot * 2 + 1] = price + GET_PRICEa_1(prob);
+ }
+
+ {
+ UInt32 delta = ((UInt32)((kEndPosModelIndex / 2 - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+ for (slot = kEndPosModelIndex / 2; slot < distTableSize2; slot++)
+ {
+ posSlotPrices[(size_t)slot * 2 ] += delta;
+ posSlotPrices[(size_t)slot * 2 + 1] += delta;
+ delta += ((UInt32)1 << kNumBitPriceShiftBits);
+ }
+ }
+
+ {
+ UInt32 *dp = p->distancesPrices[lps];
+
+ dp[0] = posSlotPrices[0];
+ dp[1] = posSlotPrices[1];
+ dp[2] = posSlotPrices[2];
+ dp[3] = posSlotPrices[3];
+
+ for (i = 4; i < kNumFullDistances; i += 2)
+ {
+ UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)];
+ dp[i ] = slotPrice + tempPrices[i];
+ dp[i + 1] = slotPrice + tempPrices[i + 1];
+ }
+ }
+ }
+ // }
+}
+
+
+
+void LzmaEnc_Construct(CLzmaEnc *p)
+{
+ RangeEnc_Construct(&p->rc);
+ MatchFinder_Construct(&p->matchFinderBase);
+
+ #ifndef _7ZIP_ST
+ MatchFinderMt_Construct(&p->matchFinderMt);
+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
+ #endif
+
+ {
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+ LzmaEnc_SetProps(p, &props);
+ }
+
+ #ifndef LZMA_LOG_BSR
+ LzmaEnc_FastPosInit(p->g_FastPos);
+ #endif
+
+ LzmaEnc_InitPriceTables(p->ProbPrices);
+ p->litProbs = NULL;
+ p->saveState.litProbs = NULL;
+
+}
+
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
+{
+ void *p;
+ p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
+ if (p)
+ LzmaEnc_Construct((CLzmaEnc *)p);
+ return p;
+}
+
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
+{
+ ISzAlloc_Free(alloc, p->litProbs);
+ ISzAlloc_Free(alloc, p->saveState.litProbs);
+ p->litProbs = NULL;
+ p->saveState.litProbs = NULL;
+}
+
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ #ifndef _7ZIP_ST
+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
+ #endif
+
+ MatchFinder_Free(&p->matchFinderBase, allocBig);
+ LzmaEnc_FreeLits(p, alloc);
+ RangeEnc_Free(&p->rc, alloc);
+}
+
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
+ ISzAlloc_Free(alloc, p);
+}
+
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize)
+{
+ UInt32 nowPos32, startPos32;
+ if (p->needInit)
+ {
+ p->matchFinder.Init(p->matchFinderObj);
+ p->needInit = 0;
+ }
+
+ if (p->finished)
+ return p->result;
+ RINOK(CheckErrors(p));
+
+ nowPos32 = (UInt32)p->nowPos64;
+ startPos32 = nowPos32;
+
+ if (p->nowPos64 == 0)
+ {
+ unsigned numPairs;
+ Byte curByte;
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ return Flush(p, nowPos32);
+ ReadMatchDistances(p, &numPairs);
+ RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]);
+ // p->state = kLiteralNextStates[p->state];
+ curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
+ p->additionalOffset--;
+ nowPos32++;
+ }
+
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+
+ for (;;)
+ {
+ UInt32 dist;
+ unsigned len, posState;
+ UInt32 range, ttt, newBound;
+ CLzmaProb *probs;
+
+ if (p->fastMode)
+ len = GetOptimumFast(p);
+ else
+ {
+ unsigned oci = p->optCur;
+ if (p->optEnd == oci)
+ len = GetOptimum(p, nowPos32);
+ else
+ {
+ const COptimal *opt = &p->opt[oci];
+ len = opt->len;
+ p->backRes = opt->dist;
+ p->optCur = oci + 1;
+ }
+ }
+
+ posState = (unsigned)nowPos32 & p->pbMask;
+ range = p->rc.range;
+ probs = &p->isMatch[p->state][posState];
+
+ RC_BIT_PRE(&p->rc, probs)
+
+ dist = p->backRes;
+
+ #ifdef SHOW_STAT2
+ printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist);
+ #endif
+
+ if (dist == MARK_LIT)
+ {
+ Byte curByte;
+ const Byte *data;
+ unsigned state;
+
+ RC_BIT_0(&p->rc, probs);
+ p->rc.range = range;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+ probs = LIT_PROBS(nowPos32, *(data - 1));
+ curByte = *data;
+ state = p->state;
+ p->state = kLiteralNextStates[state];
+ if (IsLitState(state))
+ LitEnc_Encode(&p->rc, probs, curByte);
+ else
+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0]));
+ }
+ else
+ {
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRep[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+
+ if (dist < LZMA_NUM_REPS)
+ {
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRepG0[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+ if (dist == 0)
+ {
+ RC_BIT_0(&p->rc, probs);
+ probs = &p->isRep0Long[p->state][posState];
+ RC_BIT_PRE(&p->rc, probs)
+ if (len != 1)
+ {
+ RC_BIT_1_BASE(&p->rc, probs);
+ }
+ else
+ {
+ RC_BIT_0_BASE(&p->rc, probs);
+ p->state = kShortRepNextStates[p->state];
+ }
+ }
+ else
+ {
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRepG1[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+ if (dist == 1)
+ {
+ RC_BIT_0_BASE(&p->rc, probs);
+ dist = p->reps[1];
+ }
+ else
+ {
+ RC_BIT_1(&p->rc, probs);
+ probs = &p->isRepG2[p->state];
+ RC_BIT_PRE(&p->rc, probs)
+ if (dist == 2)
+ {
+ RC_BIT_0_BASE(&p->rc, probs);
+ dist = p->reps[2];
+ }
+ else
+ {
+ RC_BIT_1_BASE(&p->rc, probs);
+ dist = p->reps[3];
+ p->reps[3] = p->reps[2];
+ }
+ p->reps[2] = p->reps[1];
+ }
+ p->reps[1] = p->reps[0];
+ p->reps[0] = dist;
+ }
+
+ RC_NORM(&p->rc)
+
+ p->rc.range = range;
+
+ if (len != 1)
+ {
+ LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
+ --p->repLenEncCounter;
+ p->state = kRepNextStates[p->state];
+ }
+ }
+ else
+ {
+ unsigned posSlot;
+ RC_BIT_0(&p->rc, probs);
+ p->rc.range = range;
+ p->state = kMatchNextStates[p->state];
+
+ LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
+ // --p->lenEnc.counter;
+
+ dist -= LZMA_NUM_REPS;
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ p->reps[1] = p->reps[0];
+ p->reps[0] = dist + 1;
+
+ p->matchPriceCount++;
+ GetPosSlot(dist, posSlot);
+ // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot);
+ {
+ UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits);
+ range = p->rc.range;
+ probs = p->posSlotEncoder[GetLenToPosState(len)];
+ do
+ {
+ CLzmaProb *prob = probs + (sym >> kNumPosSlotBits);
+ UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1;
+ sym <<= 1;
+ RC_BIT(&p->rc, prob, bit);
+ }
+ while (sym < (1 << kNumPosSlotBits * 2));
+ p->rc.range = range;
+ }
+
+ if (dist >= kStartPosModelIndex)
+ {
+ unsigned footerBits = ((posSlot >> 1) - 1);
+
+ if (dist < kNumFullDistances)
+ {
+ unsigned base = ((2 | (posSlot & 1)) << footerBits);
+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, (unsigned)(dist /* - base */));
+ }
+ else
+ {
+ UInt32 pos2 = (dist | 0xF) << (32 - footerBits);
+ range = p->rc.range;
+ // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ /*
+ do
+ {
+ range >>= 1;
+ p->rc.low += range & (0 - ((dist >> --footerBits) & 1));
+ RC_NORM(&p->rc)
+ }
+ while (footerBits > kNumAlignBits);
+ */
+ do
+ {
+ range >>= 1;
+ p->rc.low += range & (0 - (pos2 >> 31));
+ pos2 += pos2;
+ RC_NORM(&p->rc)
+ }
+ while (pos2 != 0xF0000000);
+
+
+ // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+
+ {
+ unsigned m = 1;
+ unsigned bit;
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
+ bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
+ bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit);
+ p->rc.range = range;
+ // p->alignPriceCount++;
+ }
+ }
+ }
+ }
+ }
+
+ nowPos32 += (UInt32)len;
+ p->additionalOffset -= len;
+
+ if (p->additionalOffset == 0)
+ {
+ UInt32 processed;
+
+ if (!p->fastMode)
+ {
+ /*
+ if (p->alignPriceCount >= 16) // kAlignTableSize
+ FillAlignPrices(p);
+ if (p->matchPriceCount >= 128)
+ FillDistancesPrices(p);
+ if (p->lenEnc.counter <= 0)
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
+ */
+ if (p->matchPriceCount >= 64)
+ {
+ FillAlignPrices(p);
+ // { int y; for (y = 0; y < 100; y++) {
+ FillDistancesPrices(p);
+ // }}
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
+ }
+ if (p->repLenEncCounter <= 0)
+ {
+ p->repLenEncCounter = REP_LEN_COUNT;
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices);
+ }
+ }
+
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ break;
+ processed = nowPos32 - startPos32;
+
+ if (maxPackSize)
+ {
+ if (processed + kNumOpts + 300 >= maxUnpackSize
+ || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize)
+ break;
+ }
+ else if (processed >= (1 << 17))
+ {
+ p->nowPos64 += nowPos32 - startPos32;
+ return CheckErrors(p);
+ }
+ }
+ }
+
+ p->nowPos64 += nowPos32 - startPos32;
+ return Flush(p, nowPos32);
+}
+
+
+
+#define kBigHashDicLimit ((UInt32)1 << 24)
+
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ UInt32 beforeSize = kNumOpts;
+ if (!RangeEnc_Alloc(&p->rc, alloc))
+ return SZ_ERROR_MEM;
+
+ #ifndef _7ZIP_ST
+ p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
+ #endif
+
+ {
+ unsigned lclp = p->lc + p->lp;
+ if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ if (!p->litProbs || !p->saveState.litProbs)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ p->lclp = lclp;
+ }
+ }
+
+ p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
+
+ if (beforeSize + p->dictSize < keepWindowSize)
+ beforeSize = keepWindowSize - p->dictSize;
+
+ #ifndef _7ZIP_ST
+ if (p->mtMode)
+ {
+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes,
+ LZMA_MATCH_LEN_MAX
+ + 1 /* 18.04 */
+ , allocBig));
+ p->matchFinderObj = &p->matchFinderMt;
+ p->matchFinderBase.bigHash = (Byte)(
+ (p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
+ }
+ else
+ #endif
+ {
+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
+ return SZ_ERROR_MEM;
+ p->matchFinderObj = &p->matchFinderBase;
+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
+ }
+
+ return SZ_OK;
+}
+
+void LzmaEnc_Init(CLzmaEnc *p)
+{
+ unsigned i;
+ p->state = 0;
+ p->reps[0] =
+ p->reps[1] =
+ p->reps[2] =
+ p->reps[3] = 1;
+
+ RangeEnc_Init(&p->rc);
+
+ for (i = 0; i < (1 << kNumAlignBits); i++)
+ p->posAlignEncoder[i] = kProbInitValue;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ unsigned j;
+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
+ {
+ p->isMatch[i][j] = kProbInitValue;
+ p->isRep0Long[i][j] = kProbInitValue;
+ }
+ p->isRep[i] = kProbInitValue;
+ p->isRepG0[i] = kProbInitValue;
+ p->isRepG1[i] = kProbInitValue;
+ p->isRepG2[i] = kProbInitValue;
+ }
+
+ {
+ for (i = 0; i < kNumLenToPosStates; i++)
+ {
+ CLzmaProb *probs = p->posSlotEncoder[i];
+ unsigned j;
+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
+ probs[j] = kProbInitValue;
+ }
+ }
+ {
+ for (i = 0; i < kNumFullDistances; i++)
+ p->posEncoders[i] = kProbInitValue;
+ }
+
+ {
+ UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
+ UInt32 k;
+ CLzmaProb *probs = p->litProbs;
+ for (k = 0; k < num; k++)
+ probs[k] = kProbInitValue;
+ }
+
+
+ LenEnc_Init(&p->lenProbs);
+ LenEnc_Init(&p->repLenProbs);
+
+ p->optEnd = 0;
+ p->optCur = 0;
+
+ {
+ for (i = 0; i < kNumOpts; i++)
+ p->opt[i].price = kInfinityPrice;
+ }
+
+ p->additionalOffset = 0;
+
+ p->pbMask = (1 << p->pb) - 1;
+ p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
+}
+
+
+void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+ if (!p->fastMode)
+ {
+ FillDistancesPrices(p);
+ FillAlignPrices(p);
+ }
+
+ p->lenEnc.tableSize =
+ p->repLenEnc.tableSize =
+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
+
+ p->repLenEncCounter = REP_LEN_COUNT;
+
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices);
+}
+
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ unsigned i;
+ for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++)
+ if (p->dictSize <= ((UInt32)1 << i))
+ break;
+ p->distTableSize = i * 2;
+
+ p->finished = False;
+ p->result = SZ_OK;
+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ p->nowPos64 = 0;
+ return SZ_OK;
+}
+
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->matchFinderBase.stream = inStream;
+ p->needInit = 1;
+ p->rc.outStream = outStream;
+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+ ISeqInStream *inStream, UInt32 keepWindowSize,
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->matchFinderBase.stream = inStream;
+ p->needInit = 1;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
+{
+ p->matchFinderBase.directInput = 1;
+ p->matchFinderBase.bufferBase = (Byte *)src;
+ p->matchFinderBase.directInputRem = srcLen;
+}
+
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+ UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+ p->needInit = 1;
+
+ LzmaEnc_SetDataSize(pp, srcLen);
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+ #ifndef _7ZIP_ST
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ if (p->mtMode)
+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+ #else
+ UNUSED_VAR(pp);
+ #endif
+}
+
+
+typedef struct
+{
+ ISeqOutStream vt;
+ Byte *data;
+ SizeT rem;
+ BoolInt overflow;
+} CLzmaEnc_SeqOutStreamBuf;
+
+static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size)
+{
+ CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt);
+ if (p->rem < size)
+ {
+ size = p->rem;
+ p->overflow = True;
+ }
+ memcpy(p->data, data, size);
+ p->rem -= size;
+ p->data += size;
+ return size;
+}
+
+
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
+
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
+
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit,
+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ UInt64 nowPos64;
+ SRes res;
+ CLzmaEnc_SeqOutStreamBuf outStream;
+
+ outStream.vt.Write = SeqOutStreamBuf_Write;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = False;
+ p->finished = False;
+ p->result = SZ_OK;
+
+ if (reInit)
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+
+ nowPos64 = p->nowPos64;
+ RangeEnc_Init(&p->rc);
+ p->rc.outStream = &outStream.vt;
+
+ if (desiredPackSize == 0)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);
+
+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ return res;
+}
+
+
+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
+{
+ SRes res = SZ_OK;
+
+ #ifndef _7ZIP_ST
+ Byte allocaDummy[0x300];
+ allocaDummy[0] = 0;
+ allocaDummy[1] = allocaDummy[0];
+ #endif
+
+ for (;;)
+ {
+ res = LzmaEnc_CodeOneBlock(p, 0, 0);
+ if (res != SZ_OK || p->finished)
+ break;
+ if (progress)
+ {
+ res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+ if (res != SZ_OK)
+ {
+ res = SZ_ERROR_PROGRESS;
+ break;
+ }
+ }
+ }
+
+ LzmaEnc_Finish(p);
+
+ /*
+ if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
+ res = SZ_ERROR_FAIL;
+ }
+ */
+
+ return res;
+}
+
+
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
+ ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
+}
+
+
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ unsigned i;
+ UInt32 dictSize = p->dictSize;
+ if (*size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_PARAM;
+ *size = LZMA_PROPS_SIZE;
+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
+
+ if (dictSize >= ((UInt32)1 << 22))
+ {
+ UInt32 kDictMask = ((UInt32)1 << 20) - 1;
+ if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
+ dictSize = (dictSize + kDictMask) & ~kDictMask;
+ }
+ else for (i = 11; i <= 30; i++)
+ {
+ if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; }
+ if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; }
+ }
+
+ for (i = 0; i < 4; i++)
+ props[1 + i] = (Byte)(dictSize >> (8 * i));
+ return SZ_OK;
+}
+
+
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)
+{
+ return ((CLzmaEnc *)pp)->writeEndMark;
+}
+
+
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ SRes res;
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+
+ CLzmaEnc_SeqOutStreamBuf outStream;
+
+ outStream.vt.Write = SeqOutStreamBuf_Write;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = writeEndMark;
+ p->rc.outStream = &outStream.vt;
+
+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
+
+ if (res == SZ_OK)
+ {
+ res = LzmaEnc_Encode2(p, progress);
+ if (res == SZ_OK && p->nowPos64 != srcLen)
+ res = SZ_ERROR_FAIL;
+ }
+
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+ return res;
+}
+
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
+ SRes res;
+ if (!p)
+ return SZ_ERROR_MEM;
+
+ res = LzmaEnc_SetProps(p, props);
+ if (res == SZ_OK)
+ {
+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
+ if (res == SZ_OK)
+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
+ writeEndMark, progress, alloc, allocBig);
+ }
+
+ LzmaEnc_Destroy(p, alloc, allocBig);
+ return res;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h
new file mode 100644
index 00000000..867d60ba
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h
@@ -0,0 +1,76 @@
+/* LzmaEnc.h -- LZMA Encoder
+2017-07-27 : Igor Pavlov : Public domain */
+
+#ifndef __LZMA_ENC_H
+#define __LZMA_ENC_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaEncProps
+{
+ int level; /* 0 <= level <= 9 */
+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
+ (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
+ default = (1 << 24) */
+ int lc; /* 0 <= lc <= 8, default = 3 */
+ int lp; /* 0 <= lp <= 4, default = 0 */
+ int pb; /* 0 <= pb <= 4, default = 2 */
+ int algo; /* 0 - fast, 1 - normal, default = 1 */
+ int fb; /* 5 <= fb <= 273, default = 32 */
+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
+ int numHashBytes; /* 2, 3 or 4, default = 4 */
+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
+ int numThreads; /* 1 or 2, default = 2 */
+
+ UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
+ Encoder uses this value to reduce dictionary size */
+} CLzmaEncProps;
+
+void LzmaEncProps_Init(CLzmaEncProps *p);
+void LzmaEncProps_Normalize(CLzmaEncProps *p);
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
+
+
+/* ---------- CLzmaEncHandle Interface ---------- */
+
+/* LzmaEnc* functions can return the following exit codes:
+SRes:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect parameter in props
+ SZ_ERROR_WRITE - ISeqOutStream write callback error
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
+ SZ_ERROR_PROGRESS - some break from progress callback
+ SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
+*/
+
+typedef void * CLzmaEncHandle;
+
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
+void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
+
+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+
+
+/* ---------- One Call Interface ---------- */
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Precomp.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Precomp.h
new file mode 100644
index 00000000..e8ff8b40
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Precomp.h
@@ -0,0 +1,10 @@
+/* Precomp.h -- StdAfx
+2013-11-12 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_PRECOMP_H
+#define __7Z_PRECOMP_H
+
+#include "Compiler.h"
+/* #include "7zTypes.h" */
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c
new file mode 100644
index 00000000..c0668664
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c
@@ -0,0 +1,95 @@
+/* Threads.c -- multithreading library
+2017-06-26 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+#ifndef UNDER_CE
+#include <process.h>
+#endif
+
+#include "Threads.h"
+
+static WRes GetError()
+{
+ DWORD res = GetLastError();
+ return res ? (WRes)res : 1;
+}
+
+static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
+static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
+
+WRes HandlePtr_Close(HANDLE *p)
+{
+ if (*p != NULL)
+ {
+ if (!CloseHandle(*p))
+ return GetError();
+ *p = NULL;
+ }
+ return 0;
+}
+
+WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); }
+
+WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
+{
+ /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+
+ #ifdef UNDER_CE
+
+ DWORD threadId;
+ *p = CreateThread(0, 0, func, param, 0, &threadId);
+
+ #else
+
+ unsigned threadId;
+ *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
+
+ #endif
+
+ /* maybe we must use errno here, but probably GetLastError() is also OK. */
+ return HandleToWRes(*p);
+}
+
+static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
+{
+ *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
+ return HandleToWRes(*p);
+}
+
+WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }
+WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }
+
+WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }
+
+
+WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
+{
+ *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
+ return HandleToWRes(*p);
+}
+
+static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
+ { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)
+ { return Semaphore_Release(p, (LONG)num, NULL); }
+WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }
+
+WRes CriticalSection_Init(CCriticalSection *p)
+{
+ /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
+ #ifdef _MSC_VER
+ __try
+ #endif
+ {
+ InitializeCriticalSection(p);
+ /* InitializeCriticalSectionAndSpinCount(p, 0); */
+ }
+ #ifdef _MSC_VER
+ __except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
+ #endif
+ return 0;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h
new file mode 100644
index 00000000..488e65d3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h
@@ -0,0 +1,72 @@
+/* Threads.h -- multithreading library
+2017-06-18 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_THREADS_H
+#define __7Z_THREADS_H
+
+#ifdef _WIN32
+# ifdef VBOX
+# include <iprt/win/windows.h>
+# else
+#include <windows.h>
+# endif
+#endif
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+WRes HandlePtr_Close(HANDLE *h);
+WRes Handle_WaitObject(HANDLE h);
+
+typedef HANDLE CThread;
+#define Thread_Construct(p) *(p) = NULL
+#define Thread_WasCreated(p) (*(p) != NULL)
+#define Thread_Close(p) HandlePtr_Close(p)
+#define Thread_Wait(p) Handle_WaitObject(*(p))
+
+typedef
+#ifdef UNDER_CE
+ DWORD
+#else
+ unsigned
+#endif
+ THREAD_FUNC_RET_TYPE;
+
+#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
+#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
+typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
+WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
+
+typedef HANDLE CEvent;
+typedef CEvent CAutoResetEvent;
+typedef CEvent CManualResetEvent;
+#define Event_Construct(p) *(p) = NULL
+#define Event_IsCreated(p) (*(p) != NULL)
+#define Event_Close(p) HandlePtr_Close(p)
+#define Event_Wait(p) Handle_WaitObject(*(p))
+WRes Event_Set(CEvent *p);
+WRes Event_Reset(CEvent *p);
+WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
+
+typedef HANDLE CSemaphore;
+#define Semaphore_Construct(p) *(p) = NULL
+#define Semaphore_IsCreated(p) (*(p) != NULL)
+#define Semaphore_Close(p) HandlePtr_Close(p)
+#define Semaphore_Wait(p) Handle_WaitObject(*(p))
+WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
+WRes Semaphore_Release1(CSemaphore *p);
+
+typedef CRITICAL_SECTION CCriticalSection;
+WRes CriticalSection_Init(CCriticalSection *p);
+#define CriticalSection_Delete(p) DeleteCriticalSection(p)
+#define CriticalSection_Enter(p) EnterCriticalSection(p)
+#define CriticalSection_Leave(p) LeaveCriticalSection(p)
+
+EXTERN_C_END
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt
new file mode 100644
index 00000000..e82fd33c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt
@@ -0,0 +1,446 @@
+HISTORY of the LZMA SDK
+-----------------------
+
+19.00 2019-02-21
+-------------------------
+- Encryption strength for 7z archives was increased:
+ the size of random initialization vector was increased from 64-bit to 128-bit,
+ and the pseudo-random number generator was improved.
+- The bug in 7zIn.c code was fixed.
+
+
+18.06 2018-12-30
+-------------------------
+- The speed for LZMA/LZMA2 compressing was increased by 3-10%,
+ and there are minor changes in compression ratio.
+- Some bugs were fixed.
+- The bug in 7-Zip 18.02-18.05 was fixed:
+ There was memory leak in multithreading xz decoder - XzDecMt_Decode(),
+ if xz stream contains only one block.
+- The changes for MSVS compiler makefiles:
+ - the makefiles now use "PLATFORM" macroname with values (x64, x86, arm64)
+ instead of "CPU" macroname with values (AMD64, ARM64).
+ - the makefiles by default now use static version of the run-time library.
+
+
+18.05 2018-04-30
+-------------------------
+- The speed for LZMA/LZMA2 compressing was increased
+ by 8% for fastest/fast compression levels and
+ by 3% for normal/maximum compression levels.
+- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in
+ Windows 10 because of some BUG with "Large Pages" in Windows 10.
+ Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299).
+- The BUG was fixed in Lzma2Enc.c
+ Lzma2Enc_Encode2() function worked incorretly,
+ if (inStream == NULL) and the number of block threads is more than 1.
+
+
+18.03 beta 2018-03-04
+-------------------------
+- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm
+ for x64 with about 30% higher speed than main version of LZMA decoder written in C.
+- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%.
+- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
+ if there are multiple independent data chunks in LZMA2 stream.
+- 7-Zip now can use multi-threading for xz decoding,
+ if there are multiple blocks in xz stream.
+
+
+18.01 2019-01-28
+-------------------------
+- The BUG in 17.01 - 18.00 beta was fixed:
+ XzDec.c : random block unpacking and XzUnpacker_IsBlockFinished()
+ didn't work correctly for xz archives without checksum (CRC).
+
+
+18.00 beta 2019-01-10
+-------------------------
+- The BUG in xz encoder was fixed:
+ There was memory leak of 16 KB for each file compressed with
+ xz compression method, if additional filter was used.
+
+
+17.01 beta 2017-08-28
+-------------------------
+- Minor speed optimization for LZMA2 (xz and 7z) multi-threading compression.
+ 7-Zip now uses additional memory buffers for multi-block LZMA2 compression.
+ CPU utilization was slightly improved.
+- 7-zip now creates multi-block xz archives by default. Block size can be
+ specified with -ms[Size]{m|g} switch.
+- xz decoder now can unpack random block from multi-block xz archives.
+- 7-Zip command line: @listfile now doesn't work after -- switch.
+ Use -i@listfile before -- switch instead.
+- The BUGs were fixed:
+ 7-Zip 17.00 beta crashed for commands that write anti-item to 7z archive.
+
+
+17.00 beta 2017-04-29
+-------------------------
+- NewHandler.h / NewHandler.cpp:
+ now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900).
+- C/7zTypes.h : the names of variables in interface structures were changed (vt).
+- Some bugs were fixed. 7-Zip could crash in some cases.
+- Some internal changes in code.
+
+
+16.04 2016-10-04
+-------------------------
+- The bug was fixed in DllSecur.c.
+
+
+16.03 2016-09-28
+-------------------------
+- SFX modules now use some protection against DLL preloading attack.
+- Some bugs in 7z code were fixed.
+
+
+16.02 2016-05-21
+-------------------------
+- The BUG in 16.00 - 16.01 was fixed:
+ Split Handler (SplitHandler.cpp) returned incorrect
+ total size value (kpidSize) for split archives.
+
+
+16.01 2016-05-19
+-------------------------
+- Some internal changes to reduce the number of compiler warnings.
+
+
+16.00 2016-05-10
+-------------------------
+- Some bugs were fixed.
+
+
+15.12 2015-11-19
+-------------------------
+- The BUG in C version of 7z decoder was fixed:
+ 7zDec.c : SzDecodeLzma2()
+ 7z decoder could mistakenly report about decoding error for some 7z archives
+ that use LZMA2 compression method.
+ The probability to get that mistaken decoding error report was about
+ one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size).
+- The BUG (in 9.26-15.11) in C version of 7z decoder was fixed:
+ 7zArcIn.c : SzReadHeader2()
+ 7z decoder worked incorrectly for 7z archives that contain
+ empty solid blocks, that can be placed to 7z archive, if some file is
+ unavailable for reading during archive creation.
+
+
+15.09 beta 2015-10-16
+-------------------------
+- The BUG in LZMA / LZMA2 encoding code was fixed.
+ The BUG in LzFind.c::MatchFinder_ReadBlock() function.
+ If input data size is larger than (4 GiB - dictionary_size),
+ the following code worked incorrectly:
+ - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions
+ for compressing from memory to memory.
+ That BUG is not related to LZMA encoder version that works via streams.
+ - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if
+ default value of chunk size (CLzma2EncProps::blockSize) is changed
+ to value larger than (4 GiB - dictionary_size).
+
+
+9.38 beta 2015-01-03
+-------------------------
+- The BUG in 9.31-9.37 was fixed:
+ IArchiveGetRawProps interface was disabled for 7z archives.
+- The BUG in 9.26-9.36 was fixed:
+ Some code in CPP\7zip\Archive\7z\ worked correctly only under Windows.
+
+
+9.36 beta 2014-12-26
+-------------------------
+- The BUG in command line version was fixed:
+ 7-Zip created temporary archive in current folder during update archive
+ operation, if -w{Path} switch was not specified.
+ The fixed 7-Zip creates temporary archive in folder that contains updated archive.
+- The BUG in 9.33-9.35 was fixed:
+ 7-Zip silently ignored file reading errors during 7z or gz archive creation,
+ and the created archive contained only part of file that was read before error.
+ The fixed 7-Zip stops archive creation and it reports about error.
+
+
+9.35 beta 2014-12-07
+-------------------------
+- 7zr.exe now support AES encryption.
+- SFX modules were added to LZMA SDK
+- Some bugs were fixed.
+
+
+9.21 beta 2011-04-11
+-------------------------
+- New class FString for file names at file systems.
+- Speed optimization in CRC code for big-endian CPUs.
+- The BUG in Lzma2Dec.c was fixed:
+ Lzma2Decode function didn't work.
+
+
+9.18 beta 2010-11-02
+-------------------------
+- New small SFX module for installers (SfxSetup).
+
+
+9.12 beta 2010-03-24
+-------------------------
+- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
+ if more than 10 threads were used (or more than 20 threads in some modes).
+
+
+9.11 beta 2010-03-15
+-------------------------
+- PPMd compression method support
+
+
+9.09 2009-12-12
+-------------------------
+- The bug was fixed:
+ Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
+ incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
+- Some bugs were fixed
+
+
+9.06 2009-08-17
+-------------------------
+- Some changes in ANSI-C 7z Decoder interfaces.
+
+
+9.04 2009-05-30
+-------------------------
+- LZMA2 compression method support
+- xz format support
+
+
+4.65 2009-02-03
+-------------------------
+- Some minor fixes
+
+
+4.63 2008-12-31
+-------------------------
+- Some minor fixes
+
+
+4.61 beta 2008-11-23
+-------------------------
+- The bug in ANSI-C LZMA Decoder was fixed:
+ If encoded stream was corrupted, decoder could access memory
+ outside of allocated range.
+- Some changes in ANSI-C 7z Decoder interfaces.
+- LZMA SDK is placed in the public domain.
+
+
+4.60 beta 2008-08-19
+-------------------------
+- Some minor fixes.
+
+
+4.59 beta 2008-08-13
+-------------------------
+- The bug was fixed:
+ LZMA Encoder in fast compression mode could access memory outside of
+ allocated range in some rare cases.
+
+
+4.58 beta 2008-05-05
+-------------------------
+- ANSI-C LZMA Decoder was rewritten for speed optimizations.
+- ANSI-C LZMA Encoder was included to LZMA SDK.
+- C++ LZMA code now is just wrapper over ANSI-C code.
+
+
+4.57 2007-12-12
+-------------------------
+- Speed optimizations in ?++ LZMA Decoder.
+- Small changes for more compatibility with some C/C++ compilers.
+
+
+4.49 beta 2007-07-05
+-------------------------
+- .7z ANSI-C Decoder:
+ - now it supports BCJ and BCJ2 filters
+ - now it supports files larger than 4 GB.
+ - now it supports "Last Write Time" field for files.
+- C++ code for .7z archives compressing/decompressing from 7-zip
+ was included to LZMA SDK.
+
+
+4.43 2006-06-04
+-------------------------
+- Small changes for more compatibility with some C/C++ compilers.
+
+
+4.42 2006-05-15
+-------------------------
+- Small changes in .h files in ANSI-C version.
+
+
+4.39 beta 2006-04-14
+-------------------------
+- The bug in versions 4.33b:4.38b was fixed:
+ C++ version of LZMA encoder could not correctly compress
+ files larger than 2 GB with HC4 match finder (-mfhc4).
+
+
+4.37 beta 2005-04-06
+-------------------------
+- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
+
+
+4.35 beta 2005-03-02
+-------------------------
+- The bug was fixed in C++ version of LZMA Decoder:
+ If encoded stream was corrupted, decoder could access memory
+ outside of allocated range.
+
+
+4.34 beta 2006-02-27
+-------------------------
+- Compressing speed and memory requirements for compressing were increased
+- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
+
+
+4.32 2005-12-09
+-------------------------
+- Java version of LZMA SDK was included
+
+
+4.30 2005-11-20
+-------------------------
+- Compression ratio was improved in -a2 mode
+- Speed optimizations for compressing in -a2 mode
+- -fb switch now supports values up to 273
+- The bug in 7z_C (7zIn.c) was fixed:
+ It used Alloc/Free functions from different memory pools.
+ So if program used two memory pools, it worked incorrectly.
+- 7z_C: .7z format supporting was improved
+- LZMA# SDK (C#.NET version) was included
+
+
+4.27 (Updated) 2005-09-21
+-------------------------
+- Some GUIDs/interfaces in C++ were changed.
+ IStream.h:
+ ISequentialInStream::Read now works as old ReadPart
+ ISequentialOutStream::Write now works as old WritePart
+
+
+4.27 2005-08-07
+-------------------------
+- The bug in LzmaDecodeSize.c was fixed:
+ if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
+ decompressing worked incorrectly.
+
+
+4.26 2005-08-05
+-------------------------
+- Fixes in 7z_C code and LzmaTest.c:
+ previous versions could work incorrectly,
+ if malloc(0) returns 0
+
+
+4.23 2005-06-29
+-------------------------
+- Small fixes in C++ code
+
+
+4.22 2005-06-10
+-------------------------
+- Small fixes
+
+
+4.21 2005-06-08
+-------------------------
+- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
+- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
+ - LzmaStateDecode.h
+ - LzmaStateDecode.c
+ - LzmaStateTest.c
+- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
+
+
+4.17 2005-04-18
+-------------------------
+- New example for RAM->RAM compressing/decompressing:
+ LZMA + BCJ (filter for x86 code):
+ - LzmaRam.h
+ - LzmaRam.cpp
+ - LzmaRamDecode.h
+ - LzmaRamDecode.c
+ - -f86 switch for lzma.exe
+
+
+4.16 2005-03-29
+-------------------------
+- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
+ If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
+ decoder could access memory outside of allocated range.
+- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
+ Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
+ LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
+- Small speed optimization in LZMA C++ code
+- filter for SPARC's code was added
+- Simplified version of .7z ANSI-C Decoder was included
+
+
+4.06 2004-09-05
+-------------------------
+- The bug in v4.05 was fixed:
+ LZMA-Encoder didn't release output stream in some cases.
+
+
+4.05 2004-08-25
+-------------------------
+- Source code of filters for x86, IA-64, ARM, ARM-Thumb
+ and PowerPC code was included to SDK
+- Some internal minor changes
+
+
+4.04 2004-07-28
+-------------------------
+- More compatibility with some C++ compilers
+
+
+4.03 2004-06-18
+-------------------------
+- "Benchmark" command was added. It measures compressing
+ and decompressing speed and shows rating values.
+ Also it checks hardware errors.
+
+
+4.02 2004-06-10
+-------------------------
+- C++ LZMA Encoder/Decoder code now is more portable
+ and it can be compiled by GCC on Linux.
+
+
+4.01 2004-02-15
+-------------------------
+- Some detection of data corruption was enabled.
+ LzmaDecode.c / RangeDecoderReadByte
+ .....
+ {
+ rd->ExtraBytes = 1;
+ return 0xFF;
+ }
+
+
+4.00 2004-02-13
+-------------------------
+- Original version of LZMA SDK
+
+
+
+HISTORY of the LZMA
+-------------------
+ 2001-2008: Improvements to LZMA compressing/decompressing code,
+ keeping compatibility with original LZMA format
+ 1996-2001: Development of LZMA compression format
+
+ Some milestones:
+
+ 2001-08-30: LZMA compression was added to 7-Zip
+ 1999-01-02: First version of 7-Zip was released
+
+
+End of document
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt
new file mode 100644
index 00000000..abe578ff
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt
@@ -0,0 +1,357 @@
+LZMA SDK 19.00
+--------------
+
+LZMA SDK provides the documentation, samples, header files,
+libraries, and tools you need to develop applications that
+use 7z / LZMA / LZMA2 / XZ compression.
+
+LZMA is an improved version of famous LZ77 compression algorithm.
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for
+decompressing.
+
+LZMA2 is a LZMA based compression method. LZMA2 provides better
+multithreading support for compression than LZMA and some other improvements.
+
+7z is a file format for data compression and file archiving.
+7z is a main file format for 7-Zip compression program (www.7-zip.org).
+7z format supports different compression methods: LZMA, LZMA2 and others.
+7z also supports AES-256 based encryption.
+
+XZ is a file format for data compression that uses LZMA2 compression.
+XZ format provides additional features: SHA/CRC check, filters for
+improved compression ratio, splitting to blocks and streams,
+
+
+
+LICENSE
+-------
+
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+Some code in LZMA SDK is based on public domain code from another developers:
+ 1) PPMd var.H (2001): Dmitry Shkarin
+ 2) SHA-256: Wei Dai (Crypto++ library)
+
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
+original LZMA SDK code, either in source code form or as a compiled binary, for
+any purpose, commercial or non-commercial, and by any means.
+
+LZMA SDK code is compatible with open source licenses, for example, you can
+include it to GNU GPL or GNU LGPL code.
+
+
+LZMA SDK Contents
+-----------------
+
+ Source code:
+
+ - C / C++ / C# / Java - LZMA compression and decompression
+ - C / C++ - LZMA2 compression and decompression
+ - C / C++ - XZ compression and decompression
+ - C - 7z decompression
+ - C++ - 7z compression and decompression
+ - C - small SFXs for installers (7z decompression)
+ - C++ - SFXs and SFXs for installers (7z decompression)
+
+ Precompiled binaries:
+
+ - console programs for lzma / 7z / xz compression and decompression
+ - SFX modules for installers.
+
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA encoding, go to directory
+CPP/7zip/Bundles/LzmaCon
+and call make to recompile it:
+ make -f makefile.gcc clean all
+
+In some UNIX/Linux versions you must compile LZMA with static libraries.
+To compile with static libraries, you can use
+LIB = -lm -static
+
+Also you can use p7zip (port of 7-Zip for POSIX systems like Unix or Linux):
+
+ http://p7zip.sourceforge.net/
+
+
+Files
+-----
+
+DOC/7zC.txt - 7z ANSI-C Decoder description
+DOC/7zFormat.txt - 7z Format description
+DOC/installer.txt - information about 7-Zip for installers
+DOC/lzma.txt - LZMA compression description
+DOC/lzma-sdk.txt - LZMA SDK description (this file)
+DOC/lzma-history.txt - history of LZMA SDK
+DOC/lzma-specification.txt - Specification of LZMA
+DOC/Methods.txt - Compression method IDs for .7z
+
+bin/installer/ - example script to create installer that uses SFX module,
+
+bin/7zdec.exe - simplified 7z archive decoder
+bin/7zr.exe - 7-Zip console program (reduced version)
+bin/x64/7zr.exe - 7-Zip console program (reduced version) (x64 version)
+bin/lzma.exe - file->file LZMA encoder/decoder for Windows
+bin/7zS2.sfx - small SFX module for installers (GUI version)
+bin/7zS2con.sfx - small SFX module for installers (Console version)
+bin/7zSD.sfx - SFX module for installers.
+
+
+7zDec.exe
+---------
+7zDec.exe is simplified 7z archive decoder.
+It supports only LZMA, LZMA2, and PPMd methods.
+7zDec decodes whole solid block from 7z archive to RAM.
+The RAM consumption can be high.
+
+
+
+
+Source code structure
+---------------------
+
+
+Asm/ - asm files (optimized code for CRC calculation and Intel-AES encryption)
+
+C/ - C files (compression / decompression and other)
+ Util/
+ 7z - 7z decoder program (decoding 7z files)
+ Lzma - LZMA program (file->file LZMA encoder/decoder).
+ LzmaLib - LZMA library (.DLL for Windows)
+ SfxSetup - small SFX module for installers
+
+CPP/ -- CPP files
+
+ Common - common files for C++ projects
+ Windows - common files for Windows related code
+
+ 7zip - files related to 7-Zip
+
+ Archive - files related to archiving
+
+ Common - common files for archive handling
+ 7z - 7z C++ Encoder/Decoder
+
+ Bundles - Modules that are bundles of other modules (files)
+
+ Alone7z - 7zr.exe: Standalone 7-Zip console program (reduced version)
+ Format7zExtractR - 7zxr.dll: Reduced version of 7z DLL: extracting from 7z/LZMA/BCJ/BCJ2.
+ Format7zR - 7zr.dll: Reduced version of 7z DLL: extracting/compressing to 7z/LZMA/BCJ/BCJ2
+ LzmaCon - lzma.exe: LZMA compression/decompression
+ LzmaSpec - example code for LZMA Specification
+ SFXCon - 7zCon.sfx: Console 7z SFX module
+ SFXSetup - 7zS.sfx: 7z SFX module for installers
+ SFXWin - 7z.sfx: GUI 7z SFX module
+
+ Common - common files for 7-Zip
+
+ Compress - files for compression/decompression
+
+ Crypto - files for encryption / decompression
+
+ UI - User Interface files
+
+ Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
+ Common - Common UI files
+ Console - Code for console program (7z.exe)
+ Explorer - Some code from 7-Zip Shell extension
+ FileManager - Some GUI code from 7-Zip File Manager
+ GUI - Some GUI code from 7-Zip
+
+
+CS/ - C# files
+ 7zip
+ Common - some common files for 7-Zip
+ Compress - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ LzmaAlone - file->file LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+Java/ - Java files
+ SevenZip
+ Compression - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+
+Note:
+ Asm / C / C++ source code of LZMA SDK is part of 7-Zip's source code.
+ 7-Zip's source code can be downloaded from 7-Zip's SourceForge page:
+
+ http://sourceforge.net/projects/sevenzip/
+
+
+
+LZMA features
+-------------
+ - Variable dictionary size (up to 1 GB)
+ - Estimated compressing speed: about 2 MB/s on 2 GHz CPU
+ - Estimated decompressing speed:
+ - 20-30 MB/s on modern 2 GHz cpu
+ - 1-2 MB/s on 200 MHz simple RISC cpu: (ARM, MIPS, PowerPC)
+ - Small memory requirements for decompressing (16 KB + DictionarySize)
+ - Small code size for decompressing: 5-8 KB
+
+LZMA decoder uses only integer operations and can be
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
+
+Some critical operations that affect the speed of LZMA decompression:
+ 1) 32*16 bit integer multiply
+ 2) Mispredicted branches (penalty mostly depends from pipeline length)
+ 3) 32-bit shift and arithmetic operations
+
+The speed of LZMA decompressing mostly depends from CPU speed.
+Memory speed has no big meaning. But if your CPU has small data cache,
+overall weight of memory speed will slightly increase.
+
+
+How To Use
+----------
+
+Using LZMA encoder/decoder executable
+--------------------------------------
+
+Usage: LZMA <e|d> inputFile outputFile [<switches>...]
+
+ e: encode file
+
+ d: decode file
+
+ b: Benchmark. There are two tests: compressing and decompressing
+ with LZMA method. Benchmark shows rating in MIPS (million
+ instructions per second). Rating value is calculated from
+ measured speed and it is normalized with Intel's Core 2 results.
+ Also Benchmark checks possible hardware errors (RAM
+ errors in most cases). Benchmark uses these settings:
+ (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
+ Also you can change the number of iterations. Example for 30 iterations:
+ LZMA b 30
+ Default number of iterations is 10.
+
+<Switches>
+
+
+ -a{N}: set compression mode 0 = fast, 1 = normal
+ default: 1 (normal)
+
+ d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
+ The maximum value for dictionary size is 1 GB = 2^30 bytes.
+ Dictionary size is calculated as DictionarySize = 2^N bytes.
+ For decompressing file compressed by LZMA method with dictionary
+ size D = 2^N you need about D bytes of memory (RAM).
+
+ -fb{N}: set number of fast bytes - [5, 273], default: 128
+ Usually big number gives a little bit better compression ratio
+ and slower compression process.
+
+ -lc{N}: set number of literal context bits - [0, 8], default: 3
+ Sometimes lc=4 gives gain for big files.
+
+ -lp{N}: set number of literal pos bits - [0, 4], default: 0
+ lp switch is intended for periodical data when period is
+ equal 2^N. For example, for 32-bit (4 bytes)
+ periodical data you can use lp=2. Often it's better to set lc0,
+ if you change lp switch.
+
+ -pb{N}: set number of pos bits - [0, 4], default: 2
+ pb switch is intended for periodical data
+ when period is equal 2^N.
+
+ -mf{MF_ID}: set Match Finder. Default: bt4.
+ Algorithms from hc* group doesn't provide good compression
+ ratio, but they often works pretty fast in combination with
+ fast mode (-a0).
+
+ Memory requirements depend from dictionary size
+ (parameter "d" in table below).
+
+ MF_ID Memory Description
+
+ bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
+ bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
+ bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
+ hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
+
+ -eos: write End Of Stream marker. By default LZMA doesn't write
+ eos marker, since LZMA decoder knows uncompressed size
+ stored in .lzma file header.
+
+ -si: Read data from stdin (it will write End Of Stream marker).
+ -so: Write data to stdout
+
+
+Examples:
+
+1) LZMA e file.bin file.lzma -d16 -lc0
+
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
+and 0 literal context bits. -lc0 allows to reduce memory requirements
+for decompression.
+
+
+2) LZMA e file.bin file.lzma -lc0 -lp2
+
+compresses file.bin to file.lzma with settings suitable
+for 32-bit periodical data (for example, ARM or MIPS code).
+
+3) LZMA d file.lzma file.bin
+
+decompresses file.lzma to file.bin.
+
+
+Compression ratio hints
+-----------------------
+
+Recommendations
+---------------
+
+To increase the compression ratio for LZMA compressing it's desirable
+to have aligned data (if it's possible) and also it's desirable to locate
+data in such order, where code is grouped in one place and data is
+grouped in other place (it's better than such mixing: code, data, code,
+data, ...).
+
+
+Filters
+-------
+You can increase the compression ratio for some data types, using
+special filters before compressing. For example, it's possible to
+increase the compression ratio on 5-10% for code for those CPU ISAs:
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
+
+You can find C source code of such filters in C/Bra*.* files
+
+You can check the compression ratio gain of these filters with such
+7-Zip commands (example for ARM code):
+No filter:
+ 7z a a1.7z a.bin -m0=lzma
+
+With filter for little-endian ARM code:
+ 7z a a2.7z a.bin -m0=arm -m1=lzma
+
+It works in such manner:
+Compressing = Filter_encoding + LZMA_encoding
+Decompressing = LZMA_decoding + Filter_decoding
+
+Compressing and decompressing speed of such filters is very high,
+so it will not increase decompressing time too much.
+Moreover, it reduces decompression time for LZMA_decoding,
+since compression ratio with filtering is higher.
+
+These filters convert CALL (calling procedure) instructions
+from relative offsets to absolute addresses, so such data becomes more
+compressible.
+
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
+
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/sdk.html
+http://www.7-zip.org/support.html
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile
new file mode 100644
index 00000000..25875fe7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile
@@ -0,0 +1,69 @@
+## @file
+# Windows makefile for C tools build.
+#
+# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+HOST_ARCH = IA32
+
+!INCLUDE Makefiles\ms.common
+
+LIBRARIES = Common
+APPLICATIONS = \
+ VfrCompile \
+ BrotliCompress \
+ EfiRom \
+ GenCrc32 \
+ GenFfs \
+ GenFv \
+ GenFw \
+ GenSec \
+ LzmaCompress \
+ TianoCompress \
+ VolInfo \
+ DevicePath
+
+all: libs apps install
+
+libs: $(LIBRARIES)
+ @echo.
+ @echo ######################
+ @echo # Build libraries
+ @echo ######################
+ @if not exist $(LIB_PATH) mkdir $(LIB_PATH)
+ @if defined PYTHON_COMMAND $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py all $**
+ @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe Makefiles\NmakeSubdirs.py all $**
+
+apps: $(APPLICATIONS)
+ @echo.
+ @echo ######################
+ @echo # Build executables
+ @echo ######################
+ @if not exist $(BIN_PATH) mkdir $(BIN_PATH)
+ @if defined PYTHON_COMMAND $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py all $**
+ @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe Makefiles\NmakeSubdirs.py all $**
+
+install: $(LIB_PATH) $(BIN_PATH)
+ @echo.
+ @echo ######################
+ @echo # Install to $(SYS_LIB_PATH)
+ @echo # Install to $(SYS_BIN_PATH)
+ @echo ######################
+ @-xcopy $(LIB_PATH)\*.lib $(SYS_LIB_PATH) /I /D /E /F /Y > NUL 2>&1
+ @-xcopy $(BIN_PATH)\*.exe $(SYS_BIN_PATH) /I /D /E /F /Y > NUL 2>&1
+ @-xcopy $(BIN_PATH)\*.bat $(SYS_BIN_PATH) /I /D /E /F /Y > NUL 2>&1
+
+.PHONY: clean
+clean:
+ @if defined PYTHON_COMMAND $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py clean $(LIBRARIES) $(APPLICATIONS)
+ @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe Makefiles\NmakeSubdirs.py clean $(LIBRARIES) $(APPLICATIONS)
+
+.PHONY: cleanall
+cleanall:
+ @if defined PYTHON_COMMAND $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py cleanall $(LIBRARIES) $(APPLICATIONS)
+ @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe Makefiles\NmakeSubdirs.py cleanall $(LIBRARIES) $(APPLICATIONS)
+# Next line protects the libs pseudo target from inadvertent GNU make activity
+ if exist libs RMDIR /S /Q libs
+
+!INCLUDE Makefiles\ms.rule
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile.kmk
new file mode 100644
index 00000000..23a6b8dc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefile.kmk
@@ -0,0 +1,54 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for EFI C build programs.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+include $(PATH_SUB_CURRENT)/Common/Makefile.kmk
+
+include $(PATH_SUB_CURRENT)/GenFv/Makefile.kmk
+include $(PATH_SUB_CURRENT)/LzmaCompress/Makefile.kmk
+include $(PATH_SUB_CURRENT)/GenFw/Makefile.kmk
+include $(PATH_SUB_CURRENT)/TianoCompress/Makefile.kmk
+include $(PATH_SUB_CURRENT)/EfiRom/Makefile.kmk
+include $(PATH_SUB_CURRENT)/GenSec/Makefile.kmk
+include $(PATH_SUB_CURRENT)/GenFfs/Makefile.kmk
+include $(PATH_SUB_CURRENT)/GenCrc32/Makefile.kmk
+include $(PATH_SUB_CURRENT)/VolInfo/Makefile.kmk
+include $(PATH_SUB_CURRENT)/VfrCompile/Makefile.kmk
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat
new file mode 100644
index 00000000..2ea3cf8a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.bat
@@ -0,0 +1,40 @@
+@REM ## @file
+@REM # Makefile
+@REM #
+@REM # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+@REM # SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM #
+
+@echo off
+setlocal
+set TOOL_ERROR=0
+SET NMAKE_COMMAND=%1
+SHIFT
+
+:loop
+if "%1"=="" goto success
+
+ECHO Building %1
+pushd %1
+nmake %NMAKE_COMMAND%
+if ERRORLEVEL 1 (
+ set /A TOOL_ERROR= %TOOL_ERROR% + %ERRORLEVEL%
+ goto error
+)
+ECHO %1 built successfully (%NMAKE_COMMAND%)
+ECHO.
+shift
+popd
+goto loop
+
+:success
+goto exit
+
+:error
+popd
+set /A TOOL_ERROR=%TOOL_ERROR%+%ERRORLEVEL%
+ECHO Error while making %1!
+VERIFY OTHER 2>NUL
+
+:exit
+exit /B %TOOL_ERROR%
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.py
new file mode 100755
index 00000000..155eb223
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/NmakeSubdirs.py
@@ -0,0 +1,166 @@
+# @file NmakeSubdirs.py
+# This script support parallel build for nmake in windows environment.
+# It supports Python2.x and Python3.x both.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+#
+# Import Modules
+#
+
+from __future__ import print_function
+import argparse
+import threading
+import time
+import os
+import subprocess
+import multiprocessing
+import copy
+import sys
+__prog__ = 'NmakeSubdirs'
+__version__ = '%s Version %s' % (__prog__, '0.10 ')
+__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights reserved.'
+__description__ = 'Replace for NmakeSubdirs.bat in windows ,support parallel build for nmake.\n'
+
+cpu_count = multiprocessing.cpu_count()
+output_lock = threading.Lock()
+def RunCommand(WorkDir=None, *Args, **kwargs):
+ if WorkDir is None:
+ WorkDir = os.curdir
+ if "stderr" not in kwargs:
+ kwargs["stderr"] = subprocess.STDOUT
+ if "stdout" not in kwargs:
+ kwargs["stdout"] = subprocess.PIPE
+ p = subprocess.Popen(Args, cwd=WorkDir, stderr=kwargs["stderr"], stdout=kwargs["stdout"])
+ stdout, stderr = p.communicate()
+ message = ""
+ if stdout is not None:
+ message = stdout.decode(errors='ignore') #for compatibility in python 2 and 3
+
+ if p.returncode != 0:
+ raise RuntimeError("Error while execute command \'{0}\' in direcotry {1}\n{2}".format(" ".join(Args), WorkDir, message))
+
+ output_lock.acquire(True)
+ print("execute command \"{0}\" in directory {1}".format(" ".join(Args), WorkDir))
+ try:
+ print(message)
+ except:
+ pass
+ output_lock.release()
+
+ return p.returncode, stdout
+
+class TaskUnit(object):
+ def __init__(self, func, args, kwargs):
+ self.func = func
+ self.args = args
+ self.kwargs = kwargs
+
+ def __eq__(self, other):
+ return id(self).__eq__(id(other))
+
+ def run(self):
+ return self.func(*self.args, **self.kwargs)
+
+ def __str__(self):
+ para = list(self.args)
+ para.extend("{0}={1}".format(k, v)for k, v in self.kwargs.items())
+
+ return "{0}({1})".format(self.func.__name__, ",".join(para))
+
+class ThreadControl(object):
+
+ def __init__(self, maxthread):
+ self._processNum = maxthread
+ self.pending = []
+ self.running = []
+ self.pendingLock = threading.Lock()
+ self.runningLock = threading.Lock()
+ self.error = False
+ self.errorLock = threading.Lock()
+ self.errorMsg = "errorMsg"
+
+ def addTask(self, func, *args, **kwargs):
+ self.pending.append(TaskUnit(func, args, kwargs))
+
+ def waitComplete(self):
+ self._schedule.join()
+
+ def startSchedule(self):
+ self._schedule = threading.Thread(target=self.Schedule)
+ self._schedule.start()
+
+ def Schedule(self):
+ for i in range(self._processNum):
+ task = threading.Thread(target=self.startTask)
+ task.daemon = False
+ self.running.append(task)
+
+ self.runningLock.acquire(True)
+ for thread in self.running:
+ thread.start()
+ self.runningLock.release()
+
+ while len(self.running) > 0:
+ time.sleep(0.1)
+ if self.error:
+ print("subprocess not exit successfully")
+ print(self.errorMsg)
+
+ def startTask(self):
+ while True:
+ if self.error:
+ break
+ self.pendingLock.acquire(True)
+ if len(self.pending) == 0:
+ self.pendingLock.release()
+ break
+ task = self.pending.pop(0)
+ self.pendingLock.release()
+ try:
+ task.run()
+ except RuntimeError as e:
+ if self.error: break
+ self.errorLock.acquire(True)
+ self.error = True
+ self.errorMsg = str(e)
+ time.sleep(0.1)
+ self.errorLock.release()
+ break
+
+ self.runningLock.acquire(True)
+ self.running.remove(threading.currentThread())
+ self.runningLock.release()
+
+def Run():
+ curdir = os.path.abspath(os.curdir)
+ if len(args.subdirs) == 1:
+ args.jobs = 1
+ if args.jobs == 1:
+ try:
+ for dir in args.subdirs:
+ RunCommand(os.path.join(curdir, dir), "nmake", args.target, stdout=sys.stdout, stderr=subprocess.STDOUT)
+ except RuntimeError:
+ exit(1)
+ else:
+ controller = ThreadControl(args.jobs)
+ for dir in args.subdirs:
+ controller.addTask(RunCommand, os.path.join(curdir, dir), "nmake", args.target)
+ controller.startSchedule()
+ controller.waitComplete()
+ if controller.error:
+ exit(1)
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(prog=__prog__, description=__description__ + __copyright__, conflict_handler='resolve')
+
+ parser.add_argument("target", help="the target for nmake")
+ parser.add_argument("subdirs", nargs="+", help="the relative dir path of makefile")
+ parser.add_argument("--jobs", type=int, dest="jobs", default=cpu_count, help="thread number")
+ parser.add_argument('--version', action='version', version=__version__)
+ args = parser.parse_args()
+ Run()
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/app.makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/app.makefile
new file mode 100644
index 00000000..37ed3c2f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/app.makefile
@@ -0,0 +1,22 @@
+## @file
+# Makefiles
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+MAKEROOT ?= ../..
+
+include $(MAKEROOT)/Makefiles/header.makefile
+
+APPLICATION = $(MAKEROOT)/bin/$(APPNAME)
+
+.PHONY:all
+all: $(MAKEROOT)/bin $(APPLICATION)
+
+$(APPLICATION): $(OBJECTS)
+ $(LINKER) -o $(APPLICATION) $(BUILD_LFLAGS) $(OBJECTS) -L$(MAKEROOT)/libs $(LIBS)
+
+$(OBJECTS): $(MAKEROOT)/Include/Common/BuildVersion.h
+
+include $(MAKEROOT)/Makefiles/footer.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/footer.makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/footer.makefile
new file mode 100644
index 00000000..4eeb1a06
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/footer.makefile
@@ -0,0 +1,30 @@
+## @file
+# Makefile
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+DEPFILES = $(OBJECTS:%.o=%.d)
+
+$(MAKEROOT)/libs-$(HOST_ARCH):
+ mkdir -p $(MAKEROOT)/libs-$(HOST_ARCH)
+
+.PHONY: install
+install: $(MAKEROOT)/libs-$(HOST_ARCH) $(LIBRARY)
+ cp $(LIBRARY) $(MAKEROOT)/libs-$(HOST_ARCH)
+
+$(LIBRARY): $(OBJECTS)
+ $(BUILD_AR) crs $@ $^
+
+%.o : %.c
+ $(BUILD_CC) -c $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) $< -o $@
+
+%.o : %.cpp
+ $(BUILD_CXX) -c $(BUILD_CPPFLAGS) $(BUILD_CXXFLAGS) $< -o $@
+
+.PHONY: clean
+clean:
+ @rm -f $(OBJECTS) $(LIBRARY) $(DEPFILES)
+
+-include $(DEPFILES)
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/header.makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/header.makefile
new file mode 100644
index 00000000..45c93595
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/header.makefile
@@ -0,0 +1,137 @@
+## @file
+#
+# The makefile can be invoked with
+# HOST_ARCH = x86_64 or x64 for EM64T build
+# HOST_ARCH = ia32 or IA32 for IA32 build
+# HOST_ARCH = Arm or ARM for ARM build
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ifndef HOST_ARCH
+ #
+ # If HOST_ARCH is not defined, then we use 'uname -m' to attempt
+ # try to figure out the appropriate HOST_ARCH.
+ #
+ uname_m = $(shell uname -m)
+ $(info Attempting to detect HOST_ARCH from 'uname -m': $(uname_m))
+ ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))
+ HOST_ARCH=X64
+ endif
+ ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
+ HOST_ARCH=IA32
+ endif
+ ifneq (,$(findstring aarch64,$(uname_m)))
+ HOST_ARCH=AARCH64
+ else ifneq (,$(findstring arm64,$(uname_m)))
+ HOST_ARCH=AARCH64
+ else ifneq (,$(findstring arm,$(uname_m)))
+ HOST_ARCH=ARM
+ endif
+ ifneq (,$(findstring riscv64,$(uname_m)))
+ HOST_ARCH=RISCV64
+ endif
+ ifndef HOST_ARCH
+ $(info Could not detected HOST_ARCH from uname results)
+ $(error HOST_ARCH is not defined!)
+ endif
+ $(info Detected HOST_ARCH of $(HOST_ARCH) using uname.)
+endif
+
+CYGWIN:=$(findstring CYGWIN, $(shell uname -s))
+LINUX:=$(findstring Linux, $(shell uname -s))
+DARWIN:=$(findstring Darwin, $(shell uname -s))
+ifeq ($(CXX), llvm)
+BUILD_CC ?= $(CLANG_BIN)clang
+BUILD_CXX ?= $(CLANG_BIN)clang++
+BUILD_AS ?= $(CLANG_BIN)clang
+BUILD_AR ?= $(CLANG_BIN)llvm-ar
+BUILD_LD ?= $(CLANG_BIN)llvm-ld
+else
+BUILD_CC ?= gcc
+BUILD_CXX ?= g++
+BUILD_AS ?= gcc
+BUILD_AR ?= ar
+BUILD_LD ?= ld
+endif
+LINKER ?= $(BUILD_CC)
+ifeq ($(HOST_ARCH), IA32)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/Ia32/
+
+else ifeq ($(HOST_ARCH), X64)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/X64/
+
+else ifeq ($(HOST_ARCH), ARM)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/Arm/
+
+else ifeq ($(HOST_ARCH), AARCH64)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
+
+else ifeq ($(HOST_ARCH), RISCV64)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/RiscV64/
+
+else
+$(error Bad HOST_ARCH)
+endif
+
+INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE)
+BUILD_CPPFLAGS = $(INCLUDE)
+
+# keep EXTRA_OPTFLAGS last
+BUILD_OPTFLAGS = -O2 $(EXTRA_OPTFLAGS)
+
+ifeq ($(DARWIN),Darwin)
+# assume clang or clang compatible flags on OS X
+BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror \
+-Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -nostdlib -g
+else
+ifeq ($(CXX), llvm)
+BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -fwrapv \
+-fno-delete-null-pointer-checks -Wall -Werror \
+-Wno-deprecated-declarations -Wno-self-assign \
+-Wno-unused-result -nostdlib -g
+else
+BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -fwrapv \
+-fno-delete-null-pointer-checks -Wall -Werror \
+-Wno-deprecated-declarations -Wno-stringop-truncation -Wno-restrict \
+-Wno-unused-result -nostdlib -g
+endif
+endif
+ifeq ($(CXX), llvm)
+BUILD_LFLAGS =
+BUILD_CXXFLAGS = -Wno-deprecated-register -Wno-unused-result
+else
+BUILD_LFLAGS =
+BUILD_CXXFLAGS = -Wno-unused-result
+endif
+ifeq ($(HOST_ARCH), IA32)
+#
+# Snow Leopard is a 32-bit and 64-bit environment. uname -m returns i386, but gcc defaults
+# to x86_64. So make sure tools match uname -m. You can manual have a 64-bit kernal on Snow Leopard
+# so only do this is uname -m returns i386.
+#
+ifeq ($(DARWIN),Darwin)
+ BUILD_CFLAGS += -arch i386
+ BUILD_CPPFLAGS += -arch i386
+ BUILD_LFLAGS += -arch i386
+endif
+endif
+
+# keep BUILD_OPTFLAGS last
+BUILD_CFLAGS += $(BUILD_OPTFLAGS)
+BUILD_CXXFLAGS += $(BUILD_OPTFLAGS)
+
+# keep EXTRA_LDFLAGS last
+BUILD_LFLAGS += $(EXTRA_LDFLAGS)
+
+.PHONY: all
+.PHONY: install
+.PHONY: clean
+
+all:
+
+$(MAKEROOT)/libs:
+ mkdir $(MAKEROOT)/libs
+
+$(MAKEROOT)/bin:
+ mkdir $(MAKEROOT)/bin
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/lib.makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/lib.makefile
new file mode 100644
index 00000000..ea6bf247
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/lib.makefile
@@ -0,0 +1,14 @@
+## @file
+# Makefiles
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+include $(MAKEROOT)/Makefiles/header.makefile
+
+LIBRARY = $(MAKEROOT)/libs/lib$(LIBNAME).a
+
+all: $(MAKEROOT)/libs $(LIBRARY)
+
+include $(MAKEROOT)/Makefiles/footer.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.app b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.app
new file mode 100644
index 00000000..3aeb5974
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.app
@@ -0,0 +1,28 @@
+## @file
+# Makefile
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+APPLICATION = $(BIN_PATH)\$(APPNAME).exe
+
+all: $(APPLICATION)
+
+$(APPLICATION) : $(OBJECTS)
+ -@if not exist $(BIN_PATH) mkdir $(BIN_PATH)
+ $(LD) /nologo /debug /OPT:REF /OPT:ICF=10 /incremental:no /nodefaultlib:libc.lib /out:$@ $(LIBS) $**
+
+$(OBJECTS) : $(SOURCE_PATH)\Include\Common\BuildVersion.h
+
+.PHONY:clean
+.PHONY:cleanall
+
+clean:
+ del /f /q $(OBJECTS) *.pdb > nul
+
+cleanall:
+ del /f /q $(OBJECTS) $(APPLICATION) *.pdb $(BIN_PATH)\$(APPNAME).pdb > nul
+
+!INCLUDE $(SOURCE_PATH)\Makefiles\ms.rule
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.common b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.common
new file mode 100644
index 00000000..695da7a3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.common
@@ -0,0 +1,62 @@
+## @file
+# Makefile
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+!IFNDEF EDK_TOOLS_PATH
+!ERROR "Please set your EDK_TOOLS_PATH!"
+!ENDIF
+
+!IFNDEF BASE_TOOLS_PATH
+!ERROR "BASE_TOOLS_PATH is not set! Please run build_tools.bat at first!"
+!ENDIF
+
+!IFNDEF HOST_ARCH
+HOST_ARCH = IA32
+!ENDIF
+
+MAKE = nmake -nologo
+
+# DOS del command doesn't support ":\\" in the file path, such as j:\\BaseTools. Convert ":\\" to ":\"
+BASE_TOOLS_PATH = $(BASE_TOOLS_PATH::\\=:\)
+EDK_TOOLS_PATH = $(EDK_TOOLS_PATH::\\=:\)
+
+SOURCE_PATH = $(BASE_TOOLS_PATH)\Source\C
+BIN_PATH = $(BASE_TOOLS_PATH)\Bin
+LIB_PATH = $(BASE_TOOLS_PATH)\Lib
+
+SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin
+SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib
+
+!IF "$(HOST_ARCH)"=="IA32"
+ARCH_INCLUDE = $(SOURCE_PATH)\Include\Ia32
+BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32
+LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win32
+SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win32
+SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32
+
+!ELSEIF "$(HOST_ARCH)"=="X64"
+ARCH_INCLUDE = $(SOURCE_PATH)\Include\X64
+BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64
+LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win64
+SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win64
+SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win64
+
+!ELSE
+!ERROR "Bad HOST_ARCH"
+!ENDIF
+
+CC = cl.exe
+CXX = cl.exe
+AS = ml.exe
+AR = lib.exe
+LD = link.exe
+LINKER = $(LD)
+
+INC = $(INC) -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common
+
+CFLAGS = $(CFLAGS) /nologo /Zi /c /O2 /MT /W4 /WX /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE
+CPPFLAGS = $(CPPFLAGS) /EHsc /nologo /Zi /c /O2 /MT /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.lib b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.lib
new file mode 100644
index 00000000..6b61fa47
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.lib
@@ -0,0 +1,25 @@
+## @file
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+!INCLUDE ..\Makefiles\ms.common
+
+LIBRARY = $(LIB_PATH)\$(LIBNAME).lib
+
+all: $(LIBRARY)
+
+$(LIBRARY) : $(OBJECTS)
+ -@if not exist $(LIB_PATH) mkdir $(LIB_PATH)
+ $(AR) /nologo /out:$@ $**
+
+.PHONY:clean
+clean:
+ del /f /q $(OBJECTS) *.pdb > nul
+
+.PHONY:cleanall
+cleanall:
+ del /f /q $(OBJECTS) $(LIBRARY) *.pdb > nul
+
+!INCLUDE ..\Makefiles\ms.rule
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.rule b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.rule
new file mode 100644
index 00000000..ba34eabd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/Makefiles/ms.rule
@@ -0,0 +1,20 @@
+## @file
+# Makefile
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+#DEPFILES = $(OBJECTS:%.o=%.d)
+
+.c.obj :
+ $(CC) -c $(CFLAGS) $(INC) $< -Fo$@
+
+.S.obj :
+ $(AS) -c $(ASFLAGS) $< -Fo$@
+
+.cpp.obj :
+ $(CXX) -c $(CPPFLAGS) $(INC) $< -Fo$@
+
+#-include $(DEPFILES)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/EfiCompressor.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/EfiCompressor.c
new file mode 100644
index 00000000..4c9ce442
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/EfiCompressor.c
@@ -0,0 +1,206 @@
+/** @file
+Efi Compressor
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Python.h>
+#include <Decompress.h>
+
+/*
+ UefiDecompress(data_buffer, size, original_size)
+*/
+STATIC
+PyObject*
+UefiDecompress(
+ PyObject *Self,
+ PyObject *Args
+ )
+{
+ PyObject *SrcData;
+ UINT32 SrcDataSize;
+ UINT32 DstDataSize;
+ UINTN Status;
+ UINT8 *SrcBuf;
+ UINT8 *DstBuf;
+ UINT8 *TmpBuf;
+ Py_ssize_t SegNum;
+ Py_ssize_t Index;
+
+ Status = PyArg_ParseTuple(
+ Args,
+ "Oi",
+ &SrcData,
+ &SrcDataSize
+ );
+ if (Status == 0) {
+ return NULL;
+ }
+
+ if (SrcData->ob_type->tp_as_buffer == NULL
+ || SrcData->ob_type->tp_as_buffer->bf_getreadbuffer == NULL
+ || SrcData->ob_type->tp_as_buffer->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_Exception, "First argument is not a buffer\n");
+ return NULL;
+ }
+
+ // Because some Python objects which support "buffer" protocol have more than one
+ // memory segment, we have to copy them into a contiguous memory.
+ SrcBuf = PyMem_Malloc(SrcDataSize);
+ if (SrcBuf == NULL) {
+ PyErr_SetString(PyExc_Exception, "Not enough memory\n");
+ goto ERROR;
+ }
+
+ SegNum = SrcData->ob_type->tp_as_buffer->bf_getsegcount((PyObject *)SrcData, NULL);
+ TmpBuf = SrcBuf;
+ for (Index = 0; Index < SegNum; ++Index) {
+ VOID *BufSeg;
+ Py_ssize_t Len;
+
+ Len = SrcData->ob_type->tp_as_buffer->bf_getreadbuffer((PyObject *)SrcData, Index, &BufSeg);
+ if (Len < 0) {
+ PyErr_SetString(PyExc_Exception, "Buffer segment is not available\n");
+ goto ERROR;
+ }
+ memcpy(TmpBuf, BufSeg, Len);
+ TmpBuf += Len;
+ }
+
+ Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID **)&DstBuf, &DstDataSize, 1);
+ if (Status != EFI_SUCCESS) {
+ PyErr_SetString(PyExc_Exception, "Failed to decompress\n");
+ goto ERROR;
+ }
+
+ return PyBuffer_FromMemory(DstBuf, (Py_ssize_t)DstDataSize);
+
+ERROR:
+ if (SrcBuf != NULL) {
+ free(SrcBuf);
+ }
+
+ if (DstBuf != NULL) {
+ free(DstBuf);
+ }
+ return NULL;
+}
+
+
+STATIC
+PyObject*
+FrameworkDecompress(
+ PyObject *Self,
+ PyObject *Args
+ )
+{
+ PyObject *SrcData;
+ UINT32 SrcDataSize;
+ UINT32 DstDataSize;
+ UINTN Status;
+ UINT8 *SrcBuf;
+ UINT8 *DstBuf;
+ UINT8 *TmpBuf;
+ Py_ssize_t SegNum;
+ Py_ssize_t Index;
+
+ Status = PyArg_ParseTuple(
+ Args,
+ "Oi",
+ &SrcData,
+ &SrcDataSize
+ );
+ if (Status == 0) {
+ return NULL;
+ }
+
+ if (SrcData->ob_type->tp_as_buffer == NULL
+ || SrcData->ob_type->tp_as_buffer->bf_getreadbuffer == NULL
+ || SrcData->ob_type->tp_as_buffer->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_Exception, "First argument is not a buffer\n");
+ return NULL;
+ }
+
+ // Because some Python objects which support "buffer" protocol have more than one
+ // memory segment, we have to copy them into a contiguous memory.
+ SrcBuf = PyMem_Malloc(SrcDataSize);
+ if (SrcBuf == NULL) {
+ PyErr_SetString(PyExc_Exception, "Not enough memory\n");
+ goto ERROR;
+ }
+
+ SegNum = SrcData->ob_type->tp_as_buffer->bf_getsegcount((PyObject *)SrcData, NULL);
+ TmpBuf = SrcBuf;
+ for (Index = 0; Index < SegNum; ++Index) {
+ VOID *BufSeg;
+ Py_ssize_t Len;
+
+ Len = SrcData->ob_type->tp_as_buffer->bf_getreadbuffer((PyObject *)SrcData, Index, &BufSeg);
+ if (Len < 0) {
+ PyErr_SetString(PyExc_Exception, "Buffer segment is not available\n");
+ goto ERROR;
+ }
+ memcpy(TmpBuf, BufSeg, Len);
+ TmpBuf += Len;
+ }
+
+ Status = Extract((VOID *)SrcBuf, SrcDataSize, (VOID **)&DstBuf, &DstDataSize, 2);
+ if (Status != EFI_SUCCESS) {
+ PyErr_SetString(PyExc_Exception, "Failed to decompress\n");
+ goto ERROR;
+ }
+
+ return PyString_FromStringAndSize((CONST INT8*)DstBuf, (Py_ssize_t)DstDataSize);
+
+ERROR:
+ if (SrcBuf != NULL) {
+ free(SrcBuf);
+ }
+
+ if (DstBuf != NULL) {
+ free(DstBuf);
+ }
+ return NULL;
+}
+
+
+STATIC
+PyObject*
+UefiCompress(
+ PyObject *Self,
+ PyObject *Args
+ )
+{
+ return NULL;
+}
+
+
+STATIC
+PyObject*
+FrameworkCompress(
+ PyObject *Self,
+ PyObject *Args
+ )
+{
+ return NULL;
+}
+
+STATIC INT8 DecompressDocs[] = "Decompress(): Decompress data using UEFI standard algorithm\n";
+STATIC INT8 CompressDocs[] = "Compress(): Compress data using UEFI standard algorithm\n";
+
+STATIC PyMethodDef EfiCompressor_Funcs[] = {
+ {"UefiDecompress", (PyCFunction)UefiDecompress, METH_VARARGS, DecompressDocs},
+ {"UefiCompress", (PyCFunction)UefiCompress, METH_VARARGS, DecompressDocs},
+ {"FrameworkDecompress", (PyCFunction)FrameworkDecompress, METH_VARARGS, DecompressDocs},
+ {"FrameworkCompress", (PyCFunction)FrameworkCompress, METH_VARARGS, DecompressDocs},
+ {NULL, NULL, 0, NULL}
+};
+
+PyMODINIT_FUNC
+initEfiCompressor(VOID) {
+ Py_InitModule3("EfiCompressor", EfiCompressor_Funcs, "EFI Compression Algorithm Extension Module");
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/Makefile
new file mode 100644
index 00000000..46322b8d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/Makefile
@@ -0,0 +1,18 @@
+## @file
+# Makefile
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenSec
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = GenSec.obj
+
+#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py
new file mode 100755
index 00000000..7ccc6d8c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py
@@ -0,0 +1,37 @@
+## @file
+# package and install PyEfiCompressor extension
+#
+# Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+from distutils.core import setup, Extension
+import os
+
+if 'BASE_TOOLS_PATH' not in os.environ:
+ raise "Please define BASE_TOOLS_PATH to the root of base tools tree"
+
+BaseToolsDir = os.environ['BASE_TOOLS_PATH']
+setup(
+ name="EfiCompressor",
+ version="0.01",
+ ext_modules=[
+ Extension(
+ 'EfiCompressor',
+ sources=[
+ os.path.join(BaseToolsDir, 'Source', 'C', 'Common', 'Decompress.c'),
+ 'EfiCompressor.c'
+ ],
+ include_dirs=[
+ os.path.join(BaseToolsDir, 'Source', 'C', 'Include'),
+ os.path.join(BaseToolsDir, 'Source', 'C', 'Include', 'Ia32'),
+ os.path.join(BaseToolsDir, 'Source', 'C', 'Common')
+ ],
+ )
+ ],
+ )
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/GNUmakefile
new file mode 100644
index 00000000..6e0e25c1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/GNUmakefile
@@ -0,0 +1,15 @@
+## @file
+# GNU/Linux makefile for 'TianoCompress' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = TianoCompress
+
+LIBS = -lCommon
+
+OBJECTS = TianoCompress.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile
new file mode 100644
index 00000000..46a250e7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile
@@ -0,0 +1,16 @@
+## @file
+# Windows makefile for 'TianoCompress' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = TianoCompress
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = TianoCompress.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile.kmk
new file mode 100644
index 00000000..77e3e9d2
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI TianoCompress build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += TianoCompress
+TianoCompress_TEMPLATE = VBoxEfiBldProg
+TianoCompress_SOURCES = TianoCompress.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.c
new file mode 100644
index 00000000..8288b97d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.c
@@ -0,0 +1,2795 @@
+/** @file
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman
+coding. LZ77 transforms the source data into a sequence of Original Characters
+and Pointers to repeated strings.
+This sequence is further divided into Blocks and Huffman codings are applied to
+each Block.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Compress.h"
+#include "Decompress.h"
+#include "TianoCompress.h"
+#include "EfiUtilityMsgs.h"
+#include "ParseInf.h"
+#include <stdio.h>
+#include "assert.h"
+
+//
+// Macro Definitions
+//
+static BOOLEAN VerboseMode = FALSE;
+static BOOLEAN QuietMode = FALSE;
+#undef UINT8_MAX
+#define UINT8_MAX 0xff
+#define UINT8_BIT 8
+#define THRESHOLD 3
+#define INIT_CRC 0
+#define WNDBIT 19
+#define WNDSIZ (1U << WNDBIT)
+#define MAXMATCH 256
+#define BLKSIZ (1U << 14) // 16 * 1024U
+#define PERC_FLAG 0x80000000U
+#define CODE_BIT 16
+#define NIL 0
+#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)
+#define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)
+#define CRCPOLY 0xA001
+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)
+
+//
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set
+//
+//#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9
+#define NP (WNDBIT + 1)
+#define PBIT 5
+//#define NT (CODE_BIT + 3)
+//#define TBIT 5
+//#if NT > NP
+//#define NPT NT
+//#else
+//#define NPT NP
+//#endif
+
+//
+// Global Variables
+//
+STATIC BOOLEAN ENCODE = FALSE;
+STATIC BOOLEAN DECODE = FALSE;
+STATIC BOOLEAN UEFIMODE = FALSE;
+STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
+STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
+STATIC INT16 mHeap[NC + 1];
+STATIC INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN;
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;
+STATIC UINT32 mCompSize, mOrigSize;
+
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],
+ mCFreq[2 * NC - 1], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];
+
+STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;
+
+static UINT64 DebugLevel;
+static BOOLEAN DebugMode;
+//
+// functions
+//
+EFI_STATUS
+TianoCompress (
+ IN UINT8 *SrcBuffer,
+ IN UINT32 SrcSize,
+ IN UINT8 *DstBuffer,
+ IN OUT UINT32 *DstSize
+ )
+/*++
+
+Routine Description:
+
+ The internal implementation of [Efi/Tiano]Compress().
+
+Arguments:
+
+ SrcBuffer - The buffer storing the source data
+ SrcSize - The size of source data
+ DstBuffer - The buffer to store the compressed data
+
+ Version - The version of de/compression algorithm.
+ Version 1 for EFI 1.1 de/compression algorithm.
+ Version 2 for Tiano de/compression algorithm.
+
+Returns:
+
+ EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case,
+ DstSize contains the size needed.
+ EFI_SUCCESS - Compression is successful.
+ EFI_OUT_OF_RESOURCES - No resource to complete function.
+ EFI_INVALID_PARAMETER - Parameter supplied is wrong.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Initializations
+ //
+ mBufSiz = 0;
+ mBuf = NULL;
+ mText = NULL;
+ mLevel = NULL;
+ mChildCount = NULL;
+ mPosition = NULL;
+ mParent = NULL;
+ mPrev = NULL;
+ mNext = NULL;
+
+
+ mSrc = SrcBuffer;
+ mSrcUpperLimit = mSrc + SrcSize;
+ mDst = DstBuffer;
+ mDstUpperLimit = mDst +*DstSize;
+
+ PutDword (0L);
+ PutDword (0L);
+
+ MakeCrcTable ();
+
+ mOrigSize = mCompSize = 0;
+ mCrc = INIT_CRC;
+
+ //
+ // Compress it
+ //
+ Status = Encode ();
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Null terminate the compressed data
+ //
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = 0;
+ }
+
+ //
+ // Fill in compressed size and original size
+ //
+ mDst = DstBuffer;
+
+ PutDword (mCompSize + 1);
+ PutDword (mOrigSize);
+ //
+ // Return
+ //
+
+ if (mCompSize + 1 + 8 > *DstSize) {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ *DstSize = mCompSize + 1 + 8;
+ return EFI_SUCCESS;
+ }
+}
+
+STATIC
+VOID
+PutDword (
+ IN UINT32 Data
+ )
+/*++
+
+Routine Description:
+
+ Put a dword to output stream
+
+Arguments:
+
+ Data - the dword to put
+
+Returns: (VOID)
+
+--*/
+{
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);
+ }
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);
+ }
+}
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Allocate memory spaces for data structures used in compression process
+
+Arguments:
+ VOID
+
+Returns:
+
+ EFI_SUCCESS - Memory is allocated successfully
+ EFI_OUT_OF_RESOURCES - Allocation fails
+
+--*/
+{
+ UINT32 Index;
+
+ mText = malloc (WNDSIZ * 2 + MAXMATCH);
+ if (mText == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {
+ mText[Index] = 0;
+ }
+
+ mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));
+ mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount));
+ mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition));
+ mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
+ mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
+ mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
+ if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||
+ mParent == NULL || mPrev == NULL || mNext == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mBufSiz = BLKSIZ;
+ mBuf = malloc (mBufSiz);
+ while (mBuf == NULL) {
+ mBufSiz = (mBufSiz / 10U) * 9U;
+ if (mBufSiz < 4 * 1024U) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mBuf = malloc (mBufSiz);
+ }
+
+ mBuf[0] = 0;
+
+ return EFI_SUCCESS;
+}
+
+VOID
+FreeMemory (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Called when compression is completed to free memory previously allocated.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ if (mText != NULL) {
+ free (mText);
+ }
+
+ if (mLevel != NULL) {
+ free (mLevel);
+ }
+
+ if (mChildCount != NULL) {
+ free (mChildCount);
+ }
+
+ if (mPosition != NULL) {
+ free (mPosition);
+ }
+
+ if (mParent != NULL) {
+ free (mParent);
+ }
+
+ if (mPrev != NULL) {
+ free (mPrev);
+ }
+
+ if (mNext != NULL) {
+ free (mNext);
+ }
+
+ if (mBuf != NULL) {
+ free (mBuf);
+ }
+
+ return ;
+}
+
+STATIC
+VOID
+InitSlide (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize String Info Log data structures
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE Index;
+
+ for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) {
+ mLevel[Index] = 1;
+ mPosition[Index] = NIL; // sentinel
+ }
+
+ for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) {
+ mParent[Index] = NIL;
+ }
+
+ mAvail = 1;
+ for (Index = 1; Index < WNDSIZ - 1; Index++) {
+ mNext[Index] = (NODE) (Index + 1);
+ }
+
+ mNext[WNDSIZ - 1] = NIL;
+ for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) {
+ mNext[Index] = NIL;
+ }
+}
+
+STATIC
+NODE
+Child (
+ IN NODE NodeQ,
+ IN UINT8 CharC
+ )
+/*++
+
+Routine Description:
+
+ Find child node given the parent node and the edge character
+
+Arguments:
+
+ NodeQ - the parent node
+ CharC - the edge character
+
+Returns:
+
+ The child node (NIL if not found)
+
+--*/
+{
+ NODE NodeR;
+
+ NodeR = mNext[HASH (NodeQ, CharC)];
+ //
+ // sentinel
+ //
+ mParent[NIL] = NodeQ;
+ while (mParent[NodeR] != NodeQ) {
+ NodeR = mNext[NodeR];
+ }
+
+ return NodeR;
+}
+
+STATIC
+VOID
+MakeChild (
+ IN NODE Parent,
+ IN UINT8 CharC,
+ IN NODE Child
+ )
+/*++
+
+Routine Description:
+
+ Create a new child for a given parent node.
+
+Arguments:
+
+ Parent - the parent node
+ CharC - the edge character
+ Child - the child node
+
+Returns: (VOID)
+
+--*/
+{
+ NODE Node1;
+ NODE Node2;
+
+ Node1 = (NODE) HASH (Parent, CharC);
+ Node2 = mNext[Node1];
+ mNext[Node1] = Child;
+ mNext[Child] = Node2;
+ mPrev[Node2] = Child;
+ mPrev[Child] = Node1;
+ mParent[Child] = Parent;
+ mChildCount[Parent]++;
+}
+
+STATIC
+VOID
+Split (
+ NODE Old
+ )
+/*++
+
+Routine Description:
+
+ Split a node.
+
+Arguments:
+
+ Old - the node to split
+
+Returns: (VOID)
+
+--*/
+{
+ NODE New;
+ NODE TempNode;
+
+ New = mAvail;
+ mAvail = mNext[New];
+ mChildCount[New] = 0;
+ TempNode = mPrev[Old];
+ mPrev[New] = TempNode;
+ mNext[TempNode] = New;
+ TempNode = mNext[Old];
+ mNext[New] = TempNode;
+ mPrev[TempNode] = New;
+ mParent[New] = mParent[Old];
+ mLevel[New] = (UINT8) mMatchLen;
+ mPosition[New] = mPos;
+ MakeChild (New, mText[mMatchPos + mMatchLen], Old);
+ MakeChild (New, mText[mPos + mMatchLen], mPos);
+}
+
+STATIC
+VOID
+InsertNode (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Insert string info for current position into the String Info Log
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE NodeQ;
+ NODE NodeR;
+ NODE Index2;
+ NODE NodeT;
+ UINT8 CharC;
+ UINT8 *t1;
+ UINT8 *t2;
+
+ if (mMatchLen >= 4) {
+ //
+ // We have just got a long match, the target tree
+ // can be located by MatchPos + 1. Traverse the tree
+ // from bottom up to get to a proper starting point.
+ // The usage of PERC_FLAG ensures proper node deletion
+ // in DeleteNode() later.
+ //
+ mMatchLen--;
+ NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ);
+ NodeQ = mParent[NodeR];
+ while (NodeQ == NIL) {
+ NodeR = mNext[NodeR];
+ NodeQ = mParent[NodeR];
+ }
+
+ while (mLevel[NodeQ] >= mMatchLen) {
+ NodeR = NodeQ;
+ NodeQ = mParent[NodeQ];
+ }
+
+ NodeT = NodeQ;
+ while (mPosition[NodeT] < 0) {
+ mPosition[NodeT] = mPos;
+ NodeT = mParent[NodeT];
+ }
+
+ if (NodeT < WNDSIZ) {
+ mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG);
+ }
+ } else {
+ //
+ // Locate the target tree
+ //
+ NodeQ = (NODE) (mText[mPos] + WNDSIZ);
+ CharC = mText[mPos + 1];
+ NodeR = Child (NodeQ, CharC);
+ if (NodeR == NIL) {
+ MakeChild (NodeQ, CharC, mPos);
+ mMatchLen = 1;
+ return ;
+ }
+
+ mMatchLen = 2;
+ }
+ //
+ // Traverse down the tree to find a match.
+ // Update Position value along the route.
+ // Node split or creation is involved.
+ //
+ for (;;) {
+ if (NodeR >= WNDSIZ) {
+ Index2 = MAXMATCH;
+ mMatchPos = NodeR;
+ } else {
+ Index2 = mLevel[NodeR];
+ mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
+ }
+
+ if (mMatchPos >= mPos) {
+ mMatchPos -= WNDSIZ;
+ }
+
+ t1 = &mText[mPos + mMatchLen];
+ t2 = &mText[mMatchPos + mMatchLen];
+ while (mMatchLen < Index2) {
+ if (*t1 != *t2) {
+ Split (NodeR);
+ return ;
+ }
+
+ mMatchLen++;
+ t1++;
+ t2++;
+ }
+
+ if (mMatchLen >= MAXMATCH) {
+ break;
+ }
+
+ mPosition[NodeR] = mPos;
+ NodeQ = NodeR;
+ NodeR = Child (NodeQ, *t1);
+ if (NodeR == NIL) {
+ MakeChild (NodeQ, *t1, mPos);
+ return ;
+ }
+
+ mMatchLen++;
+ }
+
+ NodeT = mPrev[NodeR];
+ mPrev[mPos] = NodeT;
+ mNext[NodeT] = mPos;
+ NodeT = mNext[NodeR];
+ mNext[mPos] = NodeT;
+ mPrev[NodeT] = mPos;
+ mParent[mPos] = NodeQ;
+ mParent[NodeR] = NIL;
+
+ //
+ // Special usage of 'next'
+ //
+ mNext[NodeR] = mPos;
+
+}
+
+STATIC
+VOID
+DeleteNode (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Delete outdated string info. (The Usage of PERC_FLAG
+ ensures a clean deletion)
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ NODE NodeQ;
+ NODE NodeR;
+ NODE NodeS;
+ NODE NodeT;
+ NODE NodeU;
+
+ if (mParent[mPos] == NIL) {
+ return ;
+ }
+
+ NodeR = mPrev[mPos];
+ NodeS = mNext[mPos];
+ mNext[NodeR] = NodeS;
+ mPrev[NodeS] = NodeR;
+ NodeR = mParent[mPos];
+ mParent[mPos] = NIL;
+ if (NodeR >= WNDSIZ) {
+ return ;
+ }
+
+ mChildCount[NodeR]--;
+ if (mChildCount[NodeR] > 1) {
+ return ;
+ }
+
+ NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG);
+ if (NodeT >= mPos) {
+ NodeT -= WNDSIZ;
+ }
+
+ NodeS = NodeT;
+ NodeQ = mParent[NodeR];
+ NodeU = mPosition[NodeQ];
+ while (NodeU & (UINT32) PERC_FLAG) {
+ NodeU &= (UINT32)~PERC_FLAG;
+ if (NodeU >= mPos) {
+ NodeU -= WNDSIZ;
+ }
+
+ if (NodeU > NodeS) {
+ NodeS = NodeU;
+ }
+
+ mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ);
+ NodeQ = mParent[NodeQ];
+ NodeU = mPosition[NodeQ];
+ }
+
+ if (NodeQ < WNDSIZ) {
+ if (NodeU >= mPos) {
+ NodeU -= WNDSIZ;
+ }
+
+ if (NodeU > NodeS) {
+ NodeS = NodeU;
+ }
+
+ mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG);
+ }
+
+ NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]);
+ NodeT = mPrev[NodeS];
+ NodeU = mNext[NodeS];
+ mNext[NodeT] = NodeU;
+ mPrev[NodeU] = NodeT;
+ NodeT = mPrev[NodeR];
+ mNext[NodeT] = NodeS;
+ mPrev[NodeS] = NodeT;
+ NodeT = mNext[NodeR];
+ mPrev[NodeT] = NodeS;
+ mNext[NodeS] = NodeT;
+ mParent[NodeS] = mParent[NodeR];
+ mParent[NodeR] = NIL;
+ mNext[NodeR] = mAvail;
+ mAvail = NodeR;
+}
+
+STATIC
+VOID
+GetNextMatch (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Advance the current position (read in new data if needed).
+ Delete outdated string info. Find a match string for current position.
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Number;
+
+ mRemainder--;
+ mPos++;
+ if (mPos == WNDSIZ * 2) {
+ memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);
+ Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ);
+ mRemainder += Number;
+ mPos = WNDSIZ;
+ }
+
+ DeleteNode ();
+ InsertNode ();
+}
+
+STATIC
+EFI_STATUS
+Encode (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ The main controlling routine for compression process.
+
+Arguments: (VOID)
+
+Returns:
+
+ EFI_SUCCESS - The compression is successful
+ EFI_OUT_0F_RESOURCES - Not enough memory for compression process
+
+--*/
+{
+ EFI_STATUS Status;
+ INT32 LastMatchLen;
+ NODE LastMatchPos;
+
+ Status = AllocateMemory ();
+ if (EFI_ERROR (Status)) {
+ FreeMemory ();
+ return Status;
+ }
+
+ InitSlide ();
+
+ HufEncodeStart ();
+
+ mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH);
+
+ mMatchLen = 0;
+ mPos = WNDSIZ;
+ InsertNode ();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ while (mRemainder > 0) {
+ LastMatchLen = mMatchLen;
+ LastMatchPos = mMatchPos;
+ GetNextMatch ();
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+
+ if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {
+ //
+ // Not enough benefits are gained by outputting a pointer,
+ // so just output the original character
+ //
+ Output (mText[mPos - 1], 0);
+
+ } else {
+
+ if (LastMatchLen == THRESHOLD) {
+ if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) {
+ Output (mText[mPos - 1], 0);
+ continue;
+ }
+ }
+ //
+ // Outputting a pointer is beneficial enough, do it.
+ //
+ Output (
+ LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),
+ (mPos - LastMatchPos - 2) & (WNDSIZ - 1)
+ );
+ LastMatchLen--;
+ while (LastMatchLen > 0) {
+ GetNextMatch ();
+ LastMatchLen--;
+ }
+
+ if (mMatchLen > mRemainder) {
+ mMatchLen = mRemainder;
+ }
+ }
+ }
+
+ HufEncodeEnd ();
+ FreeMemory ();
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+CountTFreq (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Count the frequencies for the Extra Set
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+ INT32 Number;
+ INT32 Count;
+
+ for (Index = 0; Index < NT; Index++) {
+ mTFreq[Index] = 0;
+ }
+
+ Number = NC;
+ while (Number > 0 && mCLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mCLen[Index++];
+ if (Index3 == 0) {
+ Count = 1;
+ while (Index < Number && mCLen[Index] == 0) {
+ Index++;
+ Count++;
+ }
+
+ if (Count <= 2) {
+ mTFreq[0] = (UINT16) (mTFreq[0] + Count);
+ } else if (Count <= 18) {
+ mTFreq[1]++;
+ } else if (Count == 19) {
+ mTFreq[0]++;
+ mTFreq[1]++;
+ } else {
+ mTFreq[2]++;
+ }
+ } else {
+ mTFreq[Index3 + 2]++;
+ }
+ }
+}
+
+STATIC
+VOID
+WritePTLen (
+ IN INT32 Number,
+ IN INT32 nbit,
+ IN INT32 Special
+ )
+/*++
+
+Routine Description:
+
+ Outputs the code length array for the Extra Set or the Position Set.
+
+Arguments:
+
+ Number - the number of symbols
+ nbit - the number of bits needed to represent 'n'
+ Special - the special symbol that needs to be take care of
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+
+ while (Number > 0 && mPTLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ PutBits (nbit, Number);
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mPTLen[Index++];
+ if (Index3 <= 6) {
+ PutBits (3, Index3);
+ } else {
+ PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2);
+ }
+
+ if (Index == Special) {
+ while (Index < 6 && mPTLen[Index] == 0) {
+ Index++;
+ }
+
+ PutBits (2, (Index - 3) & 3);
+ }
+ }
+}
+
+STATIC
+VOID
+WriteCLen (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Outputs the code length array for Char&Length Set
+
+Arguments: (VOID)
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+ INT32 Number;
+ INT32 Count;
+
+ Number = NC;
+ while (Number > 0 && mCLen[Number - 1] == 0) {
+ Number--;
+ }
+
+ PutBits (CBIT, Number);
+ Index = 0;
+ while (Index < Number) {
+ Index3 = mCLen[Index++];
+ if (Index3 == 0) {
+ Count = 1;
+ while (Index < Number && mCLen[Index] == 0) {
+ Index++;
+ Count++;
+ }
+
+ if (Count <= 2) {
+ for (Index3 = 0; Index3 < Count; Index3++) {
+ PutBits (mPTLen[0], mPTCode[0]);
+ }
+ } else if (Count <= 18) {
+ PutBits (mPTLen[1], mPTCode[1]);
+ PutBits (4, Count - 3);
+ } else if (Count == 19) {
+ PutBits (mPTLen[0], mPTCode[0]);
+ PutBits (mPTLen[1], mPTCode[1]);
+ PutBits (4, 15);
+ } else {
+ PutBits (mPTLen[2], mPTCode[2]);
+ PutBits (CBIT, Count - 20);
+ }
+ } else {
+ PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]);
+ }
+ }
+}
+
+STATIC
+VOID
+EncodeC (
+ IN INT32 Value
+ )
+{
+ PutBits (mCLen[Value], mCCode[Value]);
+}
+
+STATIC
+VOID
+EncodeP (
+ IN UINT32 Value
+ )
+{
+ UINT32 Index;
+ UINT32 NodeQ;
+
+ Index = 0;
+ NodeQ = Value;
+ while (NodeQ) {
+ NodeQ >>= 1;
+ Index++;
+ }
+
+ PutBits (mPTLen[Index], mPTCode[Index]);
+ if (Index > 1) {
+ PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1)));
+ }
+}
+
+STATIC
+VOID
+SendBlock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Huffman code the block and output it.
+
+Arguments:
+ (VOID)
+
+Returns:
+ (VOID)
+
+--*/
+{
+ UINT32 Index;
+ UINT32 Index2;
+ UINT32 Index3;
+ UINT32 Flags;
+ UINT32 Root;
+ UINT32 Pos;
+ UINT32 Size;
+ Flags = 0;
+
+ Root = MakeTree (NC, mCFreq, mCLen, mCCode);
+ Size = mCFreq[Root];
+
+ PutBits (16, Size);
+ if (Root >= NC) {
+ CountTFreq ();
+ Root = MakeTree (NT, mTFreq, mPTLen, mPTCode);
+ if (Root >= NT) {
+ WritePTLen (NT, TBIT, 3);
+ } else {
+ PutBits (TBIT, 0);
+ PutBits (TBIT, Root);
+ }
+
+ WriteCLen ();
+ } else {
+ PutBits (TBIT, 0);
+ PutBits (TBIT, 0);
+ PutBits (CBIT, 0);
+ PutBits (CBIT, Root);
+ }
+
+ Root = MakeTree (NP, mPFreq, mPTLen, mPTCode);
+ if (Root >= NP) {
+ WritePTLen (NP, PBIT, -1);
+ } else {
+ PutBits (PBIT, 0);
+ PutBits (PBIT, Root);
+ }
+
+ Pos = 0;
+ for (Index = 0; Index < Size; Index++) {
+ if (Index % UINT8_BIT == 0) {
+ Flags = mBuf[Pos++];
+ } else {
+ Flags <<= 1;
+ }
+
+ if (Flags & (1U << (UINT8_BIT - 1))) {
+ EncodeC (mBuf[Pos++] + (1U << UINT8_BIT));
+ Index3 = mBuf[Pos++];
+ for (Index2 = 0; Index2 < 3; Index2++) {
+ Index3 <<= UINT8_BIT;
+ Index3 += mBuf[Pos++];
+ }
+
+ EncodeP (Index3);
+ } else {
+ EncodeC (mBuf[Pos++]);
+ }
+ }
+
+ for (Index = 0; Index < NC; Index++) {
+ mCFreq[Index] = 0;
+ }
+
+ for (Index = 0; Index < NP; Index++) {
+ mPFreq[Index] = 0;
+ }
+}
+
+STATIC
+VOID
+Output (
+ IN UINT32 CharC,
+ IN UINT32 Pos
+ )
+/*++
+
+Routine Description:
+
+ Outputs an Original Character or a Pointer
+
+Arguments:
+
+ CharC - The original character or the 'String Length' element of a Pointer
+ Pos - The 'Position' field of a Pointer
+
+Returns: (VOID)
+
+--*/
+{
+ STATIC UINT32 CPos;
+
+ if ((mOutputMask >>= 1) == 0) {
+ mOutputMask = 1U << (UINT8_BIT - 1);
+ //
+ // Check the buffer overflow per outputing UINT8_BIT symbols
+ // which is an Original Character or a Pointer. The biggest
+ // symbol is a Pointer which occupies 5 bytes.
+ //
+ if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) {
+ SendBlock ();
+ mOutputPos = 0;
+ }
+
+ CPos = mOutputPos++;
+ mBuf[CPos] = 0;
+ }
+
+ mBuf[mOutputPos++] = (UINT8) CharC;
+ mCFreq[CharC]++;
+ if (CharC >= (1U << UINT8_BIT)) {
+ mBuf[CPos] |= mOutputMask;
+ mBuf[mOutputPos++] = (UINT8) (Pos >> 24);
+ mBuf[mOutputPos++] = (UINT8) (Pos >> 16);
+ mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT));
+ mBuf[mOutputPos++] = (UINT8) Pos;
+ CharC = 0;
+ while (Pos) {
+ Pos >>= 1;
+ CharC++;
+ }
+
+ mPFreq[CharC]++;
+ }
+}
+
+STATIC
+VOID
+HufEncodeStart (
+ VOID
+ )
+{
+ INT32 Index;
+
+ for (Index = 0; Index < NC; Index++) {
+ mCFreq[Index] = 0;
+ }
+
+ for (Index = 0; Index < NP; Index++) {
+ mPFreq[Index] = 0;
+ }
+
+ mOutputPos = mOutputMask = 0;
+ InitPutBits ();
+ return ;
+}
+
+STATIC
+VOID
+HufEncodeEnd (
+ VOID
+ )
+{
+ SendBlock ();
+
+ //
+ // Flush remaining bits
+ //
+ PutBits (UINT8_BIT - 1, 0);
+
+ return ;
+}
+
+STATIC
+VOID
+MakeCrcTable (
+ VOID
+ )
+{
+ UINT32 Index;
+ UINT32 Index2;
+ UINT32 Temp;
+
+ for (Index = 0; Index <= UINT8_MAX; Index++) {
+ Temp = Index;
+ for (Index2 = 0; Index2 < UINT8_BIT; Index2++) {
+ if (Temp & 1) {
+ Temp = (Temp >> 1) ^ CRCPOLY;
+ } else {
+ Temp >>= 1;
+ }
+ }
+
+ mCrcTable[Index] = (UINT16) Temp;
+ }
+}
+
+STATIC
+VOID
+PutBits (
+ IN INT32 Number,
+ IN UINT32 Value
+ )
+/*++
+
+Routine Description:
+
+ Outputs rightmost n bits of x
+
+Arguments:
+
+ Number - the rightmost n bits of the data is used
+ x - the data
+
+Returns: (VOID)
+
+--*/
+{
+ UINT8 Temp;
+
+ while (Number >= mBitCount) {
+ //
+ // Number -= mBitCount should never equal to 32
+ //
+ Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount)));
+
+ if (mDst < mDstUpperLimit) {
+ *mDst++ = Temp;
+ }
+
+ mCompSize++;
+ mSubBitBuf = 0;
+ mBitCount = UINT8_BIT;
+ }
+
+ mSubBitBuf |= Value << (mBitCount -= Number);
+}
+
+STATIC
+INT32
+FreadCrc (
+ OUT UINT8 *Pointer,
+ IN INT32 Number
+ )
+/*++
+
+Routine Description:
+
+ Read in source data
+
+Arguments:
+
+ Pointer - the buffer to hold the data
+ Number - number of bytes to read
+
+Returns:
+
+ number of bytes actually read
+
+--*/
+{
+ INT32 Index;
+
+ for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) {
+ *Pointer++ = *mSrc++;
+ }
+
+ Number = Index;
+
+ Pointer -= Number;
+ mOrigSize += Number;
+
+ Index--;
+ while (Index >= 0) {
+ UPDATE_CRC (*Pointer++);
+ Index--;
+ }
+
+ return Number;
+}
+
+STATIC
+VOID
+InitPutBits (
+ VOID
+ )
+{
+ mBitCount = UINT8_BIT;
+ mSubBitBuf = 0;
+}
+
+STATIC
+VOID
+CountLen (
+ IN INT32 Index
+ )
+/*++
+
+Routine Description:
+
+ Count the number of each code length for a Huffman tree.
+
+Arguments:
+
+ Index - the top node
+
+Returns: (VOID)
+
+--*/
+{
+ STATIC INT32 Depth = 0;
+
+ if (Index < mN) {
+ mLenCnt[(Depth < 16) ? Depth : 16]++;
+ } else {
+ Depth++;
+ CountLen (mLeft[Index]);
+ CountLen (mRight[Index]);
+ Depth--;
+ }
+}
+
+STATIC
+VOID
+MakeLen (
+ IN INT32 Root
+ )
+/*++
+
+Routine Description:
+
+ Create code length array for a Huffman tree
+
+Arguments:
+
+ Root - the root of the tree
+
+Returns:
+
+ VOID
+
+--*/
+{
+ INT32 Index;
+ INT32 Index3;
+ UINT32 Cum;
+
+ for (Index = 0; Index <= 16; Index++) {
+ mLenCnt[Index] = 0;
+ }
+
+ CountLen (Root);
+
+ //
+ // Adjust the length count array so that
+ // no code will be generated longer than its designated length
+ //
+ Cum = 0;
+ for (Index = 16; Index > 0; Index--) {
+ Cum += mLenCnt[Index] << (16 - Index);
+ }
+
+ while (Cum != (1U << 16)) {
+ mLenCnt[16]--;
+ for (Index = 15; Index > 0; Index--) {
+ if (mLenCnt[Index] != 0) {
+ mLenCnt[Index]--;
+ mLenCnt[Index + 1] += 2;
+ break;
+ }
+ }
+
+ Cum--;
+ }
+
+ for (Index = 16; Index > 0; Index--) {
+ Index3 = mLenCnt[Index];
+ Index3--;
+ while (Index3 >= 0) {
+ mLen[*mSortPtr++] = (UINT8) Index;
+ Index3--;
+ }
+ }
+}
+
+STATIC
+VOID
+DownHeap (
+ IN INT32 Index
+ )
+{
+ INT32 Index2;
+ INT32 Index3;
+
+ //
+ // priority queue: send Index-th entry down heap
+ //
+ Index3 = mHeap[Index];
+ Index2 = 2 * Index;
+ while (Index2 <= mHeapSize) {
+ if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) {
+ Index2++;
+ }
+
+ if (mFreq[Index3] <= mFreq[mHeap[Index2]]) {
+ break;
+ }
+
+ mHeap[Index] = mHeap[Index2];
+ Index = Index2;
+ Index2 = 2 * Index;
+ }
+
+ mHeap[Index] = (INT16) Index3;
+}
+
+STATIC
+VOID
+MakeCode (
+ IN INT32 Number,
+ IN UINT8 Len[ ],
+ OUT UINT16 Code[]
+ )
+/*++
+
+Routine Description:
+
+ Assign code to each symbol based on the code length array
+
+Arguments:
+
+ Number - number of symbols
+ Len - the code length array
+ Code - stores codes for each symbol
+
+Returns: (VOID)
+
+--*/
+{
+ INT32 Index;
+ UINT16 Start[18];
+
+ Start[1] = 0;
+ for (Index = 1; Index <= 16; Index++) {
+ Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1);
+ }
+
+ for (Index = 0; Index < Number; Index++) {
+ Code[Index] = Start[Len[Index]]++;
+ }
+}
+
+STATIC
+INT32
+MakeTree (
+ IN INT32 NParm,
+ IN UINT16 FreqParm[],
+ OUT UINT8 LenParm[ ],
+ OUT UINT16 CodeParm[]
+ )
+/*++
+
+Routine Description:
+
+ Generates Huffman codes given a frequency distribution of symbols
+
+Arguments:
+
+ NParm - number of symbols
+ FreqParm - frequency of each symbol
+ LenParm - code length for each symbol
+ CodeParm - code for each symbol
+
+Returns:
+
+ Root of the Huffman tree.
+
+--*/
+{
+ INT32 Index;
+ INT32 Index2;
+ INT32 Index3;
+ INT32 Avail;
+
+ //
+ // make tree, calculate len[], return root
+ //
+ mN = NParm;
+ mFreq = FreqParm;
+ mLen = LenParm;
+ Avail = mN;
+ mHeapSize = 0;
+ mHeap[1] = 0;
+ for (Index = 0; Index < mN; Index++) {
+ mLen[Index] = 0;
+ if (mFreq[Index]) {
+ mHeapSize++;
+ mHeap[mHeapSize] = (INT16) Index;
+ }
+ }
+
+ if (mHeapSize < 2) {
+ CodeParm[mHeap[1]] = 0;
+ return mHeap[1];
+ }
+
+ for (Index = mHeapSize / 2; Index >= 1; Index--) {
+ //
+ // make priority queue
+ //
+ DownHeap (Index);
+ }
+
+ mSortPtr = CodeParm;
+ do {
+ Index = mHeap[1];
+ if (Index < mN) {
+ *mSortPtr++ = (UINT16) Index;
+ }
+
+ mHeap[1] = mHeap[mHeapSize--];
+ DownHeap (1);
+ Index2 = mHeap[1];
+ if (Index2 < mN) {
+ *mSortPtr++ = (UINT16) Index2;
+ }
+
+ Index3 = Avail++;
+ mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]);
+ mHeap[1] = (INT16) Index3;
+ DownHeap (1);
+ mLeft[Index3] = (UINT16) Index;
+ mRight[Index3] = (UINT16) Index2;
+ } while (mHeapSize > 1);
+
+ mSortPtr = CodeParm;
+ MakeLen (Index3);
+ MakeCode (NParm, LenParm, CodeParm);
+
+ //
+ // return root
+ //
+ return Index3;
+}
+
+EFI_STATUS
+GetFileContents (
+ IN char *InputFileName,
+ OUT UINT8 *FileBuffer,
+ OUT UINT32 *BufferLength
+ )
+/*++
+
+Routine Description:
+
+ Get the contents of file specified in InputFileName
+ into FileBuffer.
+
+Arguments:
+
+ InputFileName - Name of the input file.
+
+ FileBuffer - Output buffer to contain data
+
+ BufferLength - Actual length of the data
+
+Returns:
+
+ EFI_SUCCESS on successful return
+ EFI_ABORTED if unable to open input file.
+
+--*/
+{
+ UINTN Size;
+ UINTN FileSize;
+ FILE *InputFile;
+
+ Size = 0;
+ //
+ // Copy the file contents to the output buffer.
+ //
+ InputFile = fopen (LongFilePath (InputFileName), "rb");
+ if (InputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file: %s", InputFileName);
+ return EFI_ABORTED;
+ }
+
+ fseek (InputFile, 0, SEEK_END);
+ FileSize = ftell (InputFile);
+ fseek (InputFile, 0, SEEK_SET);
+ //
+ // Now read the contents of the file into the buffer
+ //
+ if (FileSize > 0 && FileBuffer != NULL) {
+ if (fread (FileBuffer, FileSize, 1, InputFile) != 1) {
+ Error (NULL, 0, 0004, "Error reading contents of input file: %s", InputFileName);
+ fclose (InputFile);
+ return EFI_ABORTED;
+ }
+ }
+
+ fclose (InputFile);
+ Size += (UINTN) FileSize;
+ *BufferLength = Size;
+
+ if (FileBuffer != NULL) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+}
+
+VOID
+Version (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the standard utility information to SDTOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
+}
+
+VOID
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "Options:\n");
+ fprintf (stdout, " --uefi\n\
+ Enable UefiCompress, use TianoCompress when without this option\n");
+ fprintf (stdout, " -o FileName, --output FileName\n\
+ File will be created to store the output content.\n");
+ fprintf (stdout, " -v, --verbose\n\
+ Turn on verbose output with informational messages.\n");
+ fprintf (stdout, " -q, --quiet\n\
+ Disable all messages except key message and fatal error\n");
+ fprintf (stdout, " --debug [0-9]\n\
+ Enable debug messages, at input debug level.\n");
+ fprintf (stdout, " --version\n\
+ Show program's version number and exit.\n");
+ fprintf (stdout, " -h, --help\n\
+ Show this help message and exit.\n");
+}
+
+
+int
+main (
+ int argc,
+ char *argv[]
+ )
+/*++
+
+Routine Description:
+
+ Main
+
+Arguments:
+
+ command line parameters
+
+Returns:
+
+ EFI_SUCCESS Section header successfully generated and section concatenated.
+ EFI_ABORTED Could not generate the section
+ EFI_OUT_OF_RESOURCES No resource to complete the operation.
+
+--*/
+{
+ FILE *OutputFile;
+ char *OutputFileName;
+ char *InputFileName;
+ FILE *InputFile;
+ EFI_STATUS Status;
+ UINT8 *FileBuffer;
+ UINT8 *OutBuffer;
+ UINT32 InputLength;
+ UINT32 DstSize;
+ SCRATCH_DATA *Scratch;
+ UINT8 *Src;
+ UINT32 OrigSize;
+ UINT32 CompSize;
+
+ SetUtilityName(UTILITY_NAME);
+
+ FileBuffer = NULL;
+ Src = NULL;
+ OutBuffer = NULL;
+ Scratch = NULL;
+ OrigSize = 0;
+ CompSize = 0;
+ InputLength = 0;
+ InputFileName = NULL;
+ OutputFileName = NULL;
+ InputFile = NULL;
+ OutputFile = NULL;
+ DstSize=0;
+ DebugLevel = 0;
+ DebugMode = FALSE;
+
+ //
+ // Verify the correct number of arguments
+ //
+ if (argc == 1) {
+ Error (NULL, 0, 1001, "Missing options", "No input options specified.");
+ Usage();
+ return 0;
+ }
+
+ if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
+ Usage();
+ return 0;
+ }
+
+ if ((strcmp(argv[1], "--version") == 0)) {
+ Version();
+ return 0;
+ }
+
+ argc--;
+ argv++;
+ if (strcmp(argv[0],"-e") == 0) {
+ //
+ // encode the input file
+ //
+ ENCODE = TRUE;
+ argc--;
+ argv++;
+ } else if (strcmp(argv[0], "-d") == 0) {
+ //
+ // decode the input file
+ //
+ DECODE = TRUE;
+ argc--;
+ argv++;
+ } else {
+ //
+ // Error command line
+ //
+ Error (NULL, 0, 1003, "Invalid option value", "the options specified are not recognized.");
+ Usage();
+ return 1;
+ }
+
+ while (argc > 0) {
+ if ((strcmp(argv[0], "-v") == 0) || (stricmp(argv[0], "--verbose") == 0)) {
+ VerboseMode = TRUE;
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if (stricmp(argv[0], "--uefi") == 0) {
+ UEFIMODE = TRUE;
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if (stricmp (argv[0], "--debug") == 0) {
+ argc-=2;
+ argv++;
+ Status = AsciiStringToUint64(argv[0], FALSE, &DebugLevel);
+ if (DebugLevel > 9) {
+ Error (NULL, 0 ,2000, "Invalid parameter", "Unrecognized argument %s", argv[0]);
+ goto ERROR;
+ }
+ if (DebugLevel>=5 && DebugLevel <=9){
+ DebugMode = TRUE;
+ } else {
+ DebugMode = FALSE;
+ }
+ argv++;
+ continue;
+ }
+
+ if ((strcmp(argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ QuietMode = TRUE;
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if ((strcmp(argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Output File name is missing for -o option");
+ goto ERROR;
+ }
+ OutputFileName = argv[1];
+ argc -=2;
+ argv +=2;
+ continue;
+ }
+
+ if (argv[0][0]!='-') {
+ InputFileName = argv[0];
+ argc--;
+ argv++;
+ continue;
+ }
+
+ Error (NULL, 0, 1000, "Unknown option", argv[0]);
+ goto ERROR;
+ }
+
+ if (InputFileName == NULL) {
+ Error (NULL, 0, 1001, "Missing options", "No input files specified.");
+ goto ERROR;
+ }
+
+//
+// All Parameters has been parsed, now set the message print level
+//
+ if (QuietMode) {
+ SetPrintLevel(40);
+ } else if (VerboseMode) {
+ SetPrintLevel(15);
+ } else if (DebugMode) {
+ SetPrintLevel(DebugLevel);
+ }
+
+ if (VerboseMode) {
+ VerboseMsg("%s tool start.\n", UTILITY_NAME);
+ }
+ Scratch = (SCRATCH_DATA *)malloc(sizeof(SCRATCH_DATA));
+ if (Scratch == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+
+ InputFile = fopen (LongFilePath (InputFileName), "rb");
+ if (InputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening input file", InputFileName);
+ goto ERROR;
+ }
+
+ Status = GetFileContents(
+ InputFileName,
+ FileBuffer,
+ &InputLength);
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FileBuffer = (UINT8 *) malloc (InputLength);
+ if (FileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+
+ Status = GetFileContents (
+ InputFileName,
+ FileBuffer,
+ &InputLength
+ );
+ }
+
+ if (EFI_ERROR(Status)) {
+ Error (NULL, 0, 0004, "Error getting contents of file: %s", InputFileName);
+ goto ERROR;
+ }
+
+ if (OutputFileName == NULL) {
+ OutputFileName = DEFAULT_OUTPUT_FILE;
+ }
+ OutputFile = fopen (LongFilePath (OutputFileName), "wb");
+ if (OutputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);
+ goto ERROR;
+ }
+
+ if (ENCODE) {
+ //
+ // First call TianoCompress to get DstSize
+ //
+ if (DebugMode) {
+ DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding", NULL);
+ }
+ if (UEFIMODE) {
+ Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ } else {
+ Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ }
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ OutBuffer = (UINT8 *) malloc (DstSize);
+ if (OutBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+ }
+
+ if (UEFIMODE) {
+ Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ } else {
+ Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ }
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 0007, "Error compressing file", NULL);
+ goto ERROR;
+ }
+
+ if (OutBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+
+ fwrite(OutBuffer,(size_t)DstSize, 1, OutputFile);
+ fclose(OutputFile);
+ fclose(InputFile);
+ free(Scratch);
+ free(FileBuffer);
+ free(OutBuffer);
+
+ if (DebugMode) {
+ DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding Successful!\n", NULL);
+ }
+ if (VerboseMode) {
+ VerboseMsg("Encoding successful\n");
+ }
+ return 0;
+ }
+ else if (DECODE) {
+ if (DebugMode) {
+ DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);
+ }
+
+ if (UEFIMODE) {
+ Status = Extract((VOID *)FileBuffer, InputLength, (VOID *)&OutBuffer, &DstSize, 1);
+ if (Status != EFI_SUCCESS) {
+ goto ERROR;
+ }
+ fwrite(OutBuffer, (size_t)(DstSize), 1, OutputFile);
+ } else {
+ if (InputLength < 8){
+ Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);
+ goto ERROR;
+ }
+ //
+ // Get Compressed file original size
+ //
+ Src = (UINT8 *)FileBuffer;
+ OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);
+
+ //
+ // Allocate OutputBuffer
+ //
+ if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {
+ Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);
+ goto ERROR;
+ }
+ OutBuffer = (UINT8 *)malloc(OrigSize);
+ if (OutBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+
+ Status = TDecompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);
+ if (Status != EFI_SUCCESS) {
+ goto ERROR;
+ }
+ fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);
+ }
+ fclose(OutputFile);
+ fclose(InputFile);
+ if (Scratch != NULL) {
+ free(Scratch);
+ }
+ if (FileBuffer != NULL) {
+ free(FileBuffer);
+ }
+ if (OutBuffer != NULL) {
+ free(OutBuffer);
+ }
+
+ if (DebugMode) {
+ DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding successful!\n", NULL);
+ }
+
+ if (VerboseMode) {
+ VerboseMsg("Decoding successful\n");
+ }
+ return 0;
+ }
+
+ERROR:
+ if (DebugMode) {
+ if (ENCODE) {
+ DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding Error\n", NULL);
+ } else if (DECODE) {
+ DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding Error\n", NULL);
+ }
+ }
+ if (OutputFile != NULL) {
+ fclose(OutputFile);
+ }
+ if (InputFile != NULL) {
+ fclose (InputFile);
+ }
+ if (Scratch != NULL) {
+ free(Scratch);
+ }
+ if (FileBuffer != NULL) {
+ free(FileBuffer);
+ }
+ if (OutBuffer != NULL) {
+ free(OutBuffer);
+ }
+
+ if (VerboseMode) {
+ VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
+ }
+ return GetUtilityStatus ();
+}
+
+VOID
+FillBuf (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfBits
+ )
+/*++
+
+Routine Description:
+
+ Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
+
+Arguments:
+
+ Sd - The global scratch data
+ NumOfBits - The number of bits to shift and read.
+
+Returns: (VOID)
+
+--*/
+{
+ Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
+
+ while (NumOfBits > Sd->mBitCount) {
+
+ Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
+
+ if (Sd->mCompSize > 0) {
+ //
+ // Get 1 byte into SubBitBuf
+ //
+ Sd->mCompSize--;
+ Sd->mSubBitBuf = 0;
+ Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
+ Sd->mBitCount = 8;
+
+ } else {
+ //
+ // No more bits from the source, just pad zero bit.
+ //
+ Sd->mSubBitBuf = 0;
+ Sd->mBitCount = 8;
+
+ }
+ }
+
+ Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
+ Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
+}
+
+UINT32
+GetBits (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfBits
+ )
+/*++
+
+Routine Description:
+
+ Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
+ NumOfBits of bits from source. Returns NumOfBits of bits that are
+ popped out.
+
+Arguments:
+
+ Sd - The global scratch data.
+ NumOfBits - The number of bits to pop and read.
+
+Returns:
+
+ The bits that are popped out.
+
+--*/
+{
+ UINT32 OutBits;
+
+ OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
+
+ FillBuf (Sd, NumOfBits);
+
+ return OutBits;
+}
+
+UINT16
+MakeTable (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfChar,
+ IN UINT8 *BitLen,
+ IN UINT16 TableBits,
+ OUT UINT16 *Table
+ )
+/*++
+
+Routine Description:
+
+ Creates Huffman Code mapping table according to code length array.
+
+Arguments:
+
+ Sd - The global scratch data
+ NumOfChar - Number of symbols in the symbol set
+ BitLen - Code length array
+ TableBits - The width of the mapping table
+ Table - The table
+
+Returns:
+
+ 0 - OK.
+ BAD_TABLE - The table is corrupted.
+
+--*/
+{
+ UINT16 Count[17];
+ UINT16 Weight[17];
+ UINT16 Start[18];
+ UINT16 *Pointer;
+ UINT16 Index3;
+ UINT16 Index;
+ UINT16 Len;
+ UINT16 Char;
+ UINT16 JuBits;
+ UINT16 Avail;
+ UINT16 NextCode;
+ UINT16 Mask;
+ UINT16 WordOfStart;
+ UINT16 WordOfCount;
+ UINT16 MaxTableLength;
+
+ for (Index = 0; Index <= 16; Index++) {
+ Count[Index] = 0;
+ }
+
+ for (Index = 0; Index < NumOfChar; Index++) {
+ if (BitLen[Index] > 16) {
+ return (UINT16) BAD_TABLE;
+ }
+ Count[BitLen[Index]]++;
+ }
+
+ Start[0] = 0;
+ Start[1] = 0;
+
+ for (Index = 1; Index <= 16; Index++) {
+ WordOfStart = Start[Index];
+ WordOfCount = Count[Index];
+ Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));
+ }
+
+ if (Start[17] != 0) {
+ //
+ //(1U << 16)
+ //
+ return (UINT16) BAD_TABLE;
+ }
+
+ JuBits = (UINT16) (16 - TableBits);
+
+ Weight[0] = 0;
+ for (Index = 1; Index <= TableBits; Index++) {
+ Start[Index] >>= JuBits;
+ Weight[Index] = (UINT16) (1U << (TableBits - Index));
+ }
+
+ while (Index <= 16) {
+ Weight[Index] = (UINT16) (1U << (16 - Index));
+ Index++;
+ }
+
+ Index = (UINT16) (Start[TableBits + 1] >> JuBits);
+
+ if (Index != 0) {
+ Index3 = (UINT16) (1U << TableBits);
+ while (Index != Index3) {
+ Table[Index++] = 0;
+ }
+ }
+
+ Avail = NumOfChar;
+ Mask = (UINT16) (1U << (15 - TableBits));
+ MaxTableLength = (UINT16) (1U << TableBits);
+
+ for (Char = 0; Char < NumOfChar; Char++) {
+
+ Len = BitLen[Char];
+ if (Len == 0 || Len >= 17) {
+ continue;
+ }
+
+ NextCode = (UINT16) (Start[Len] + Weight[Len]);
+
+ if (Len <= TableBits) {
+
+ if (Start[Len] >= NextCode || NextCode > MaxTableLength){
+ return (UINT16) BAD_TABLE;
+ }
+
+ for (Index = Start[Len]; Index < NextCode; Index++) {
+ Table[Index] = Char;
+ }
+
+ } else {
+
+ Index3 = Start[Len];
+ Pointer = &Table[Index3 >> JuBits];
+ Index = (UINT16) (Len - TableBits);
+
+ while (Index != 0) {
+ if (*Pointer == 0) {
+ Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
+ *Pointer = Avail++;
+ }
+
+ if (Index3 & Mask) {
+ Pointer = &Sd->mRight[*Pointer];
+ } else {
+ Pointer = &Sd->mLeft[*Pointer];
+ }
+
+ Index3 <<= 1;
+ Index--;
+ }
+
+ *Pointer = Char;
+
+ }
+
+ Start[Len] = NextCode;
+ }
+ //
+ // Succeeds
+ //
+ return 0;
+}
+
+UINT32
+DecodeP (
+ IN SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Decodes a position value.
+
+Arguments:
+
+ Sd - the global scratch data
+
+Returns:
+
+ The position value decoded.
+
+--*/
+{
+ UINT16 Val;
+ UINT32 Mask;
+ UINT32 Pos;
+
+ Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
+
+ if (Val >= MAXNP) {
+ Mask = 1U << (BITBUFSIZ - 1 - 8);
+
+ do {
+
+ if (Sd->mBitBuf & Mask) {
+ Val = Sd->mRight[Val];
+ } else {
+ Val = Sd->mLeft[Val];
+ }
+
+ Mask >>= 1;
+ } while (Val >= MAXNP);
+ }
+ //
+ // Advance what we have read
+ //
+ FillBuf (Sd, Sd->mPTLen[Val]);
+
+ Pos = Val;
+ if (Val > 1) {
+ Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
+ }
+
+ return Pos;
+}
+
+UINT16
+ReadPTLen (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 nn,
+ IN UINT16 nbit,
+ IN UINT16 Special
+ )
+/*++
+
+Routine Description:
+
+ Reads code lengths for the Extra Set or the Position Set
+
+Arguments:
+
+ Sd - The global scratch data
+ nn - Number of symbols
+ nbit - Number of bits needed to represent nn
+ Special - The special symbol that needs to be taken care of
+
+Returns:
+
+ 0 - OK.
+ BAD_TABLE - Table is corrupted.
+
+--*/
+{
+ UINT16 Number;
+ UINT16 CharC;
+ volatile UINT16 Index;
+ UINT32 Mask;
+
+ assert (nn <= NPT);
+
+ Number = (UINT16) GetBits (Sd, nbit);
+
+ if (Number == 0) {
+ CharC = (UINT16) GetBits (Sd, nbit);
+
+ for (Index = 0; Index < 256; Index++) {
+ Sd->mPTTable[Index] = CharC;
+ }
+
+ for (Index = 0; Index < nn; Index++) {
+ Sd->mPTLen[Index] = 0;
+ }
+
+ return 0;
+ }
+
+ Index = 0;
+
+ while (Index < Number) {
+
+ CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
+
+ if (CharC == 7) {
+ Mask = 1U << (BITBUFSIZ - 1 - 3);
+ while (Mask & Sd->mBitBuf) {
+ Mask >>= 1;
+ CharC += 1;
+ }
+ }
+
+ FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
+
+ Sd->mPTLen[Index++] = (UINT8) CharC;
+
+ if (Index == Special) {
+ CharC = (UINT16) GetBits (Sd, 2);
+ while ((INT16) (--CharC) >= 0) {
+ Sd->mPTLen[Index++] = 0;
+ }
+ }
+ }
+
+ while (Index < nn) {
+ Sd->mPTLen[Index++] = 0;
+ }
+
+ return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
+}
+
+VOID
+ReadCLen (
+ SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Reads code lengths for Char&Len Set.
+
+Arguments:
+
+ Sd - the global scratch data
+
+Returns: (VOID)
+
+--*/
+{
+ UINT16 Number;
+ UINT16 CharC;
+ volatile UINT16 Index;
+ UINT32 Mask;
+
+ Number = (UINT16) GetBits (Sd, CBIT);
+
+ if (Number == 0) {
+ CharC = (UINT16) GetBits (Sd, CBIT);
+
+ for (Index = 0; Index < NC; Index++) {
+ Sd->mCLen[Index] = 0;
+ }
+
+ for (Index = 0; Index < 4096; Index++) {
+ Sd->mCTable[Index] = CharC;
+ }
+
+ return ;
+ }
+
+ Index = 0;
+ while (Index < Number) {
+
+ CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
+ if (CharC >= NT) {
+ Mask = 1U << (BITBUFSIZ - 1 - 8);
+
+ do {
+
+ if (Mask & Sd->mBitBuf) {
+ CharC = Sd->mRight[CharC];
+ } else {
+ CharC = Sd->mLeft[CharC];
+ }
+
+ Mask >>= 1;
+
+ } while (CharC >= NT);
+ }
+ //
+ // Advance what we have read
+ //
+ FillBuf (Sd, Sd->mPTLen[CharC]);
+
+ if (CharC <= 2) {
+
+ if (CharC == 0) {
+ CharC = 1;
+ } else if (CharC == 1) {
+ CharC = (UINT16) (GetBits (Sd, 4) + 3);
+ } else if (CharC == 2) {
+ CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
+ }
+
+ while ((INT16) (--CharC) >= 0) {
+ Sd->mCLen[Index++] = 0;
+ }
+
+ } else {
+
+ Sd->mCLen[Index++] = (UINT8) (CharC - 2);
+
+ }
+ }
+
+ while (Index < NC) {
+ Sd->mCLen[Index++] = 0;
+ }
+
+ MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
+
+ return ;
+}
+
+UINT16
+DecodeC (
+ SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Decode a character/length value.
+
+Arguments:
+
+ Sd - The global scratch data.
+
+Returns:
+
+ The value decoded.
+
+--*/
+{
+ UINT16 Index2;
+ UINT32 Mask;
+
+ if (Sd->mBlockSize == 0) {
+ //
+ // Starting a new block
+ //
+ Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
+ Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
+ if (Sd->mBadTableFlag != 0) {
+ return 0;
+ }
+
+ ReadCLen (Sd);
+
+ Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
+ if (Sd->mBadTableFlag != 0) {
+ return 0;
+ }
+ }
+
+ Sd->mBlockSize--;
+ Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
+
+ if (Index2 >= NC) {
+ Mask = 1U << (BITBUFSIZ - 1 - 12);
+
+ do {
+ if (Sd->mBitBuf & Mask) {
+ Index2 = Sd->mRight[Index2];
+ } else {
+ Index2 = Sd->mLeft[Index2];
+ }
+
+ Mask >>= 1;
+ } while (Index2 >= NC);
+ }
+ //
+ // Advance what we have read
+ //
+ FillBuf (Sd, Sd->mCLen[Index2]);
+
+ return Index2;
+}
+
+VOID
+Decode (
+ SCRATCH_DATA *Sd
+ )
+/*++
+
+Routine Description:
+
+ Decode the source data and put the resulting data into the destination buffer.
+
+Arguments:
+
+ Sd - The global scratch data
+
+Returns: (VOID)
+
+ --*/
+{
+ UINT16 BytesRemain;
+ UINT32 DataIdx;
+ UINT16 CharC;
+
+ BytesRemain = (UINT16) (-1);
+
+ DataIdx = 0;
+
+ for (;;) {
+ CharC = DecodeC (Sd);
+ if (Sd->mBadTableFlag != 0) {
+ goto Done ;
+ }
+
+ if (CharC < 256) {
+ //
+ // Process an Original character
+ //
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ goto Done ;
+ } else {
+ Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
+ }
+
+ } else {
+ //
+ // Process a Pointer
+ //
+ CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
+
+ BytesRemain = CharC;
+
+ DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
+
+ BytesRemain--;
+
+ while ((INT16) (BytesRemain) >= 0) {
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ goto Done ;
+ }
+ if (DataIdx >= Sd->mOrigSize) {
+ Sd->mBadTableFlag = (UINT16) BAD_TABLE;
+ goto Done ;
+ }
+ Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
+
+ BytesRemain--;
+ }
+ //
+ // Once mOutBuf is fully filled, directly return
+ //
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ goto Done ;
+ }
+ }
+ }
+
+Done:
+ return ;
+}
+
+RETURN_STATUS
+EFIAPI
+TDecompress (
+ IN VOID *Source,
+ IN OUT VOID *Destination,
+ IN OUT VOID *Scratch,
+ IN UINT32 Version
+ )
+/*++
+
+Routine Description:
+
+ The internal implementation of Decompress().
+
+Arguments:
+
+ Source - The source buffer containing the compressed data.
+ Destination - The destination buffer to store the decompressed data
+ Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
+ Version - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm
+
+Returns:
+
+ RETURN_SUCCESS - Decompression is successful
+ RETURN_INVALID_PARAMETER - The source data is corrupted
+
+--*/
+{
+ volatile UINT32 Index;
+ UINT32 CompSize;
+ UINT32 OrigSize;
+ SCRATCH_DATA *Sd;
+ CONST UINT8 *Src;
+ UINT8 *Dst;
+
+ //
+ // Verify input is not NULL
+ //
+ assert(Source);
+// assert(Destination);
+ assert(Scratch);
+
+ Src = (UINT8 *)Source;
+ Dst = (UINT8 *)Destination;
+
+ Sd = (SCRATCH_DATA *) Scratch;
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
+ OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+
+ //
+ // If compressed file size is 0, return
+ //
+ if (OrigSize == 0) {
+ return RETURN_SUCCESS;
+ }
+
+ Src = Src + 8;
+
+ for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
+ ((UINT8 *) Sd)[Index] = 0;
+ }
+ //
+ // The length of the field 'Position Set Code Length Array Size' in Block Header.
+ // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
+ // For Tiano de/compression algorithm(Version 2), mPBit = 5
+ //
+ switch (Version) {
+ case 1 :
+ Sd->mPBit = 4;
+ break;
+ case 2 :
+ Sd->mPBit = 5;
+ break;
+ default:
+ assert(FALSE);
+ }
+ Sd->mSrcBase = (UINT8 *)Src;
+ Sd->mDstBase = Dst;
+ Sd->mCompSize = CompSize;
+ Sd->mOrigSize = OrigSize;
+
+ //
+ // Fill the first BITBUFSIZ bits
+ //
+ FillBuf (Sd, BITBUFSIZ);
+
+ //
+ // Decompress it
+ //
+
+ Decode (Sd);
+
+ if (Sd->mBadTableFlag != 0) {
+ //
+ // Something wrong with the source
+ //
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.h
new file mode 100644
index 00000000..b4867b8f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/TianoCompress/TianoCompress.h
@@ -0,0 +1,431 @@
+/** @file
+ Internal include file for Tiano Decompress Library.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __TIANO_DECOMPRESS_H__
+#define __TIANO_DECOMPRESS_H__
+
+#include <stdio.h>
+#include <assert.h>
+#include <Common/UefiBaseTypes.h>
+
+
+//
+// Decompression algorithm begins here
+//
+#define UTILITY_NAME "TianoCompress"
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+//
+// Default output file name
+//
+#define DEFAULT_OUTPUT_FILE "file.tmp"
+
+#define BITBUFSIZ 32
+#define MAXMATCH 256
+#define THRESHOLD 3
+#define CODE_BIT 16
+#define BAD_TABLE - 1
+
+typedef INT32 NODE;
+
+//
+// C: Char&Len Set; P: Position Set; T: exTra Set
+//
+#define NC (0xff + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9
+#define MAXPBIT 5
+#define TBIT 5
+#define MAXNP ((1U << MAXPBIT) - 1)
+#define NT (CODE_BIT + 3)
+#if NT > MAXNP
+#define NPT NT
+#else
+#define NPT MAXNP
+#endif
+
+typedef struct {
+ UINT8 *mSrcBase; // Starting address of compressed data
+ UINT8 *mDstBase; // Starting address of decompressed data
+ UINT32 mOutBuf;
+ UINT32 mInBuf;
+
+ UINT16 mBitCount;
+ UINT32 mBitBuf;
+ UINT32 mSubBitBuf;
+ UINT16 mBlockSize;
+ UINT32 mCompSize;
+ UINT32 mOrigSize;
+
+ UINT16 mBadTableFlag;
+
+ UINT16 mLeft[2 * NC - 1];
+ UINT16 mRight[2 * NC - 1];
+ UINT8 mCLen[NC];
+ UINT8 mPTLen[NPT];
+ UINT16 mCTable[4096];
+ UINT16 mPTTable[256];
+
+ //
+ // The length of the field 'Position Set Code Length Array Size' in Block Header.
+ // For EFI 1.1 de/compression algorithm, mPBit = 4
+ // For Tiano de/compression algorithm, mPBit = 5
+ //
+ UINT8 mPBit;
+} SCRATCH_DATA;
+
+//
+// Function Prototypes
+//
+
+EFI_STATUS
+GetFileContents (
+ IN char *InputFileName,
+ OUT UINT8 *FileBuffer,
+ OUT UINT32 *BufferLength
+ );
+
+STATIC
+VOID
+PutDword(
+ IN UINT32 Data
+ );
+
+STATIC
+EFI_STATUS
+AllocateMemory (
+ VOID
+ );
+
+STATIC
+VOID
+FreeMemory (
+ VOID
+ );
+
+STATIC
+VOID
+InitSlide (
+ VOID
+ );
+
+STATIC
+NODE
+Child (
+ IN NODE NodeQ,
+ IN UINT8 CharC
+ );
+
+STATIC
+VOID
+MakeChild (
+ IN NODE NodeQ,
+ IN UINT8 CharC,
+ IN NODE NodeR
+ );
+
+STATIC
+VOID
+Split (
+ IN NODE Old
+ );
+
+STATIC
+VOID
+InsertNode (
+ VOID
+ );
+
+STATIC
+VOID
+DeleteNode (
+ VOID
+ );
+
+STATIC
+VOID
+GetNextMatch (
+ VOID
+ );
+
+STATIC
+EFI_STATUS
+Encode (
+ VOID
+ );
+
+STATIC
+VOID
+CountTFreq (
+ VOID
+ );
+
+STATIC
+VOID
+WritePTLen (
+ IN INT32 Number,
+ IN INT32 nbit,
+ IN INT32 Special
+ );
+
+STATIC
+VOID
+WriteCLen (
+ VOID
+ );
+
+STATIC
+VOID
+EncodeC (
+ IN INT32 Value
+ );
+
+STATIC
+VOID
+EncodeP (
+ IN UINT32 Value
+ );
+
+STATIC
+VOID
+SendBlock (
+ VOID
+ );
+
+STATIC
+VOID
+Output (
+ IN UINT32 c,
+ IN UINT32 p
+ );
+
+STATIC
+VOID
+HufEncodeStart (
+ VOID
+ );
+
+STATIC
+VOID
+HufEncodeEnd (
+ VOID
+ );
+
+STATIC
+VOID
+MakeCrcTable (
+ VOID
+ );
+
+
+STATIC
+VOID
+PutBits (
+ IN INT32 Number,
+ IN UINT32 Value
+ );
+
+STATIC
+INT32
+FreadCrc (
+ OUT UINT8 *Pointer,
+ IN INT32 Number
+ );
+
+STATIC
+VOID
+InitPutBits (
+ VOID
+ );
+
+STATIC
+VOID
+CountLen (
+ IN INT32 Index
+ );
+
+STATIC
+VOID
+MakeLen (
+ IN INT32 Root
+ );
+
+STATIC
+VOID
+DownHeap (
+ IN INT32 Index
+ );
+
+STATIC
+VOID
+MakeCode (
+ IN INT32 Number,
+ IN UINT8 Len[ ],
+ OUT UINT16 Code[]
+ );
+
+STATIC
+INT32
+MakeTree (
+ IN INT32 NParm,
+ IN UINT16 FreqParm[],
+ OUT UINT8 LenParm[ ],
+ OUT UINT16 CodeParm[]
+ );
+
+/**
+ Read NumOfBit of bits from source into mBitBuf
+
+ Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
+
+ @param Sd The global scratch data
+ @param NumOfBits The number of bits to shift and read.
+
+**/
+VOID
+FillBuf (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfBits
+ );
+
+/**
+ Get NumOfBits of bits out from mBitBuf
+
+ Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
+ NumOfBits of bits from source. Returns NumOfBits of bits that are
+ popped out.
+
+ @param Sd The global scratch data.
+ @param NumOfBits The number of bits to pop and read.
+
+ @return The bits that are popped out.
+
+**/
+UINT32
+GetBits (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfBits
+ );
+
+/**
+ Creates Huffman Code mapping table according to code length array.
+
+ Creates Huffman Code mapping table for Extra Set, Char&Len Set
+ and Position Set according to code length array.
+
+ @param Sd The global scratch data
+ @param NumOfChar Number of symbols in the symbol set
+ @param BitLen Code length array
+ @param TableBits The width of the mapping table
+ @param Table The table
+
+ @retval 0 OK.
+ @retval BAD_TABLE The table is corrupted.
+
+**/
+UINT16
+MakeTable (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 NumOfChar,
+ IN UINT8 *BitLen,
+ IN UINT16 TableBits,
+ OUT UINT16 *Table
+ );
+
+/**
+ Decodes a position value.
+
+ Get a position value according to Position Huffman Table.
+
+ @param Sd the global scratch data
+
+ @return The position value decoded.
+
+**/
+UINT32
+DecodeP (
+ IN SCRATCH_DATA *Sd
+ );
+
+/**
+ Reads code lengths for the Extra Set or the Position Set.
+
+ Read in the Extra Set or Position Set Length Array, then
+ generate the Huffman code mapping for them.
+
+ @param Sd The global scratch data.
+ @param nn Number of symbols.
+ @param nbit Number of bits needed to represent nn.
+ @param Special The special symbol that needs to be taken care of.
+
+ @retval 0 OK.
+ @retval BAD_TABLE Table is corrupted.
+
+**/
+UINT16
+ReadPTLen (
+ IN SCRATCH_DATA *Sd,
+ IN UINT16 nn,
+ IN UINT16 nbit,
+ IN UINT16 Special
+ );
+
+/**
+ Reads code lengths for Char&Len Set.
+
+ Read in and decode the Char&Len Set Code Length Array, then
+ generate the Huffman Code mapping table for the Char&Len Set.
+
+ @param Sd the global scratch data
+
+**/
+VOID
+ReadCLen (
+ SCRATCH_DATA *Sd
+ );
+
+/**
+ Decode a character/length value.
+
+ Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates
+ Huffman code mapping table for Extra Set, Code&Len Set and
+ Position Set.
+
+ @param Sd The global scratch data.
+
+ @return The value decoded.
+
+**/
+UINT16
+DecodeC (
+ SCRATCH_DATA *Sd
+ );
+
+/**
+ Decode the source data and put the resulting data into the destination buffer.
+
+ Decode the source data and put the resulting data into the destination buffer.
+
+ @param Sd The global scratch data
+
+**/
+VOID
+Decode (
+ SCRATCH_DATA *Sd
+ );
+
+RETURN_STATUS
+EFIAPI
+TDecompress (
+ IN VOID *Source,
+ IN OUT VOID *Destination,
+ IN OUT VOID *Scratch,
+ IN UINT32 Version
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/EfiVfr.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/EfiVfr.h
new file mode 100644
index 00000000..e9d80fe7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/EfiVfr.h
@@ -0,0 +1,44 @@
+/** @file
+Defines and prototypes for the UEFI VFR compiler internal use.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFIVFR_H_
+#define _EFIVFR_H_
+
+#include "Common/UefiBaseTypes.h"
+#include "Common/UefiInternalFormRepresentation.h"
+#include "Common/MdeModuleHii.h"
+
+#define MAX_VFR_LINE_LEN 4096
+
+#define EFI_IFR_MAX_LENGTH 0xFF
+#define MAX_IFR_EXPRESSION_DEPTH 0x9
+
+#define EFI_VARSTORE_ID_INVALID 0
+#define EFI_VAROFFSET_INVALID 0xFFFF
+#define EFI_VARSTORE_ID_START 0x20
+#define EFI_STRING_ID_INVALID 0x0
+#define EFI_IMAGE_ID_INVALID 0xFFFF
+
+#define EFI_IFR_MAX_DEFAULT_TYPE 0x10
+
+typedef enum {
+ QUESTION_NORMAL,
+ QUESTION_DATE,
+ QUESTION_TIME,
+ QUESTION_REF,
+} EFI_QUESION_TYPE;
+
+typedef enum {
+ EQUAL,
+ LESS_EQUAL,
+ LESS_THAN,
+ GREATER_THAN,
+ GREATER_EQUAL
+} EFI_COMPARE_TYPE;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/GNUmakefile
new file mode 100644
index 00000000..5cf434ae
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/GNUmakefile
@@ -0,0 +1,80 @@
+## @file
+# GNU/Linux makefile for 'VfrCompile' module build.
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+MAKEROOT ?= ..
+
+APPNAME = VfrCompile
+
+LIBS = -lCommon
+
+TOOL_INCLUDE = -I Pccts/h
+
+#OBJECTS = VfrSyntax.o VfrServices.o DLGLexer.o EfiVfrParser.o ATokenBuffer.o DLexerBase.o AParser.o
+OBJECTS = AParser.o DLexerBase.o ATokenBuffer.o EfiVfrParser.o VfrLexer.o VfrSyntax.o \
+ VfrFormPkg.o VfrError.o VfrUtilityLib.o VfrCompiler.o
+ifeq ($(CXX), llvm)
+VFR_CPPFLAGS = -Wno-deprecated-register -DPCCTS_USE_NAMESPACE_STD $(BUILD_CPPFLAGS)
+else
+VFR_CPPFLAGS = -DPCCTS_USE_NAMESPACE_STD $(BUILD_CPPFLAGS)
+endif
+# keep BUILD_OPTFLAGS last
+VFR_CXXFLAGS = $(BUILD_OPTFLAGS)
+
+# keep EXTRA_LDFLAGS last
+VFR_LFLAGS = $(EXTRA_LDFLAGS)
+
+LINKER = $(BUILD_CXX)
+
+EXTRA_CLEAN_OBJECTS = EfiVfrParser.cpp EfiVfrParser.h VfrParser.dlg VfrTokens.h VfrLexer.cpp VfrLexer.h VfrSyntax.cpp tokens.h
+
+MAKEROOT ?= ../..
+
+include $(MAKEROOT)/Makefiles/header.makefile
+
+APPLICATION = $(MAKEROOT)/bin/$(APPNAME)
+
+.PHONY:all
+all: $(MAKEROOT)/bin $(APPLICATION)
+
+$(APPLICATION): $(OBJECTS)
+ $(LINKER) -o $(APPLICATION) $(VFR_LFLAGS) $(OBJECTS) -L$(MAKEROOT)/libs $(LIBS)
+
+VfrCompiler.o: ../Include/Common/BuildVersion.h
+
+include $(MAKEROOT)/Makefiles/footer.makefile
+
+VfrSyntax.cpp EfiVfrParser.cpp EfiVfrParser.h VfrParser.dlg VfrTokens.h: Pccts/antlr/antlr VfrSyntax.g
+ Pccts/antlr/antlr -CC -e3 -ck 3 -k 2 -fl VfrParser.dlg -ft VfrTokens.h -o . VfrSyntax.g
+
+VfrLexer.cpp VfrLexer.h: Pccts/dlg/dlg VfrParser.dlg
+ Pccts/dlg/dlg -C2 -i -CC -cl VfrLexer -o . VfrParser.dlg
+
+Pccts/antlr/antlr:
+ BIN_DIR='.' $(MAKE) -C Pccts/antlr
+
+Pccts/dlg/dlg:
+ BIN_DIR='.' $(MAKE) -C Pccts/dlg
+
+ATokenBuffer.o: Pccts/h/ATokenBuffer.cpp
+ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@
+
+DLexerBase.o: Pccts/h/DLexerBase.cpp
+ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@
+
+AParser.o: Pccts/h/AParser.cpp
+ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@
+
+VfrSyntax.o: VfrSyntax.cpp
+ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@
+
+clean: localClean
+
+localClean:
+ BIN_DIR='.' $(MAKE) -C Pccts/antlr clean
+ BIN_DIR='.' $(MAKE) -C Pccts/dlg clean
+ rm -f $(EXTRA_CLEAN_OBJECTS)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile
new file mode 100644
index 00000000..24c3dbd6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile
@@ -0,0 +1,50 @@
+## @file
+# Windows makefile for 'VfrCompile' module build.
+#
+# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+CPPFLAGS = $(CPPFLAGS) /WX /D PCCTS_USE_NAMESPACE_STD
+APPNAME = VfrCompile
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = AParser.obj DLexerBase.obj ATokenBuffer.obj \
+ EfiVfrParser.obj VfrLexer.obj VfrSyntax.obj \
+ VfrFormPkg.obj VfrError.obj VfrUtilityLib.obj VfrCompiler.obj
+
+INC = $(INC) -I $(BASE_TOOLS_PATH)\Source\C\VfrCompile\Pccts\h
+
+!INCLUDE ..\Makefiles\ms.app
+
+VfrSyntax.cpp EfiVfrParser.cpp EfiVfrParser.h VfrParser.dlg VfrTokens.h: VfrSyntax.g
+ pushd . & cd Pccts & $(MAKE) & popd
+ antlr -CC -e3 -ck 3 -k 2 -fl VfrParser.dlg -ft VfrTokens.h -o . VfrSyntax.g
+# pushd . & cd Pccts & $(MAKE) clean
+
+VfrLexer.cpp VfrLexer.h: VfrParser.dlg
+ dlg -C2 -i -CC -cl VfrLexer -o . VfrParser.dlg
+
+ATokenBuffer.obj: Pccts\h\ATokenBuffer.cpp
+ $(CXX) -c $(CPPFLAGS) $(INC) $? -Fo$@
+
+DLexerBase.obj: Pccts\h\DLexerBase.cpp
+ $(CXX) -c $(CPPFLAGS) $(INC) $? -Fo$@
+
+AParser.obj: Pccts\h\AParser.cpp
+ $(CXX) -c $(CPPFLAGS) $(INC) $? -Fo$@
+
+EXTRA_CLEAN_OBJECTS = VfrParser.dlg EfiVfrParser.cpp EfiVfrParser.h \
+ VfrLexer.cpp VfrLexer.h \
+ VfrSyntax.cpp VfrTokens.h
+
+clean: localClean
+cleanall: localClean localCleanall
+
+localClean:
+ -DEL $(EXTRA_CLEAN_OBJECTS)
+
+localCleanall:
+ pushd . & cd Pccts & $(MAKE) cleanall & popd
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile.kmk
new file mode 100644
index 00000000..821ed919
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Makefile.kmk
@@ -0,0 +1,155 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI VfrCompile build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += VfrCompile
+VfrCompile_TEMPLATE = VBoxEfiBldProg
+VfrCompile_DEFS = PCCTS_USE_NAMESPACE_STD __USE_PROTOS
+#
+# Workaround a crash in the release version of VfrCompile on Windos
+# when parsing Tcg2Config.vfr, no time to investigate that deeper right now...
+#
+if "$(KBUILD_TARGET)" == "win" && "$(KBUILD_TYPE)" == "release"
+ VfrCompile_CXXFLAGS += -noover -Od
+endif
+VfrCompile_INCS = \
+ . \
+ Pccts/h \
+ $(VfrCompile_0_OUTDIR)
+VfrCompile_SOURCES = \
+ VfrCompiler.cpp \
+ VfrFormPkg.cpp \
+ VfrError.cpp \
+ VfrUtilityLib.cpp \
+ Pccts/h/AParser.cpp \
+ Pccts/h/DLexerBase.cpp \
+ Pccts/h/ATokenBuffer.cpp \
+ $(VfrCompile_0_OUTDIR)/VfrSyntax.cpp \
+ $(VfrCompile_0_OUTDIR)/EfiVfrParser.cpp \
+ $(VfrCompile_0_OUTDIR)/VfrLexer.cpp
+VfrCompile_INTERMEDIATES = \
+ $(VfrCompile_0_OUTDIR)/VfrTokens.h \
+ $(VfrCompile_0_OUTDIR)/VfrLexer.h \
+ $(VfrCompile_0_OUTDIR)/EfiVfrParser.h
+VfrCompile_CLEAN = \
+ $(VfrCompile_0_OUTDIR)/VfrSyntax.cpp \
+ $(VfrCompile_0_OUTDIR)/EfiVfrParser.cpp \
+ $(VfrCompile_0_OUTDIR)/VfrLexer.cpp
+
+$$(VfrCompile_0_OUTDIR)/VfrSyntax.cpp \
++ $$(VfrCompile_0_OUTDIR)/EfiVfrParser.cpp \
++ $$(VfrCompile_0_OUTDIR)/EfiVfrParser.h \
++ $$(VfrCompile_0_OUTDIR)/VfrParser.dlg \
++ $$(VfrCompile_0_OUTDIR)/VfrTokens.h: \
+ $$(antlr_1_TARGET) \
+ $(PATH_SUB_CURRENT)/VfrSyntax.g
+ $(antlr_1_TARGET) -CC -e3 -ck 3 -k 2 \
+ -fl $(dir $@)/VfrParser.dlg \
+ -ft $(dir $@)/VfrTokens.h \
+ -o $(dir $@) \
+ $(VfrCompile_DEFPATH)/VfrSyntax.g
+
+$$(VfrCompile_0_OUTDIR)/VfrLexer.cpp \
++ $$(VfrCompile_0_OUTDIR)/VfrLexer.h: \
+ $$(dlg_1_TARGET) \
+ $$(VfrCompile_0_OUTDIR)/VfrParser.dlg
+ $(dlg_1_TARGET) -C2 -i -CC -cl VfrLexer \
+ -o $(dir $@) \
+ $(VfrCompile_0_OUTDIR)/VfrParser.dlg
+
+
+#
+# Antlr parser generator from the Purdue Compiler Construction Tool Set.
+#
+BLDPROGS += antlr
+antlr_TEMPLATE = VBoxEfiBldProg
+antlr_DEFS = \
+ USER_ZZSYN \
+ ZZLEXBUFSIZE=65536 \
+ __USE_PROTOS
+antlr_INCS = \
+ Pccts/antlr \
+ Pccts/support/set \
+ Pccts/h
+antlr_SOURCES = \
+ Pccts/antlr/antlr.c \
+ Pccts/antlr/bits.c \
+ Pccts/antlr/build.c \
+ Pccts/antlr/egman.c \
+ Pccts/antlr/err.c \
+ Pccts/antlr/fcache.c \
+ Pccts/antlr/fset.c \
+ Pccts/antlr/fset2.c \
+ Pccts/antlr/gen.c \
+ Pccts/antlr/globals.c \
+ Pccts/antlr/hash.c \
+ Pccts/antlr/lex.c \
+ Pccts/antlr/main.c \
+ Pccts/antlr/misc.c \
+ Pccts/antlr/mrhoist.c \
+ Pccts/antlr/pred.c \
+ Pccts/antlr/scan.c \
+ Pccts/support/set/set.c
+
+#
+# DFA lexical analyzer generator from the Purdue Compiler Construction Tool Set.
+#
+BLDPROGS += dlg
+dlg_TEMPLATE = VBoxEfiBldProg
+dlg_DEFS = \
+ USER_ZZSYN \
+ ZZLEXBUFSIZE=65536 \
+ __USE_PROTOS
+dlg_INCS = \
+ Pccts/dlg \
+ Pccts/support/set \
+ Pccts/h
+dlg_SOURCES = \
+ Pccts/dlg/automata.c \
+ Pccts/dlg/dlg_a.c \
+ Pccts/dlg/dlg_p.c \
+ Pccts/dlg/err.c \
+ Pccts/dlg/main.c \
+ Pccts/dlg/output.c \
+ Pccts/dlg/relabel.c \
+ Pccts/dlg/support.c \
+ Pccts/support/set/set.c
+
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_131.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_131.txt
new file mode 100644
index 00000000..0888cbf1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_131.txt
@@ -0,0 +1,522 @@
+CHANGES FROM 1.31
+
+This file contains the migration of PCCTS from 1.31 in the order that
+changes were made. 1.32b7 is the last beta before full 1.32.
+Terence Parr, Parr Research Corporation 1995.
+
+
+======================================================================
+1.32b1
+Added Russell Quong to banner, changed banner for output slightly
+Fixed it so that you have before / after actions for C++ in class def
+Fixed bug in optimizer that made it sometimes forget to set internal
+ token pointers. Only showed up when a {...} was in the "wrong spot".
+
+======================================================================
+1.32b2
+Added fixes by Dave Seidel for PC compilers in 32 bit mode (config.h
+and set.h).
+
+======================================================================
+1.32b3
+Fixed hideous bug in code generator for wildcard and for ~token op.
+
+from Dave Seidel
+
+ Added pcnames.bat
+ 1. in antlr/main.c: change strcasecmp() to stricmp()
+
+ 2. in dlg/output.c: use DLEXER_C instead on "DLexer.C"
+
+ 3. in h/PBlackBox.h: use <iostream.h> instead of <stream.h>
+
+======================================================================
+1.32b4
+When the -ft option was used, any path prefix screwed up
+the gate on the .h files
+
+Fixed yet another bug due to the optimizer.
+
+The exception handling thing was a bit wacko:
+
+a : ( A B )? A B
+ | A C
+ ;
+ exception ...
+
+caused an exception if "A C" was the input. In other words,
+it found that A C didn't match the (A B)? pred and caused
+an exception rather than trying the next alt. All I did
+was to change the zzmatch_wsig() macros.
+
+Fixed some problems in gen.c relating to the name of token
+class bit sets in the output.
+
+Added the tremendously cool generalized predicate. For the
+moment, I'll give this bried description.
+
+a : <<predicate>>? blah
+ | foo
+ ;
+
+This implies that (assuming blah and foo are syntactically
+ambiguous) "predicate" indicates the semantic validity of
+applying "blah". If "predicate" is false, "foo" is attempted.
+
+Previously, you had to say:
+
+a : <<LA(1)==ID ? predicate : 1>>? ID
+ | ID
+ ;
+
+Now, you can simply use "predicate" without the ?: operator
+if you turn on ANTLR command line option: "-prc on". This
+tells ANTLR to compute that all by itself. It computes n
+tokens of lookahead where LT(n) or LATEXT(n) is the farthest
+ahead you look.
+
+If you give a predicate using "-prc on" that is followed
+by a construct that can recognize more than one n-sequence,
+you will get a warning from ANTLR. For example,
+
+a : <<isTypeName(LT(1)->getText())>>? (ID|INT)
+ ;
+
+This is wrong because the predicate will be applied to INTs
+as well as ID's. You should use this syntax to make
+the predicate more specific:
+
+a : (ID)? => <<isTypeName(LT(1)->getText())>>? (ID|INT)
+ ;
+
+which says "don't apply the predicate unless ID is the
+current lookahead context".
+
+You cannot currently have anything in the "(context)? =>"
+except sequences such as:
+
+( LPAREN ID | LPAREN SCOPE )? => <<pred>>?
+
+I haven't tested this THAT much, but it does work for the
+C++ grammar.
+
+======================================================================
+1.32b5
+
+Added getLine() to the ANTLRTokenBase and DLGBasedToken classes
+left line() for backward compatibility.
+----
+Removed SORCERER_TRANSFORM from the ast.h stuff.
+-------
+Fixed bug in code gen of ANTLR such that nested syn preds work more
+efficiently now. The ANTLRTokenBuffer was getting very large
+with nested predicates.
+------
+Memory leak is now gone from ANTLRTokenBuf; all tokens are deleted.
+For backward compatibility reasons, you have to say parser->deleteTokens()
+or mytokenbuffer->deleteTokens() but later it will be the default mode.
+Say this after the parser is constructed. E.g.,
+
+ ParserBlackBox<DLGLexer, MyParser, ANTLRToken> p(stdin);
+ p.parser()->deleteTokens();
+ p.parser()->start_symbol();
+
+
+==============================
+1.32b6
+
+Changed so that deleteTokens() will do a delete ((ANTLRTokenBase *))
+on the ptr. This gets the virtual destructor.
+
+Fixed some weird things in the C++ header files (a few return types).
+
+Made the AST routines correspond to the book and SORCERER stuff.
+
+New token stuff: See testcpp/14/test.g
+
+ANTLR accepts a #pragma gc_tokens which says
+[1] Generate label = copy(LT(1)) instead of label=LT(1) for
+ all labeled token references.
+[2] User now has to define ANTLRTokenPtr (as a class or a typedef
+ to just a pointer) as well as the ANTLRToken class itself.
+ See the example.
+
+To delete tokens in token buffer, use deleteTokens() message on parser.
+
+ All tokens that fall off the ANTLRTokenBuffer get deleted
+ which is what currently happens when deleteTokens() message
+ has been sent to token buffer.
+
+We always generate ANTLRTokenPtr instead of 'ANTLRToken *' now.
+Then if no pragma set, ANTLR generates a
+
+ class ANTLRToken;
+ typedef ANTLRToken *ANTLRTokenPtr;
+
+in each file.
+
+Made a warning for x:rule_ref <<$x>>; still no warning for $i's, however.
+class BB {
+
+a : x:b y:A <<$x
+$y>>
+ ;
+
+b : B;
+
+}
+generates
+Antlr parser generator Version 1.32b6 1989-1995
+test.g, line 3: error: There are no token ptrs for rule references: '$x'
+
+===================
+1.32b7:
+
+[With respect to token object garbage collection (GC), 1.32b7
+ backtracks from 1.32b6, but results in better and less intrusive GC.
+ This is the last beta version before full 1.32.]
+
+BIGGEST CHANGES:
+
+o The "#pragma gc_tokens" is no longer used.
+
+o .C files are now .cpp files (hence, makefiles will have to
+ be changed; or you can rerun genmk). This is a good move,
+ but causes some backward incompatibility problems. You can
+ avoid this by changing CPP_FILE_SUFFIX to ".C" in pccts/h/config.h.
+
+o The token object class hierarchy has been flattened to include
+ only three classes: ANTLRAbstractToken, ANTLRCommonToken, and
+ ANTLRCommonNoRefCountToken. The common token now does garbage
+ collection via ref counting.
+
+o "Smart" pointers are now used for garbage collection. That is,
+ ANTLRTokenPtr is used instead of "ANTLRToken *".
+
+o The antlr.1 man page has been cleaned up slightly.
+
+o The SUN C++ compiler now complains less about C++ support code.
+
+o Grammars which subclass ANTLRCommonToken must wrap all token
+ pointer references in mytoken(token_ptr). This is the only
+ serious backward incompatibility. See below.
+
+
+MINOR CHANGES:
+
+--------------------------------------------------------
+1 deleteTokens()
+
+The deleteTokens() message to the parser or token buffer has been changed
+to one of:
+
+ void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); }
+ void garbageCollectTokens() { inputTokens->garbageCollectTokens(); }
+
+The token buffer deletes all non-referenced tokens by default now.
+
+--------------------------------------------------------
+2 makeToken()
+
+The makeToken() message returns a new type. The function should look
+like:
+
+ virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
+ ANTLRChar *txt,
+ int line)
+ {
+ ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt);
+ t->setLine(line);
+ return t;
+ }
+
+--------------------------------------------------------
+3 TokenType
+
+Changed TokenType-> ANTLRTokenType (often forces changes in AST defs due
+to #[] constructor called to AST(tokentype, string)).
+
+--------------------------------------------------------
+4 AST()
+
+You must define AST(ANTLRTokenPtr t) now in your AST class definition.
+You might also have to include ATokPtr.h above the definition; e.g.,
+if AST is defined in a separate file, such as AST.h, it's a good idea
+to include ATOKPTR_H (ATokPtr.h). For example,
+
+ #include ATOKPTR_H
+ class AST : public ASTBase {
+ protected:
+ ANTLRTokenPtr token;
+ public:
+ AST(ANTLRTokenPtr t) { token = t; }
+ void preorder_action() {
+ char *s = token->getText();
+ printf(" %s", s);
+ }
+ };
+
+Note the use of smart pointers rather than "ANTLRToken *".
+
+--------------------------------------------------------
+5 SUN C++
+
+From robertb oakhill.sps.mot.com Bob Bailey. Changed ANTLR C++ output
+to avoid an error in Sun C++ 3.0.1. Made "public" return value
+structs created to hold multiple return values public.
+
+--------------------------------------------------------
+6 genmk
+
+Fixed genmk so that target List.* is not included anymore. It's
+called SList.* anyway.
+
+--------------------------------------------------------
+7 \r vs \n
+
+Scott Vorthmann <vorth cmu.edu> fixed antlr.g in ANTLR so that \r
+is allowed as the return character as well as \n.
+
+--------------------------------------------------------
+8 Exceptions
+
+Bug in exceptions attached to labeled token/tokclass references. Didn't gen
+code for exceptions. This didn't work:
+
+a : "help" x:ID
+ ;
+ exception[x]
+ catch MismatchedToken : <<printf("eh?\n");>>
+
+Now ANTLR generates (which is kinda big, but necessary):
+
+ if ( !_match_wsig(ID) ) {
+ if ( guessing ) goto fail;
+ _signal=MismatchedToken;
+ switch ( _signal ) {
+ case MismatchedToken :
+ printf("eh?\n");
+ _signal = NoSignal;
+ break;
+ default :
+ goto _handler;
+ }
+ }
+
+which implies that you can recover and continue parsing after a missing/bad
+token reference.
+
+--------------------------------------------------------
+9 genmk
+
+genmk now correctly uses config file for CPP_FILE_SUFFIX stuff.
+
+--------------------------------------------------------
+10 general cleanup / PURIFY
+
+Anthony Green <green vizbiz.com> suggested a bunch of good general
+clean up things for the code; he also suggested a few things to
+help out the "PURIFY" memory allocation checker.
+
+--------------------------------------------------------
+11 $-variable references.
+
+Manuel ORNATO indicated that a $-variable outside of a rule caused
+ANTLR to crash. I fixed this.
+
+12 Tom Moog suggestion
+
+Fail action of semantic predicate needs "{}" envelope. FIXED.
+
+13 references to LT(1).
+
+I have enclosed all assignments such as:
+
+ _t22 = (ANTLRTokenPtr)LT(1);
+
+in "if ( !guessing )" so that during backtracking the reference count
+for token objects is not increased.
+
+
+TOKEN OBJECT GARBAGE COLLECTION
+
+1 INTRODUCTION
+
+The class ANTLRCommonToken is now garbaged collected through a "smart"
+pointer called ANTLRTokenPtr using reference counting. Any token
+object not referenced by your grammar actions is destroyed by the
+ANTLRTokenBuffer when it must make room for more token objects.
+Referenced tokens are then destroyed in your parser when local
+ANTLRTokenPtr objects are deleted. For example,
+
+a : label:ID ;
+
+would be converted to something like:
+
+void yourclass::a(void)
+{
+ zzRULE;
+ ANTLRTokenPtr label=NULL; // used to be ANTLRToken *label;
+ zzmatch(ID);
+ label = (ANTLRTokenPtr)LT(1);
+ consume();
+ ...
+}
+
+When the "label" object is destroyed (it's just a pointer to your
+input token object LT(1)), it decrements the reference count on the
+object created for the ID. If the count goes to zero, the object
+pointed by label is deleted.
+
+To correctly manage the garbage collection, you should use
+ANTLRTokenPtr instead of "ANTLRToken *". Most ANTLR support code
+(visible to the user) has been modified to use the smart pointers.
+
+***************************************************************
+Remember that any local objects that you create are not deleted when a
+lonjmp() is executed. Unfortunately, the syntactic predicates (...)?
+use setjmp()/longjmp(). There are some situations when a few tokens
+will "leak".
+***************************************************************
+
+2 DETAILS
+
+o The default is to perform token object garbage collection.
+ You may use parser->noGarbageCollectTokens() to turn off
+ garbage collection.
+
+
+o The type ANTLRTokenPtr is always defined now (automatically).
+ If you do not wish to use smart pointers, you will have to
+ redefined ANTLRTokenPtr by subclassing, changing the header
+ file or changing ANTLR's code generation (easy enough to
+ do in gen.c).
+
+o If you don't use ParserBlackBox, the new initialization sequence is:
+
+ ANTLRTokenPtr aToken = new ANTLRToken;
+ scan.setToken(mytoken(aToken));
+
+ where mytoken(aToken) gets an ANTLRToken * from the smart pointer.
+
+o Define C++ preprocessor symbol DBG_REFCOUNTTOKEN to see a bunch of
+ debugging stuff for reference counting if you suspect something.
+
+
+3 WHY DO I HAVE TO TYPECAST ALL MY TOKEN POINTERS NOW??????
+
+If you subclass ANTLRCommonToken and then attempt to refer to one of
+your token members via a token pointer in your grammar actions, the
+C++ compiler will complain that your token object does not have that
+member. For example, if you used to do this
+
+<<
+class ANTLRToken : public ANTLRCommonToken {
+ int muck;
+ ...
+};
+>>
+
+class Foo {
+a : t:ID << t->muck = ...; >> ;
+}
+
+Now, you must do change the t->muck reference to:
+
+a : t:ID << mytoken(t)->muck = ...; >> ;
+
+in order to downcast 't' to be an "ANTLRToken *" not the
+"ANTLRAbstractToken *" resulting from ANTLRTokenPtr::operator->().
+The macro is defined as:
+
+/*
+ * Since you cannot redefine operator->() to return one of the user's
+ * token object types, we must down cast. This is a drag. Here's
+ * a macro that helps. template: "mytoken(a-smart-ptr)->myfield".
+ */
+#define mytoken(tp) ((ANTLRToken *)(tp.operator->()))
+
+You have to use macro mytoken(grammar-label) now because smart
+pointers are not specific to a parser's token objects. In other
+words, the ANTLRTokenPtr class has a pointer to a generic
+ANTLRAbstractToken not your ANTLRToken; the ANTLR support code must
+use smart pointers too, but be able to work with any kind of
+ANTLRToken. Sorry about this, but it's C++'s fault not mine. Some
+nebulous future version of the C++ compilers should obviate the need
+to downcast smart pointers with runtime type checking (and by allowing
+different return type of overridden functions).
+
+A way to have backward compatible code is to shut off the token object
+garbage collection; i.e., use parser->noGarbageCollectTokens() and
+change the definition of ANTLRTokenPtr (that's why you get source code
+<wink>).
+
+
+PARSER EXCEPTION HANDLING
+
+I've noticed some weird stuff with the exception handling. I intend
+to give this top priority for the "book release" of ANTLR.
+
+==========
+1.32 Full Release
+
+o Changed Token class hierarchy to be (Thanks to Tom Moog):
+
+ ANTLRAbstractToken
+ ANTLRRefCountToken
+ ANTLRCommonToken
+ ANTLRNoRefCountCommonToken
+
+o Added virtual panic() to ANTLRAbstractToken. Made ANTLRParser::panic()
+ virtual also.
+
+o Cleaned up the dup() stuff in AST hierarchy to use shallowCopy() to
+ make node copies. John Farr at Medtronic suggested this. I.e.,
+ if you want to use dup() with either ANTLR or SORCERER or -transform
+ mode with SORCERER, you must defined shallowCopy() as:
+
+ virtual PCCTS_AST *shallowCopy()
+ {
+ return new AST;
+ p->setDown(NULL);
+ p->setRight(NULL);
+ return p;
+ }
+
+ or
+
+ virtual PCCTS_AST *shallowCopy()
+ {
+ return new AST(*this);
+ }
+
+ if you have defined a copy constructor such as
+
+ AST(const AST &t) // shallow copy constructor
+ {
+ token = t.token;
+ iconst = t.iconst;
+ setDown(NULL);
+ setRight(NULL);
+ }
+
+o Added a warning with -CC and -gk are used together. This is broken,
+ hence a warning is appropriate.
+
+o Added warning when #-stuff is used w/o -gt option.
+
+o Updated MPW installation.
+
+o "Miller, Philip W." <MILLERPW f1groups.fsd.jhuapl.edu> suggested
+ that genmk be use RENAME_OBJ_FLAG RENAME_EXE_FLAG instead of
+ hardcoding "-o" in genmk.c.
+
+o made all exit() calls use EXIT_SUCCESS or EXIT_FAILURE.
+
+===========================================================================
+1.33
+
+EXIT_FAILURE and EXIT_SUCCESS were not always defined. I had to modify
+a bunch of files to use PCCTS_EXIT_XXX, which forces a new version. Sorry
+about that.
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133.txt
new file mode 100644
index 00000000..a9e40a12
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133.txt
@@ -0,0 +1,2448 @@
+=======================================================================
+List of Implemented Fixes and Changes for Maintenance Releases of PCCTS
+=======================================================================
+
+ DISCLAIMER
+
+ The software and these notes are provided "as is". They may include
+ typographical or technical errors and their authors disclaims all
+ liability of any kind or nature for damages due to error, fault,
+ defect, or deficiency regardless of cause. All warranties of any
+ kind, either express or implied, including, but not limited to, the
+ implied warranties of merchantability and fitness for a particular
+ purpose are disclaimed.
+
+
+ -------------------------------------------------------
+ Note: Items #153 to #1 are now in a separate file named
+ CHANGES_FROM_133_BEFORE_MR13.txt
+ -------------------------------------------------------
+
+#312. (Changed in MR33) Bug caused by change #299.
+
+ In change #299 a warning message was suppressed when there was
+ no LT(1) in a semantic predicate and max(k,ck) was 1. The
+ changed caused the code which set a default predicate depth for
+ the semantic predicate to be left as 0 rather than set to 1.
+
+ This manifested as an error at line #1559 of mrhost.c
+
+ Reported by Peter Dulimov.
+
+#311. (Changed in MR33) Added sorcer/lib to Makefile.
+
+ Reported by Dale Martin.
+
+#310. (Changed in MR32) In C mode zzastPush was spelled zzastpush in one case.
+
+ Reported by Jean-Claude Durand
+
+#309. (Changed in MR32) Renamed baseName because of VMS name conflict
+
+ Renamed baseName to pcctsBaseName to avoid library name conflict with
+ VMS library routine. Reported by Jean-François PIÉRONNE.
+
+#308. (Changed in MR32) Used "template" as name of formal in C routine
+
+ In astlib.h routine ast_scan a formal was named "template". This caused
+ problems when the C code was compiled with a C++ compiler. Reported by
+ Sabyasachi Dey.
+
+#307. (Changed in MR31) Compiler dependent bug in function prototype generation
+
+ The code which generated function prototypes contained a bug which
+ was compiler/optimization dependent. Under some circumstance an
+ extra character would be included in portions of a function prototype.
+
+ Reported by David Cook.
+
+#306. (Changed in MR30) Validating predicate following a token
+
+ A validating predicate which immediately followed a token match
+ consumed the token after the predicate rather than before. Prior
+ to this fix (in the following example) isValidTimeScaleValue() in
+ the predicate would test the text for TIMESCALE rather than for
+ NUMBER:
+
+ time_scale :
+ TIMESCALE
+ <<isValidTimeScaleValue(LT(1)->getText())>>?
+ ts:NUMBER
+ ( us:MICROSECOND << tVal = ...>>
+ | ns:NANOSECOND << tVal = ... >>
+ )
+
+ Reported by Adalbert Perbandt.
+
+#305. (Changed in MR30) Alternatives with guess blocks inside (...)* blocks.
+
+ In MR14 change #175 fixed a bug in the prediction expressions for guess
+ blocks which were of the form (alpha)? beta. Unfortunately, this
+ resulted in a new bug as exemplified by the example below, which computed
+ the first set for r as {B} rather than {B C}:
+
+ r : ( (A)? B
+ | C
+ )*
+
+ This example doesn't make any sense as A is not a prefix of B, but it
+ illustrates the problem. This bug did not appear for:
+
+ r : ( (A)?
+ | C
+ )*
+
+ because it does not use the (alpha)? beta form.
+
+ Item #175 fixed an asymmetry in ambiguity messages for the following
+ constructs which appear to have identical ambiguities (between repeating
+ the loop vs. exiting the loop). MR30 retains this fix, but the implementation
+ is slightly different.
+
+ r_star : ( (A B)? )* A ;
+ r_plus : ( (A B)? )+ A ;
+
+ Reported by Arpad Beszedes (beszedes inf.u-szeged.hu).
+
+#304. (Changed in MR30) Crash when mismatch between output value counts.
+
+ For a rule such as:
+
+ r1 : r2>[i,j];
+ r2 >[int i, int j] : A;
+
+ If there were extra actuals for the reference to rule r2 from rule r1
+ there antlr would crash. This bug was introduced by change #276.
+
+ Reported by Sinan Karasu.
+
+#303. (Changed in MR30) DLGLexerBase::replchar
+
+ DLGLexerBase::replchar and the C mode routine zzreplchar did not work
+ properly when the new character was 0.
+
+ Reported with fix by Philippe Laporte
+
+#302. (Changed in MR28) Fix significant problems in initial release of MR27.
+
+#301. (Changed in MR27) Default tab stops set to 2 spaces.
+
+ To have antlr generate true tabs rather than spaces, use "antlr -tab 0".
+ To generate 4 spaces per tab stop use "antlr -tab 4"
+
+#300. (Changed in MR27)
+
+ Consider the following methods of constructing an AST from ID:
+
+ rule1!
+ : id:ID << #0 = #[id]; >> ;
+
+ rule2!
+ : id:ID << #0 = #id; >> ;
+
+ rule3
+ : ID ;
+
+ rule4
+ : id:ID << #0 = #id; >> ;
+
+ For rule_2, the AST corresponding to id would always be NULL. This
+ is because the user explicitly suppressed AST construction using the
+ "!" operator on the rule. In MR27 the use of an AST expression
+ such as #id overrides the "!" operator and forces construction of
+ the AST.
+
+ This fix does not apply to C mode ASTs when the ASTs are referenced
+ using numbers rather than symbols.
+
+ For C mode, this requires that the (optional) function/macro zzmk_ast
+ be defined. This functions copies information from an attribute into
+ a previously allocated AST.
+
+ Reported by Jan Langer (jan langernetz.de)
+
+#299. (Changed in MR27) Don't warn if k=1 and semantic predicate missing LT(i)
+
+ If a semantic does not have a reference to LT(i) or (C mode LATEXT(i))
+ then pccts doesn't know how many lookahead tokens to use for context.
+ However, if max(k,ck) is 1 then there is really only one choice and
+ the warning is unnecessary.
+
+#298. (Changed in MR27) Removed "register" for lastpos in dlgauto.c zzgettok
+
+#297. (Changed in MR27) Incorrect prototypes when used with classic C
+
+ There were a number of errors in function headers when antlr was
+ built with compilers that do not have __STDC__ or __cplusplus set.
+
+ The functions which have variable length argument lists now use
+ PCCTS_USE_STDARG rather than __USE_PROTOTYPES__ to determine
+ whether to use stdargs or varargs.
+
+#296. (Changed in MR27) Complex return types in rules.
+
+ The following return type was not properly handled when
+ unpacking a struct with containing multiple return values:
+
+ rule > [int i, IIR_Bool (IIR_Decl::*constraint)()] : ...
+
+ Instead of using "constraint", the program got lost and used
+ an empty string.
+
+ Reported by P.A. Wilsey.
+
+#295. (Changed in MR27) Extra ";" following zzGUESS_DONE sometimes.
+
+ Certain constructs with guess blocks in MR23 led to extra ";"
+ preceding the "else" clause of an "if".
+
+ Reported by P.A. Wilsey.
+
+#294. (Changed in MR27) Infinite loop in antlr for nested blocks
+
+ An oversight in detecting an empty alternative sometimes led
+ to an infinite loop in antlr when it encountered a rule with
+ nested blocks and guess blocks.
+
+ Reported by P.A. Wilsey.
+
+#293. (Changed in MR27) Sorcerer optimization of _t->type()
+
+ Sorcerer generated code may contain many calls to _t->type() in a
+ single statement. This change introduces a temporary variable
+ to eliminate unnecesary function calls.
+
+ Change implemented by Tom Molteno (tim videoscript.com).
+
+#292. (Changed in MR27)
+
+ WARNING: Item #267 changes the signature of methods in the AST class.
+
+ **** Be sure to revise your AST functions of the same name ***
+
+#291. (Changed in MR24)
+
+ Fix to serious code generation error in MR23 for (...)+ block.
+
+#290. (Changed in MR23)
+
+ Item #247 describes a change in the way {...} blocks handled
+ an error. Consider:
+
+ r1 : {A} b ;
+ b : B;
+
+ with input "C".
+
+ Prior to change #247, the error would resemble "expected B -
+ found C". This is correct but incomplete, and therefore
+ misleading. In #247 it was changed to "expected A, B - found
+ C". This was fine, except for users of parser exception
+ handling because the exception was generated in the epilogue
+ for {...} block rather than in rule b. This made it difficult
+ for users of parser exception handling because B was not
+ expected in that context. Those not using parser exception
+ handling didn't notice the difference.
+
+ The current change restores the behavior prior to #247 when
+ parser exceptions are present, but retains the revised behavior
+ otherwise. This change should be visible only when exceptions
+ are in use and only for {...} blocks and sub-blocks of the form
+ (something|something | something | epsilon) where epsilon represents
+ an empty production and it is the last alternative of a sub-block.
+ In contrast, (something | epsilon | something) should generate the
+ same code as before, even when exceptions are used.
+
+ Reported by Philippe Laporte (philippe at transvirtual.com).
+
+#289. (Changed in MR23) Bug in matching complement of a #tokclass
+
+ Prior to MR23 when a #tokclass was matched in both its complemented form
+ and uncomplemented form, the bit set generated for its first use was used
+ for both cases. However, the prediction expression was correctly computed
+ in both cases. This meant that the second case would never be matched
+ because, for the second appearance, the prediction expression and the
+ set to be matched would be complements of each other.
+
+ Consider:
+
+ #token A "a"
+ #token B "b"
+ #token C "c"
+ #tokclass AB {A B}
+
+ r1 : AB /* alt 1x */
+ | ~AB /* alt 1y */
+ ;
+
+ Prior to MR23, this resulted in alternative 1y being unreachable. Had it
+ been written:
+
+ r2 : ~AB /* alt 2x */
+ : AB /* alt 2y */
+
+ then alternative 2y would have become unreachable.
+
+ This bug was only for the case of complemented #tokclass. For complemented
+ #token the proper code was generated.
+
+#288. (Changed in MR23) #errclass not restricted to choice points
+
+ The #errclass directive is supposed to allow a programmer to define
+ print strings which should appear in syntax error messages as a replacement
+ for some combinations of tokens. For instance:
+
+ #errclass Operator {PLUS MINUS TIMES DIVIDE}
+
+ If a syntax message includes all four of these tokens, and there is no
+ "better" choice of error class, the word "Operator" will be used rather
+ than a list of the four token names.
+
+ Prior to MR23 the #errclass definitions were used only at choice points
+ (which call the FAIL macro). In other cases where there was no choice
+ (e.g. where a single token or token class were matched) the #errclass
+ information was not used.
+
+ With MR23 the #errclass declarations are used for syntax error messages
+ when matching a #tokclass, a wildcard (i.e. "*"), or the complement of a
+ #token or #tokclass (e.g. ~Operator).
+
+ Please note that #errclass may now be defined using #tokclass names
+ (see Item #284).
+
+ Reported by Philip A. Wilsey.
+
+#287. (Changed in MR23) Print name for #tokclass
+
+ Item #148 describes how to give a print name to a #token so that,for
+ example, #token ID could have the expression "identifier" in syntax
+ error messages. This has been extended to #tokclass:
+
+ #token ID("identifier") "[a-zA-Z]+"
+ #tokclass Primitive("primitive type")
+ {INT, FLOAT, CHAR, FLOAT, DOUBLE, BOOL}
+
+ This is really a cosmetic change, since #tokclass names do not appear
+ in any error messages.
+
+#286. (Changed in MR23) Makefile change to use of cd
+
+ In cases where a pccts subdirectory name matched a directory identified
+ in a $CDPATH environment variable the build would fail. All makefile
+ cd commands have been changed from "cd xyz" to "cd ./xyz" in order
+ to avoid this problem.
+
+#285. (Changed in MR23) Check for null pointers in some dlg structures
+
+ An invalid regular expression can cause dlg to build an invalid
+ structure to represent the regular expression even while it issues
+ error messages. Additional pointer checks were added.
+
+ Reported by Robert Sherry.
+
+#284. (Changed in MR23) Allow #tokclass in #errclass definitions
+
+ Previously, a #tokclass reference in the definition of an
+ #errclass was not handled properly. Instead of being expanded
+ into the set of tokens represented by the #tokclass it was
+ treated somewhat like an #errclass. However, in a later phase
+ when all #errclass were expanded into the corresponding tokens
+ the #tokclass reference was not expanded (because it wasn't an
+ #errclass). In effect the reference was ignored.
+
+ This has been fixed.
+
+ Problem reported by Mike Dimmick (mike dimmick.demon.co.uk).
+
+#283. (Changed in MR23) Option -tmake invoke's parser's tmake
+
+ When the string #(...) appears in an action antlr replaces it with
+ a call to ASTBase::tmake(...) to construct an AST. It is sometimes
+ useful to change the tmake routine so that it has access to information
+ in the parser - something which is not possible with a static method
+ in an application where they may be multiple parsers active.
+
+ The antlr option -tmake replaces the call to ASTBase::tmake with a call
+ to a user supplied tmake routine.
+
+#282. (Changed in MR23) Initialization error for DBG_REFCOUNTTOKEN
+
+ When the pre-processor symbol DBG_REFCOUNTTOKEN is defined
+ incorrect code is generated to initialize ANTLRRefCountToken::ctor and
+ dtor.
+
+ Fix reported by Sven Kuehn (sven sevenkuehn.de).
+
+#281. (Changed in MR23) Addition of -noctor option for Sorcerer
+
+ Added a -noctor option to suppress generation of the blank ctor
+ for users who wish to define their own ctor.
+
+ Contributed by Jan Langer (jan langernetz.de).
+
+#280. (Changed in MR23) Syntax error message for EOF token
+
+ The EOF token now receives special treatment in syntax error messages
+ because there is no text matched by the eof token. The token name
+ of the eof token is used unless it is "@" - in which case the string
+ "<eof>" is used.
+
+ Problem reported by Erwin Achermann (erwin.achermann switzerland.org).
+
+#279. (Changed in MR23) Exception groups
+
+ There was a bug in the way that exception groups were attached to
+ alternatives which caused problems when there was a block contained
+ in an alternative. For instance, in the following rule;
+
+ statement : IF S { ELSE S }
+ exception ....
+ ;
+
+ the exception would be attached to the {...} block instead of the
+ entire alternative because it was attached, in error, to the last
+ alternative instead of the last OPEN alternative.
+
+ Reported by Ty Mordane (tymordane hotmail.com).
+
+#278. (Changed in MR23) makefile changes
+
+ Contributed by Tomasz Babczynski (faster lab05-7.ict.pwr.wroc.pl).
+
+ The -cfile option is not absolutely needed: when extension of
+ source file is one of the well-known C/C++ extensions it is
+ treated as C/C++ source
+
+ The gnu make defines the CXX variable as the default C++ compiler
+ name, so I added a line to copy this (if defined) to the CCC var.
+
+ Added a -sor option: after it any -class command defines the class
+ name for sorcerer, not for ANTLR. A file extended with .sor is
+ treated as sorcerer input. Because sorcerer can be called multiple
+ times, -sor option can be repeated. Any files and classes (one class
+ per group) after each -sor makes one tree parser.
+
+ Not implemented:
+
+ 1. Generate dependences for user c/c++ files.
+ 2. Support for -sor in c mode not.
+
+ I have left the old genmk program in the directory as genmk_old.c.
+
+#277. (Changed in MR23) Change in macro for failed semantic predicates
+
+ In the past, a semantic predicate that failed generated a call to
+ the macro zzfailed_pred:
+
+ #ifndef zzfailed_pred
+ #define zzfailed_pred(_p) \
+ if (guessing) { \
+ zzGUESS_FAIL; \
+ } else { \
+ something(_p)
+ }
+ #endif
+
+ If a user wished to use the failed action option for semantic predicates:
+
+ rule : <<my_predicate>>? [my_fail_action] A
+ | ...
+
+
+ the code for my_fail_action would have to contain logic for handling
+ the guess part of the zzfailed_pred macro. The user should not have
+ to be aware of the guess logic in writing the fail action.
+
+ The zzfailed_pred has been rewritten to have three arguments:
+
+ arg 1: the stringized predicate of the semantic predicate
+ arg 2: 0 => there is no user-defined fail action
+ 1 => there is a user-defined fail action
+ arg 3: the user-defined fail action (if defined)
+ otherwise a no-operation
+
+ The zzfailed_pred macro is now defined as:
+
+ #ifndef zzfailed_pred
+ #define zzfailed_pred(_p,_hasuseraction,_useraction) \
+ if (guessing) { \
+ zzGUESS_FAIL; \
+ } else { \
+ zzfailed_pred_action(_p,_hasuseraction,_useraction) \
+ }
+ #endif
+
+
+ With zzfailed_pred_action defined as:
+
+ #ifndef zzfailed_pred_action
+ #define zzfailed_pred_action(_p,_hasuseraction,_useraction) \
+ if (_hasUserAction) { _useraction } else { failedSemanticPredicate(_p); }
+ #endif
+
+ In C++ mode failedSemanticPredicate() is a virtual function.
+ In C mode the default action is a fprintf statement.
+
+ Suggested by Erwin Achermann (erwin.achermann switzerland.org).
+
+#276. (Changed in MR23) Addition of return value initialization syntax
+
+ In an attempt to reduce the problems caused by the PURIFY macro I have
+ added new syntax for initializing the return value of rules and the
+ antlr option "-nopurify".
+
+ A rule with a single return argument:
+
+ r1 > [Foo f = expr] :
+
+ now generates code that resembles:
+
+ Foo r1(void) {
+ Foo _retv = expr;
+ ...
+ }
+
+ A rule with more than one return argument:
+
+ r2 > [Foo f = expr1, Bar b = expr2 ] :
+
+ generates code that resembles:
+
+ struct _rv1 {
+ Foo f;
+ Bar b;
+ }
+
+ _rv1 r2(void) {
+ struct _rv1 _retv;
+ _retv.f = expr1;
+ _retv.b = expr2;
+ ...
+ }
+
+ C++ style comments appearing in the initialization list may cause problems.
+
+#275. (Changed in MR23) Addition of -nopurify option to antlr
+
+ A long time ago the PURIFY macro was introduced to initialize
+ return value arguments and get rid of annoying messages from program
+ that checked for uninitialized variables.
+
+ This has caused significant annoyance for C++ users that had
+ classes with virtual functions or non-trivial constructors because
+ it would zero the object, including the pointer to the virtual
+ function table. This could be defeated by redefining
+ the PURIFY macro to be empty, but it was a constant surprise to
+ new C++ users of pccts.
+
+ I would like to remove it, but I fear that some existing programs
+ depend on it and would break. My temporary solution is to add
+ an antlr option -nopurify which disables generation of the PURIFY
+ macro call.
+
+ The PURIFY macro should be avoided in favor of the new syntax
+ for initializing return arguments described in item #275.
+
+ To avoid name clash, the PURIFY macro has been renamed PCCTS_PURIFY.
+
+#274. (Changed in MR23) DLexer.cpp renamed to DLexer.h
+ (Changed in MR23) ATokPtr.cpp renamed to ATokPtrImpl.h
+
+ These two files had .cpp extensions but acted like .h files because
+ there were included in other files. This caused problems for many IDE.
+ I have renamed them. The ATokPtrImpl.h was necessary because there was
+ already an ATokPtr.h.
+
+#273. (Changed in MR23) Default win32 library changed to multi-threaded DLL
+
+ The model used for building the Win32 debug and release libraries has changed
+ to multi-threaded DLL.
+
+ To make this change in your MSVC 6 project:
+
+ Project -> Settings
+ Select the C++ tab in the right pane of the dialog box
+ Select "Category: Code Generation"
+ Under "Use run-time library" select one of the following:
+
+ Multi-threaded DLL
+ Debug Multi-threaded DLL
+
+ Suggested by Bill Menees (bill.menees gogallagher.com)
+
+#272. (Changed in MR23) Failed semantic predicate reported via virtual function
+
+ In the past, a failed semantic predicated reported the problem via a
+ macro which used fprintf(). The macro now expands into a call on
+ the virtual function ANTLRParser::failedSemanticPredicate().
+
+#271. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions
+
+ An bug (or at least an oddity) is that a reference to LT(1), LA(1),
+ or LATEXT(1) in an action which immediately follows a token match
+ in a rule refers to the token matched, not the token which is in
+ the lookahead buffer. Consider:
+
+ r : abc <<action alpha>> D <<action beta>> E;
+
+ In this case LT(1) in action alpha will refer to the next token in
+ the lookahead buffer ("D"), but LT(1) in action beta will refer to
+ the token matched by D - the preceding token.
+
+ A warning has been added for users about this when an action
+ following a token match contains a reference to LT(1), LA(1), or LATEXT(1).
+
+ This behavior should be changed, but it appears in too many programs
+ now. Another problem, perhaps more significant, is that the obvious
+ fix (moving the consume() call to before the action) could change the
+ order in which input is requested and output appears in existing programs.
+
+ This problem was reported, along with a fix by Benjamin Mandel
+ (beny sd.co.il). However, I felt that changing the behavior was too
+ dangerous for existing code.
+
+#270. (Changed in MR23) Removed static objects from PCCTSAST.cpp
+
+ There were some statically allocated objects in PCCTSAST.cpp
+ These were changed to non-static.
+
+#269. (Changed in MR23) dlg output for initializing static array
+
+ The output from dlg contains a construct similar to the
+ following:
+
+ struct XXX {
+ static const int size;
+ static int array1[5];
+ };
+
+ const int XXX::size = 4;
+ int XXX::array1[size+1];
+
+
+ The problem is that although the expression "size+1" used in
+ the definition of array1 is equal to 5 (the expression used to
+ declare array), it is not considered equivalent by some compilers.
+
+ Reported with fix by Volker H. Simonis (simonis informatik.uni-tuebingen.de)
+
+#268. (Changed in MR23) syn() routine output when k > 1
+
+ The syn() routine is supposed to print out the text of the
+ token causing the syntax error. It appears that it always
+ used the text from the first lookahead token rather than the
+ appropriate one. The appropriate one is computed by comparing
+ the token codes of lookahead token i (for i = 1 to k) with
+ the FIRST(i) set.
+
+ This has been corrected in ANTLRParser::syn().
+
+ Reported by Bill Menees (bill.menees gogallagher.com)
+
+#267. (Changed in MR23) AST traversal functions client data argument
+
+ The AST traversal functions now take an extra (optional) parameter
+ which can point to client data:
+
+ preorder_action(void* pData = NULL)
+ preorder_before_action(void* pData = NULL)
+ preorder_after_action(void* pData = NULL)
+
+ **** Warning: this changes the AST signature. ***
+ **** Be sure to revise your AST functions of the same name ***
+
+ Bill Menees (bill.menees gogallagher.com)
+
+#266. (Changed in MR23) virtual function printMessage()
+
+ Bill Menees (bill.menees gogallagher.com) has completed the
+ tedious tasks of replacing all calls to fprintf() with calls
+ to the virtual function printMessage(). For classes which
+ have a pointer to the parser it forwards the printMessage()
+ call to the parser's printMessage() routine.
+
+ This should make it significantly easier to redirect pccts
+ error and warning messages.
+
+#265. (Changed in MR23) Remove "labase++" in C++ mode
+
+ In C++ mode labase++ is called when a token is matched.
+ It appears that labase is not used in C++ mode at all, so
+ this code has been commented out.
+
+#264. (Changed in MR23) Complete rewrite of ParserBlackBox.h
+
+ The parser black box (PBlackBox.h) was completely rewritten
+ by Chris Uzdavinis (chris atdesk.com) to improve its robustness.
+
+#263. (Changed in MR23) -preamble and -preamble_first rescinded
+
+ Changes for item #253 have been rescinded.
+
+#262. (Changed in MR23) Crash with -alpha option during traceback
+
+ Under some circumstances a -alpha traceback was started at the
+ "wrong" time. As a result, internal data structures were not
+ initialized.
+
+ Reported by Arpad Beszedes (beszedes inf.u-szeged.hu).
+
+#261. (Changed in MR23) Defer token fetch for C++ mode
+
+ Item #216 has been revised to indicate that use of the defer fetch
+ option (ZZDEFER_FETCH) requires dlg option -i.
+
+#260. (MR22) Raise default lex buffer size from 8,000 to 32,000 bytes.
+
+ ZZLEXBUFSIZE is the size (in bytes) of the buffer used by dlg
+ generated lexers. The default value has been raised to 32,000 and
+ the value used by antlr, dlg, and sorcerer has also been raised to
+ 32,000.
+
+#259. (MR22) Default function arguments in C++ mode.
+
+ If a rule is declared:
+
+ rr [int i = 0] : ....
+
+ then the declaration generated by pccts resembles:
+
+ void rr(int i = 0);
+
+ however, the definition must omit the default argument:
+
+ void rr(int i) {...}
+
+ In the past the default value was not omitted. In MR22
+ the generated code resembles:
+
+ void rr(int i /* = 0 */ ) {...}
+
+ Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de)
+
+
+ Note: In MR23 this was changed so that nested C style comments
+ ("/* ... */") would not cause problems.
+
+#258. (MR22) Using a base class for your parser
+
+ In item #102 (MR10) the class statement was extended to allow one
+ to specify a base class other than ANTLRParser for the generated
+ parser. It turned out that this was less than useful because
+ the constructor still specified ANTLRParser as the base class.
+
+ The class statement now uses the first identifier appearing after
+ the ":" as the name of the base class. For example:
+
+ class MyParser : public FooParser {
+
+ Generates in MyParser.h:
+
+ class MyParser : public FooParser {
+
+ Generates in MyParser.cpp something that resembles:
+
+ MyParser::MyParser(ANTLRTokenBuffer *input) :
+ FooParser(input,1,0,0,4)
+ {
+ token_tbl = _token_tbl;
+ traceOptionValueDefault=1; // MR10 turn trace ON
+ }
+
+ The base class constructor must have a signature similar to
+ that of ANTLRParser.
+
+#257. (MR21a) Removed dlg statement that -i has no effect in C++ mode.
+
+ This was incorrect.
+
+#256. (MR21a) Malformed syntax graph causes crash after error message.
+
+ In the past, certain kinds of errors in the very first grammar
+ element could cause the construction of a malformed graph
+ representing the grammar. This would eventually result in a
+ fatal internal error. The code has been changed to be more
+ resistant to this particular error.
+
+#255. (MR21a) ParserBlackBox(FILE* f)
+
+ This constructor set openByBlackBox to the wrong value.
+
+ Reported by Kees Bakker (kees_bakker tasking.nl).
+
+#254. (MR21a) Reporting syntax error at end-of-file
+
+ When there was a syntax error at the end-of-file the syntax
+ error routine would substitute "<eof>" for the programmer's
+ end-of-file symbol. This substitution is now done only when
+ the programmer does not define his own end-of-file symbol
+ or the symbol begins with the character "@".
+
+ Reported by Kees Bakker (kees_bakker tasking.nl).
+
+#253. (MR21) Generation of block preamble (-preamble and -preamble_first)
+
+ *** This change was rescinded by item #263 ***
+
+ The antlr option -preamble causes antlr to insert the code
+ BLOCK_PREAMBLE at the start of each rule and block. It does
+ not insert code before rules references, token references, or
+ actions. By properly defining the macro BLOCK_PREAMBLE the
+ user can generate code which is specific to the start of blocks.
+
+ The antlr option -preamble_first is similar, but inserts the
+ code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol
+ PreambleFirst_123 is equivalent to the first set defined by
+ the #FirstSetSymbol described in Item #248.
+
+ I have not investigated how these options interact with guess
+ mode (syntactic predicates).
+
+#252. (MR21) Check for null pointer in trace routine
+
+ When some trace options are used when the parser is generated
+ without the trace enabled, the current rule name may be a
+ NULL pointer. A guard was added to check for this in
+ restoreState.
+
+ Reported by Douglas E. Forester (dougf projtech.com).
+
+#251. (MR21) Changes to #define zzTRACE_RULES
+
+ The macro zzTRACE_RULES was being use to pass information to
+ AParser.h. If this preprocessor symbol was not properly
+ set the first time AParser.h was #included, the declaration
+ of zzTRACEdata would be omitted (it is used by the -gd option).
+ Subsequent #includes of AParser.h would be skipped because of
+ the #ifdef guard, so the declaration of zzTracePrevRuleName would
+ never be made. The result was that proper compilation was very
+ order dependent.
+
+ The declaration of zzTRACEdata was made unconditional and the
+ problem of removing unused declarations will be left to optimizers.
+
+ Diagnosed by Douglas E. Forester (dougf projtech.com).
+
+#250. (MR21) Option for EXPERIMENTAL change to error sets for blocks
+
+ The antlr option -mrblkerr turns on an experimental feature
+ which is supposed to provide more accurate syntax error messages
+ for k=1, ck=1 grammars. When used with k>1 or ck>1 grammars the
+ behavior should be no worse than the current behavior.
+
+ There is no problem with the matching of elements or the computation
+ of prediction expressions in pccts. The task is only one of listing
+ the most appropriate tokens in the error message. The error sets used
+ in pccts error messages are approximations of the exact error set when
+ optional elements in (...)* or (...)+ are involved. While entirely
+ correct, the error messages are sometimes not 100% accurate.
+
+ There is also a minor philosophical issue. For example, suppose the
+ grammar expects the token to be an optional A followed by Z, and it
+ is X. X, of course, is neither A nor Z, so an error message is appropriate.
+ Is it appropriate to say "Expected Z" ? It is correct, it is accurate,
+ but it is not complete.
+
+ When k>1 or ck>1 the problem of providing the exactly correct
+ list of tokens for the syntax error messages ends up becoming
+ equivalent to evaluating the prediction expression for the
+ alternatives twice. However, for k=1 ck=1 grammars the prediction
+ expression can be computed easily and evaluated cheaply, so I
+ decided to try implementing it to satisfy a particular application.
+ This application uses the error set in an interactive command language
+ to provide prompts which list the alternatives available at that
+ point in the parser. The user can then enter additional tokens to
+ complete the command line. To do this required more accurate error
+ sets then previously provided by pccts.
+
+ In some cases the default pccts behavior may lead to more robust error
+ recovery or clearer error messages then having the exact set of tokens.
+ This is because (a) features like -ge allow the use of symbolic names for
+ certain sets of tokens, so having extra tokens may simply obscure things
+ and (b) the error set is use to resynchronize the parser, so a good
+ choice is sometimes more important than having the exact set.
+
+ Consider the following example:
+
+ Note: All examples code has been abbreviated
+ to the absolute minimum in order to make the
+ examples concise.
+
+ star1 : (A)* Z;
+
+ The generated code resembles:
+
+ old new (with -mrblkerr)
+ --//----------- --------------------
+ for (;;) { for (;;) {
+ match(A); match(A);
+ } }
+ match(Z); if (! A and ! Z) then
+ FAIL(...{A,Z}...);
+ }
+ match(Z);
+
+
+ With input X
+ old message: Found X, expected Z
+ new message: Found X, expected A, Z
+
+ For the example:
+
+ star2 : (A|B)* Z;
+
+ old new (with -mrblkerr)
+ ------------- --------------------
+ for (;;) { for (;;) {
+ if (!A and !B) break; if (!A and !B) break;
+ if (...) { if (...) {
+ <same ...> <same ...>
+ } }
+ else { else {
+ FAIL(...{A,B,Z}...) FAIL(...{A,B}...);
+ } }
+ } }
+ match(B); if (! A and ! B and !Z) then
+ FAIL(...{A,B,Z}...);
+ }
+ match(B);
+
+ With input X
+ old message: Found X, expected Z
+ new message: Found X, expected A, B, Z
+ With input A X
+ old message: Found X, expected Z
+ new message: Found X, expected A, B, Z
+
+ This includes the choice of looping back to the
+ star block.
+
+ The code for plus blocks:
+
+ plus1 : (A)+ Z;
+
+ The generated code resembles:
+
+ old new (with -mrblkerr)
+ ------------- --------------------
+ do { do {
+ match(A); match(A);
+ } while (A) } while (A)
+ match(Z); if (! A and ! Z) then
+ FAIL(...{A,Z}...);
+ }
+ match(Z);
+
+ With input A X
+ old message: Found X, expected Z
+ new message: Found X, expected A, Z
+
+ This includes the choice of looping back to the
+ plus block.
+
+ For the example:
+
+ plus2 : (A|B)+ Z;
+
+ old new (with -mrblkerr)
+ ------------- --------------------
+ do { do {
+ if (A) { <same>
+ match(A); <same>
+ } else if (B) { <same>
+ match(B); <same>
+ } else { <same>
+ if (cnt > 1) break; <same>
+ FAIL(...{A,B,Z}...) FAIL(...{A,B}...);
+ } }
+ cnt++; <same>
+ } }
+
+ match(Z); if (! A and ! B and !Z) then
+ FAIL(...{A,B,Z}...);
+ }
+ match(B);
+
+ With input X
+ old message: Found X, expected A, B, Z
+ new message: Found X, expected A, B
+ With input A X
+ old message: Found X, expected Z
+ new message: Found X, expected A, B, Z
+
+ This includes the choice of looping back to the
+ star block.
+
+#249. (MR21) Changes for DEC/VMS systems
+
+ Jean-François Piéronne (jfp altavista.net) has updated some
+ VMS related command files and fixed some minor problems related
+ to building pccts under the DEC/VMS operating system. For DEC/VMS
+ users the most important differences are:
+
+ a. Revised makefile.vms
+ b. Revised genMMS for genrating VMS style makefiles.
+
+#248. (MR21) Generate symbol for first set of an alternative
+
+ pccts can generate a symbol which represents the tokens which may
+ appear at the start of a block:
+
+ rr : #FirstSetSymbol(rr_FirstSet) ( Foo | Bar ) ;
+
+ This will generate the symbol rr_FirstSet of type SetWordType with
+ elements Foo and Bar set. The bits can be tested using code similar
+ to the following:
+
+ if (set_el(Foo, &rr_FirstSet)) { ...
+
+ This can be combined with the C array zztokens[] or the C++ routine
+ tokenName() to get the print name of the token in the first set.
+
+ The size of the set is given by the newly added enum SET_SIZE, a
+ protected member of the generated parser's class. The number of
+ elements in the generated set will not be exactly equal to the
+ value of SET_SIZE because of synthetic tokens created by #tokclass,
+ #errclass, the -ge option, and meta-tokens such as epsilon, and
+ end-of-file.
+
+ The #FirstSetSymbol must appear immediately before a block
+ such as (...)+, (...)*, and {...}, and (...). It may not appear
+ immediately before a token, a rule reference, or action. However
+ a token or rule reference can be enclosed in a (...) in order to
+ make the use of #pragma FirstSetSymbol legal.
+
+ rr_bad : #FirstSetSymbol(rr_bad_FirstSet) Foo; // Illegal
+
+ rr_ok : #FirstSetSymbol(rr_ok_FirstSet) (Foo); // Legal
+
+ Do not confuse FirstSetSymbol sets with the sets used for testing
+ lookahead. The sets used for FirstSetSymbol have one element per bit,
+ so the number of bytes is approximately the largest token number
+ divided by 8. The sets used for testing lookahead store 8 lookahead
+ sets per byte, so the length of the array is approximately the largest
+ token number.
+
+ If there is demand, a similar routine for follow sets can be added.
+
+#247. (MR21) Misleading error message on syntax error for optional elements.
+
+ ===================================================
+ The behavior has been revised when parser exception
+ handling is used. See Item #290
+ ===================================================
+
+ Prior to MR21, tokens which were optional did not appear in syntax
+ error messages if the block which immediately followed detected a
+ syntax error.
+
+ Consider the following grammar which accepts Number, Word, and Other:
+
+ rr : {Number} Word;
+
+ For this rule the code resembles:
+
+ if (LA(1) == Number) {
+ match(Number);
+ consume();
+ }
+ match(Word);
+
+ Prior to MR21, the error message for input "$ a" would be:
+
+ line 1: syntax error at "$" missing Word
+
+ With MR21 the message will be:
+
+ line 1: syntax error at "$" expecting Word, Number.
+
+ The generate code resembles:
+
+ if ( (LA(1)==Number) ) {
+ zzmatch(Number);
+ consume();
+ }
+ else {
+ if ( (LA(1)==Word) ) {
+ /* nothing */
+ }
+ else {
+ FAIL(... message for both Number and Word ...);
+ }
+ }
+ match(Word);
+
+ The code generated for optional blocks in MR21 is slightly longer
+ than the previous versions, but it should give better error messages.
+
+ The code generated for:
+
+ { a | b | c }
+
+ should now be *identical* to:
+
+ ( a | b | c | )
+
+ which was not the case prior to MR21.
+
+ Reported by Sue Marvin (sue siara.com).
+
+#246. (Changed in MR21) Use of $(MAKE) for calls to make
+
+ Calls to make from the makefiles were replaced with $(MAKE)
+ because of problems when using gmake.
+
+ Reported with fix by Sunil K.Vallamkonda (sunil siara.com).
+
+#245. (Changed in MR21) Changes to genmk
+
+ The following command line options have been added to genmk:
+
+ -cfiles ...
+
+ To add a user's C or C++ files into makefile automatically.
+ The list of files must be enclosed in apostrophes. This
+ option may be specified multiple times.
+
+ -compiler ...
+
+ The name of the compiler to use for $(CCC) or $(CC). The
+ default in C++ mode is "CC". The default in C mode is "cc".
+
+ -pccts_path ...
+
+ The value for $(PCCTS), the pccts directory. The default
+ is /usr/local/pccts.
+
+ Contributed by Tomasz Babczynski (t.babczynski ict.pwr.wroc.pl).
+
+#244. (Changed in MR21) Rename variable "not" in antlr.g
+
+ When antlr.g is compiled with a C++ compiler, a variable named
+ "not" causes problems. Reported by Sinan Karasu
+ (sinan.karasu boeing.com).
+
+#243 (Changed in MR21) Replace recursion with iteration in zzfree_ast
+
+ Another refinement to zzfree_ast in ast.c to limit recursion.
+
+ NAKAJIMA Mutsuki (muc isr.co.jp).
+
+
+#242. (Changed in MR21) LineInfoFormatStr
+
+ Added an #ifndef/#endif around LineInfoFormatStr in pcctscfg.h.
+
+#241. (Changed in MR21) Changed macro PURIFY to a no-op
+
+ ***********************
+ *** NOT IMPLEMENTED ***
+ ***********************
+
+ The PURIFY macro was changed to a no-op because it was causing
+ problems when passing C++ objects.
+
+ The old definition:
+
+ #define PURIFY(r,s) memset((char *) &(r),'\\0',(s));
+
+ The new definition:
+
+ #define PURIFY(r,s) /* nothing */
+#endif
+
+#240. (Changed in MR21) sorcerer/h/sorcerer.h _MATCH and _MATCHRANGE
+
+ Added test for NULL token pointer.
+
+ Suggested by Peter Keller (keller ebi.ac.uk)
+
+#239. (Changed in MR21) C++ mode AParser::traceGuessFail
+
+ If tracing is turned on when the code has been generated
+ without trace code, a failed guess generates a trace report
+ even though there are no other trace reports. This
+ make the behavior consistent with other parts of the
+ trace system.
+
+ Reported by David Wigg (wiggjd sbu.ac.uk).
+
+#238. (Changed in MR21) Namespace version #include files
+
+ Changed reference from CStdio to cstdio (and other
+ #include file names) in the namespace version of pccts.
+ Should have known better.
+
+#237. (Changed in MR21) ParserBlackBox(FILE*)
+
+ In the past, ParserBlackBox would close the FILE in the dtor
+ even though it was not opened by ParserBlackBox. The problem
+ is that there were two constructors, one which accepted a file
+ name and did an fopen, the other which accepted a FILE and did
+ not do an fopen. There is now an extra member variable which
+ remembers whether ParserBlackBox did the open or not.
+
+ Suggested by Mike Percy (mpercy scires.com).
+
+#236. (Changed in MR21) tmake now reports down pointer problem
+
+ When ASTBase::tmake attempts to update the down pointer of
+ an AST it checks to see if the down pointer is NULL. If it
+ is not NULL it does not do the update and returns NULL.
+ An attempt to update the down pointer is almost always a
+ result of a user error. This can lead to difficult to find
+ problems during tree construction.
+
+ With this change, the routine calls a virtual function
+ reportOverwriteOfDownPointer() which calls panic to
+ report the problem. Users who want the old behavior can
+ redefined the virtual function in their AST class.
+
+ Suggested by Sinan Karasu (sinan.karasu boeing.com)
+
+#235. (Changed in MR21) Made ANTLRParser::resynch() virtual
+
+ Suggested by Jerry Evans (jerry swsl.co.uk).
+
+#234. (Changed in MR21) Implicit int for function return value
+
+ ATokenBuffer:bufferSize() did not specify a type for the
+ return value.
+
+ Reported by Hai Vo-Ba (hai fc.hp.com).
+
+#233. (Changed in MR20) Converted to MSVC 6.0
+
+ Due to external circumstances I have had to convert to MSVC 6.0
+ The MSVC 5.0 project files (.dsw and .dsp) have been retained as
+ xxx50.dsp and xxx50.dsw. The MSVC 6.0 files are named xxx60.dsp
+ and xxx60.dsw (where xxx is the related to the directory/project).
+
+#232. (Changed in MR20) Make setwd bit vectors protected in parser.h
+
+ The access for the setwd array in the parser header was not
+ specified. As a result, it would depend on the code which
+ preceded it. In MR20 it will always have access "protected".
+
+ Reported by Piotr Eljasiak (eljasiak zt.gdansk.tpsa.pl).
+
+#231. (Changed in MR20) Error in token buffer debug code.
+
+ When token buffer debugging is selected via the pre-processor
+ symbol DEBUG_TOKENBUFFER there is an erroneous check in
+ AParser.cpp:
+
+ #ifdef DEBUG_TOKENBUFFER
+ if (i >= inputTokens->bufferSize() ||
+ inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */
+ ...
+ #endif
+
+ Reported by David Wigg (wiggjd sbu.ac.uk).
+
+#230. (Changed in MR20) Fixed problem with #define for -gd option
+
+ There was an error in setting zzTRACE_RULES for the -gd (trace) option.
+
+ Reported by Gary Funck (gary intrepid.com).
+
+#229. (Changed in MR20) Additional "const" for literals
+
+ "const" was added to the token name literal table.
+ "const" was added to some panic() and similar routine
+
+#228. (Changed in MR20) dlg crashes on "()"
+
+ The following token definition will cause DLG to crash.
+
+ #token "()"
+
+ When there is a syntax error in a regular expression
+ many of the dlg routines return a structure which has
+ null pointers. When this is accessed by callers it
+ generates the crash.
+
+ I have attempted to fix the more common cases.
+
+ Reported by Mengue Olivier (dolmen bigfoot.com).
+
+#227. (Changed in MR20) Array overwrite
+
+ Steveh Hand (sassth unx.sas.com) reported a problem which
+ was traced to a temporary array which was not properly
+ resized for deeply nested blocks. This has been fixed.
+
+#226. (Changed in MR20) -pedantic conformance
+
+ G. Hobbelt (i_a mbh.org) and THM made many, many minor
+ changes to create prototypes for all the functions and
+ bring antlr, dlg, and sorcerer into conformance with
+ the gcc -pedantic option.
+
+ This may require uses to add pccts/h/pcctscfg.h to some
+ files or makefiles in order to have __USE_PROTOS defined.
+
+#225 (Changed in MR20) AST stack adjustment in C mode
+
+ The fix in #214 for AST stack adjustment in C mode missed
+ some cases.
+
+ Reported with fix by Ger Hobbelt (i_a mbh.org).
+
+#224 (Changed in MR20) LL(1) and LL(2) with #pragma approx
+
+ This may take a record for the oldest, most trival, lexical
+ error in pccts. The regular expressions for LL(1) and LL(2)
+ lacked an escape for the left and right parenthesis.
+
+ Reported by Ger Hobbelt (i_a mbh.org).
+
+#223 (Changed in MR20) Addition of IBM_VISUAL_AGE directory
+
+ Build files for antlr, dlg, and sorcerer under IBM Visual Age
+ have been contributed by Anton Sergeev (ags mlc.ru). They have
+ been placed in the pccts/IBM_VISUAL_AGE directory.
+
+#222 (Changed in MR20) Replace __STDC__ with __USE_PROTOS
+
+ Most occurrences of __STDC__ replaced with __USE_PROTOS due to
+ complaints from several users.
+
+#221 (Changed in MR20) Added #include for DLexerBase.h to PBlackBox.
+
+ Added #include for DLexerBase.h to PBlackBox.
+
+#220 (Changed in MR19) strcat arguments reversed in #pred parse
+
+ The arguments to strcat are reversed when creating a print
+ name for a hash table entry for use with #pred feature.
+
+ Problem diagnosed and fix reported by Scott Harrington
+ (seh4 ix.netcom.com).
+
+#219. (Changed in MR19) C Mode routine zzfree_ast
+
+ Changes to reduce use of recursion for AST trees with only right
+ links or only left links in the C mode routine zzfree_ast.
+
+ Implemented by SAKAI Kiyotaka (ksakai isr.co.jp).
+
+#218. (Changed in MR19) Changes to support unsigned char in C mode
+
+ Changes to antlr.h and err.h to fix omissions in use of zzchar_t
+
+ Implemented by SAKAI Kiyotaka (ksakai isr.co.jp).
+
+#217. (Changed in MR19) Error message when dlg -i and -CC options selected
+
+ *** This change was rescinded by item #257 ***
+
+ The parsers generated by pccts in C++ mode are not able to support the
+ interactive lexer option (except, perhaps, when using the deferred fetch
+ parser option.(Item #216).
+
+ DLG now warns when both -i and -CC are selected.
+
+ This warning was suggested by David Venditti (07751870267-0001 t-online.de).
+
+#216. (Changed in MR19) Defer token fetch for C++ mode
+
+ Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de)
+
+ Normally, pccts keeps the lookahead token buffer completely filled.
+ This requires max(k,ck) tokens of lookahead. For some applications
+ this can cause deadlock problems. For example, there may be cases
+ when the parser can't tell when the input has been completely consumed
+ until the parse is complete, but the parse can't be completed because
+ the input routines are waiting for additional tokens to fill the
+ lookahead buffer.
+
+ When the ANTLRParser class is built with the pre-processor option
+ ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred
+ until LA(i) or LT(i) is called.
+
+ To test whether this option has been built into the ANTLRParser class
+ use "isDeferFetchEnabled()".
+
+ Using the -gd trace option with the default tracein() and traceout()
+ routines will defeat the effort to defer the fetch because the
+ trace routines print out information about the lookahead token at
+ the start of the rule.
+
+ Because the tracein and traceout routines are virtual it is
+ easy to redefine them in your parser:
+
+ class MyParser {
+ <<
+ virtual void tracein(ANTLRChar * ruleName)
+ { fprintf(stderr,"Entering: %s\n", ruleName); }
+ virtual void traceout(ANTLRChar * ruleName)
+ { fprintf(stderr,"Leaving: %s\n", ruleName); }
+ >>
+
+ The originals for those routines are pccts/h/AParser.cpp
+
+ This requires use of the dlg option -i (interactive lexer).
+
+ This is implemented only for C++ mode.
+
+ This is experimental. The interaction with guess mode (syntactic
+ predicates)is not known.
+
+#215. (Changed in MR19) Addition of reset() to DLGLexerBase
+
+ There was no obvious way to reset the lexer for reuse. The
+ reset() method now does this.
+
+ Suggested by David Venditti (07751870267-0001 t-online.de).
+
+#214. (Changed in MR19) C mode: Adjust AST stack pointer at exit
+
+ In C mode the AST stack pointer needs to be reset if there will
+ be multiple calls to the ANTLRx macros.
+
+ Reported with fix by Paul D. Smith (psmith baynetworks.com).
+
+#213. (Changed in MR18) Fatal error with -mrhoistk (k>1 hoisting)
+
+ When rearranging code I forgot to un-comment a critical line of
+ code that handles hoisting of predicates with k>1 lookahead. This
+ is now fixed.
+
+ Reported by Reinier van den Born (reinier vnet.ibm.com).
+
+#212. (Changed in MR17) Mac related changes by Kenji Tanaka
+
+ Kenji Tanaka (kentar osa.att.ne.jp) has made a number of changes for
+ Macintosh users.
+
+ a. The following Macintosh MPW files aid in installing pccts on Mac:
+
+ pccts/MPW_Read_Me
+
+ pccts/install68K.mpw
+ pccts/installPPC.mpw
+
+ pccts/antlr/antlr.r
+ pccts/antlr/antlr68K.make
+ pccts/antlr/antlrPPC.make
+
+ pccts/dlg/dlg.r
+ pccts/dlg/dlg68K.make
+ pccts/dlg/dlgPPC.make
+
+ pccts/sorcerer/sor.r
+ pccts/sorcerer/sor68K.make
+ pccts/sorcerer/sorPPC.make
+
+ They completely replace the previous Mac installation files.
+
+ b. The most significant is a change in the MAC_FILE_CREATOR symbol
+ in pcctscfg.h:
+
+ old: #define MAC_FILE_CREATOR 'MMCC' /* Metrowerks C/C++ Text files */
+ new: #define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */
+
+ c. Added calls to special_fopen_actions() where necessary.
+
+#211. (Changed in MR16a) C++ style comment in dlg
+
+ This has been fixed.
+
+#210. (Changed in MR16a) Sor accepts \r\n, \r, or \n for end-of-line
+
+ A user requested that Sorcerer be changed to accept other forms
+ of end-of-line.
+
+#209. (Changed in MR16) Name of files changed.
+
+ Old: CHANGES_FROM_1.33
+ New: CHANGES_FROM_133.txt
+
+ Old: KNOWN_PROBLEMS
+ New: KNOWN_PROBLEMS.txt
+
+#208. (Changed in MR16) Change in use of pccts #include files
+
+ There were problems with MS DevStudio when mixing Sorcerer and
+ PCCTS in the same source file. The problem is caused by the
+ redefinition of setjmp in the MS header file setjmp.h. In
+ setjmp.h the pre-processor symbol setjmp was redefined to be
+ _setjmp. A later effort to execute #include <setjmp.h> resulted
+ in an effort to #include <_setjmp.h>. I'm not sure whether this
+ is a bug or a feature. In any case, I decided to fix it by
+ avoiding the use of pre-processor symbols in #include statements
+ altogether. This has the added benefit of making pre-compiled
+ headers work again.
+
+ I've replaced statements:
+
+ old: #include PCCTS_SETJMP_H
+ new: #include "pccts_setjmp.h"
+
+ Where pccts_setjmp.h contains:
+
+ #ifndef __PCCTS_SETJMP_H__
+ #define __PCCTS_SETJMP_H__
+
+ #ifdef PCCTS_USE_NAMESPACE_STD
+ #include <Csetjmp>
+ #else
+ #include <setjmp.h>
+ #endif
+
+ #endif
+
+ A similar change has been made for other standard header files
+ required by pccts and sorcerer: stdlib.h, stdarg.h, stdio.h, etc.
+
+ Reported by Jeff Vincent (JVincent novell.com) and Dale Davis
+ (DalDavis spectrace.com).
+
+#207. (Changed in MR16) dlg reports an invalid range for: [\0x00-\0xff]
+
+ -----------------------------------------------------------------
+ Note from MR23: This fix does not work. I am investigating why.
+ -----------------------------------------------------------------
+
+ dlg will report that this is an invalid range.
+
+ Diagnosed by Piotr Eljasiak (eljasiak no-spam.zt.gdansk.tpsa.pl):
+
+ I think this problem is not specific to unsigned chars
+ because dlg reports no error for the range [\0x00-\0xfe].
+
+ I've found that information on range is kept in field
+ letter (unsigned char) of Attrib struct. Unfortunately
+ the letter value internally is for some reasons increased
+ by 1, so \0xff is represented here as 0.
+
+ That's why dlg complains about the range [\0x00-\0xff] in
+ dlg_p.g:
+
+ if ($$.letter > $2.letter) {
+ error("invalid range ", zzline);
+ }
+
+ The fix is:
+
+ if ($$.letter > $2.letter && 255 != $$2.letter) {
+ error("invalid range ", zzline);
+ }
+
+#206. (Changed in MR16) Free zzFAILtext in ANTLRParser destructor
+
+ The ANTLRParser destructor now frees zzFAILtext.
+
+ Problem and fix reported by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#205. (Changed in MR16) DLGStringReset argument now const
+
+ Changed: void DLGStringReset(DLGChar *s) {...}
+ To: void DLGStringReset(const DLGChar *s) {...}
+
+ Suggested by Dale Davis (daldavis spectrace.com)
+
+#204. (Changed in MR15a) Change __WATCOM__ to __WATCOMC__ in pcctscfg.h
+
+ Reported by Oleg Dashevskii (olegdash my-dejanews.com).
+
+#203. (Changed in MR15) Addition of sorcerer to distribution kit
+
+ I have finally caved in to popular demand. The pccts 1.33mr15
+ kit will include sorcerer. The separate sorcerer kit will be
+ discontinued.
+
+#202. (Changed) in MR15) Organization of MS Dev Studio Projects in Kit
+
+ Previously there was one workspace that contained projects for
+ all three parts of pccts: antlr, dlg, and sorcerer. Now each
+ part (and directory) has its own workspace/project and there
+ is an additional workspace/project to build a library from the
+ .cpp files in the pccts/h directory.
+
+ The library build will create pccts_debug.lib or pccts_release.lib
+ according to the configuration selected.
+
+ If you don't want to build pccts 1.33MR15 you can download a
+ ready-to-run kit for win32 from http://www.polhode.com/win32.zip.
+ The ready-to-run for win32 includes executables, a pre-built static
+ library for the .cpp files in the pccts/h directory, and a sample
+ application
+
+ You will need to define the environment variable PCCTS to point to
+ the root of the pccts directory hierarchy.
+
+#201. (Changed in MR15) Several fixes by K.J. Cummings (cummings peritus.com)
+
+ Generation of SETJMP rather than SETJMP_H in gen.c.
+
+ (Sor B19) Declaration of ref_vars_inits for ref_var_inits in
+ pccts/sorcerer/sorcerer.h.
+
+#200. (Changed in MR15) Remove operator=() in AToken.h
+
+ User reported that WatCom couldn't handle use of
+ explicit operator =(). Replace with equivalent
+ using cast operator.
+
+#199. (Changed in MR15) Don't allow use of empty #tokclass
+
+ Change antlr.g to disallow empty #tokclass sets.
+
+ Reported by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#198. Revised ANSI C grammar due to efforts by Manuel Kessler
+
+ Manuel Kessler (mlkessler cip.physik.uni-wuerzburg.de)
+
+ Allow trailing ... in function parameter lists.
+ Add bit fields.
+ Allow old-style function declarations.
+ Support cv-qualified pointers.
+ Better checking of combinations of type specifiers.
+ Release of memory for local symbols on scope exit.
+ Allow input file name on command line as well as by redirection.
+
+ and other miscellaneous tweaks.
+
+ This is not part of the pccts distribution kit. It must be
+ downloaded separately from:
+
+ http://www.polhode.com/ansi_mr15.zip
+
+#197. (Changed in MR14) Resetting the lookahead buffer of the parser
+
+ Explanation and fix by Sinan Karasu (sinan.karasu boeing.com)
+
+ Consider the code used to prime the lookahead buffer LA(i)
+ of the parser when init() is called:
+
+ void
+ ANTLRParser::
+ prime_lookahead()
+ {
+ int i;
+ for(i=1;i<=LLk; i++) consume();
+ dirty=0;
+ //lap = 0; // MR14 - Sinan Karasu (sinan.karusu boeing.com)
+ //labase = 0; // MR14
+ labase=lap; // MR14
+ }
+
+ When the parser is instantiated, lap=0,labase=0 is set.
+
+ The "for" loop runs LLk times. In consume(), lap = lap +1 (mod LLk) is
+ computed. Therefore, lap(before the loop) == lap (after the loop).
+
+ Now the only problem comes in when one does an init() of the parser
+ after an Eof has been seen. At that time, lap could be non zero.
+ Assume it was lap==1. Now we do a prime_lookahead(). If LLk is 2,
+ then
+
+ consume()
+ {
+ NLA = inputTokens->getToken()->getType();
+ dirty--;
+ lap = (lap+1)&(LLk-1);
+ }
+
+ or expanding NLA,
+
+ token_type[lap&(LLk-1)]) = inputTokens->getToken()->getType();
+ dirty--;
+ lap = (lap+1)&(LLk-1);
+
+ so now we prime locations 1 and 2. In prime_lookahead it used to set
+ lap=0 and labase=0. Now, the next token will be read from location 0,
+ NOT 1 as it should have been.
+
+ This was never caught before, because if a parser is just instantiated,
+ then lap and labase are 0, the offending assignment lines are
+ basically no-ops, since the for loop wraps around back to 0.
+
+#196. (Changed in MR14) Problems with "(alpha)? beta" guess
+
+ Consider the following syntactic predicate in a grammar
+ with 2 tokens of lookahead (k=2 or ck=2):
+
+ rule : ( alpha )? beta ;
+ alpha : S t ;
+ t : T U
+ | T
+ ;
+ beta : S t Z ;
+
+ When antlr computes the prediction expression with one token
+ of lookahead for alts 1 and 2 of rule t it finds an ambiguity.
+
+ Because the grammar has a lookahead of 2 it tries to compute
+ two tokens of lookahead for alts 1 and 2 of t. Alt 1 clearly
+ has a lookahead of (T U). Alt 2 is one token long so antlr
+ tries to compute the follow set of alt 2, which means finding
+ the things which can follow rule t in the context of (alpha)?.
+ This cannot be computed, because alpha is only part of a rule,
+ and antlr can't tell what part of beta is matched by alpha and
+ what part remains to be matched. Thus it impossible for antlr
+ to properly determine the follow set of rule t.
+
+ Prior to 1.33MR14, the follow of (alpha)? was computed as
+ FIRST(beta) as a result of the internal representation of
+ guess blocks.
+
+ With MR14 the follow set will be the empty set for that context.
+
+ Normally, one expects a rule appearing in a guess block to also
+ appear elsewhere. When the follow context for this other use
+ is "ored" with the empty set, the context from the other use
+ results, and a reasonable follow context results. However if
+ there is *no* other use of the rule, or it is used in a different
+ manner then the follow context will be inaccurate - it was
+ inaccurate even before MR14, but it will be inaccurate in a
+ different way.
+
+ For the example given earlier, a reasonable way to rewrite the
+ grammar:
+
+ rule : ( alpha )? beta
+ alpha : S t ;
+ t : T U
+ | T
+ ;
+ beta : alpha Z ;
+
+ If there are no other uses of the rule appearing in the guess
+ block it will generate a test for EOF - a workaround for
+ representing a null set in the lookahead tests.
+
+ If you encounter such a problem you can use the -alpha option
+ to get additional information:
+
+ line 2: error: not possible to compute follow set for alpha
+ in an "(alpha)? beta" block.
+
+ With the antlr -alpha command line option the following information
+ is inserted into the generated file:
+
+ #if 0
+
+ Trace of references leading to attempt to compute the follow set of
+ alpha in an "(alpha)? beta" block. It is not possible for antlr to
+ compute this follow set because it is not known what part of beta has
+ already been matched by alpha and what part remains to be matched.
+
+ Rules which make use of the incorrect follow set will also be incorrect
+
+ 1 #token T alpha/2 line 7 brief.g
+ 2 end alpha alpha/3 line 8 brief.g
+ 2 end (...)? block at start/1 line 2 brief.g
+
+ #endif
+
+ At the moment, with the -alpha option selected the program marks
+ any rules which appear in the trace back chain (above) as rules with
+ possible problems computing follow set.
+
+ Reported by Greg Knapen (gregory.knapen bell.ca).
+
+#195. (Changed in MR14) #line directive not at column 1
+
+ Under certain circumstances a predicate test could generate
+ a #line directive which was not at column 1.
+
+ Reported with fix by David KÃ¥gedal (davidk lysator.liu.se)
+ (http://www.lysator.liu.se/~davidk/).
+
+#194. (Changed in MR14) (C Mode only) Demand lookahead with #tokclass
+
+ In C mode with the demand lookahead option there is a bug in the
+ code which handles matches for #tokclass (zzsetmatch and
+ zzsetmatch_wsig).
+
+ The bug causes the lookahead pointer to get out of synchronization
+ with the current token pointer.
+
+ The problem was reported with a fix by Ger Hobbelt (hobbelt axa.nl).
+
+#193. (Changed in MR14) Use of PCCTS_USE_NAMESPACE_STD
+
+ The pcctscfg.h now contains the following definitions:
+
+ #ifdef PCCTS_USE_NAMESPACE_STD
+ #define PCCTS_STDIO_H <Cstdio>
+ #define PCCTS_STDLIB_H <Cstdlib>
+ #define PCCTS_STDARG_H <Cstdarg>
+ #define PCCTS_SETJMP_H <Csetjmp>
+ #define PCCTS_STRING_H <Cstring>
+ #define PCCTS_ASSERT_H <Cassert>
+ #define PCCTS_ISTREAM_H <istream>
+ #define PCCTS_IOSTREAM_H <iostream>
+ #define PCCTS_NAMESPACE_STD namespace std {}; using namespace std;
+ #else
+ #define PCCTS_STDIO_H <stdio.h>
+ #define PCCTS_STDLIB_H <stdlib.h>
+ #define PCCTS_STDARG_H <stdarg.h>
+ #define PCCTS_SETJMP_H <setjmp.h>
+ #define PCCTS_STRING_H <string.h>
+ #define PCCTS_ASSERT_H <assert.h>
+ #define PCCTS_ISTREAM_H <istream.h>
+ #define PCCTS_IOSTREAM_H <iostream.h>
+ #define PCCTS_NAMESPACE_STD
+ #endif
+
+ The runtime support in pccts/h uses these pre-processor symbols
+ consistently.
+
+ Also, antlr and dlg have been changed to generate code which uses
+ these pre-processor symbols rather than having the names of the
+ #include files hard-coded in the generated code.
+
+ This required the addition of "#include pcctscfg.h" to a number of
+ files in pccts/h.
+
+ It appears that this sometimes causes problems for MSVC 5 in
+ combination with the "automatic" option for pre-compiled headers.
+ In such cases disable the "automatic" pre-compiled headers option.
+
+ Suggested by Hubert Holin (Hubert.Holin Bigfoot.com).
+
+#192. (Changed in MR14) Change setText() to accept "const ANTLRChar *"
+
+ Changed ANTLRToken::setText(ANTLRChar *) to setText(const ANTLRChar *).
+ This allows literal strings to be used to initialize tokens. Since
+ the usual token implementation (ANTLRCommonToken) makes a copy of the
+ input string, this was an unnecessary limitation.
+
+ Suggested by Bob McWhirter (bob netwrench.com).
+
+#191. (Changed in MR14) HP/UX aCC compiler compatibility problem
+
+ Needed to explicitly declare zzINF_DEF_TOKEN_BUFFER_SIZE and
+ zzINF_BUFFER_TOKEN_CHUNK_SIZE as ints in pccts/h/AParser.cpp.
+
+ Reported by David Cook (dcook bmc.com).
+
+#190. (Changed in MR14) IBM OS/2 CSet compiler compatibility problem
+
+ Name conflict with "_cs" in pccts/h/ATokenBuffer.cpp
+
+ Reported by David Cook (dcook bmc.com).
+
+#189. (Changed in MR14) -gxt switch in C mode
+
+ The -gxt switch in C mode didn't work because of incorrect
+ initialization.
+
+ Reported by Sinan Karasu (sinan boeing.com).
+
+#188. (Changed in MR14) Added pccts/h/DLG_stream_input.h
+
+ This is a DLG stream class based on C++ istreams.
+
+ Contributed by Hubert Holin (Hubert.Holin Bigfoot.com).
+
+#187. (Changed in MR14) Rename config.h to pcctscfg.h
+
+ The PCCTS configuration file has been renamed from config.h to
+ pcctscfg.h. The problem with the original name is that it led
+ to name collisions when pccts parsers were combined with other
+ software.
+
+ All of the runtime support routines in pccts/h/* have been
+ changed to use the new name. Existing software can continue
+ to use pccts/h/config.h. The contents of pccts/h/config.h is
+ now just "#include "pcctscfg.h".
+
+ I don't have a record of the user who suggested this.
+
+#186. (Changed in MR14) Pre-processor symbol DllExportPCCTS class modifier
+
+ Classes in the C++ runtime support routines are now declared:
+
+ class DllExportPCCTS className ....
+
+ By default, the pre-processor symbol is defined as the empty
+ string. This if for use by MSVC++ users to create DLL classes.
+
+ Suggested by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#185. (Changed in MR14) Option to not use PCCTS_AST base class for ASTBase
+
+ Normally, the ASTBase class is derived from PCCTS_AST which contains
+ functions useful to Sorcerer. If these are not necessary then the
+ user can define the pre-processor symbol "PCCTS_NOT_USING_SOR" which
+ will cause the ASTBase class to replace references to PCCTS_AST with
+ references to ASTBase where necessary.
+
+ The class ASTDoublyLinkedBase will contain a pure virtual function
+ shallowCopy() that was formerly defined in class PCCTS_AST.
+
+ Suggested by Bob McWhirter (bob netwrench.com).
+
+#184. (Changed in MR14) Grammars with no tokens generate invalid tokens.h
+
+ Reported by Hubert Holin (Hubert.Holin bigfoot.com).
+
+#183. (Changed in MR14) -f to specify file with names of grammar files
+
+ In DEC/VMS it is difficult to specify very long command lines.
+ The -f option allows one to place the names of the grammar files
+ in a data file in order to bypass limitations of the DEC/VMS
+ command language interpreter.
+
+ Addition supplied by Bernard Giroud (b_giroud decus.ch).
+
+#182. (Changed in MR14) Output directory option for DEC/VMS
+
+ Fix some problems with the -o option under DEC/VMS.
+
+ Fix supplied by Bernard Giroud (b_giroud decus.ch).
+
+#181. (Changed in MR14) Allow chars > 127 in DLGStringInput::nextChar()
+
+ Changed DLGStringInput to cast the character using (unsigned char)
+ so that languages with character codes greater than 127 work
+ without changes.
+
+ Suggested by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#180. (Added in MR14) ANTLRParser::getEofToken()
+
+ Added "ANTLRToken ANTLRParser::getEofToken() const" to match the
+ setEofToken routine.
+
+ Requested by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#179. (Fixed in MR14) Memory leak for BufFileInput subclass of DLGInputStream
+
+ The BufFileInput class described in Item #142 neglected to release
+ the allocated buffer when an instance was destroyed.
+
+ Reported by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#178. (Fixed in MR14) Bug in "(alpha)? beta" guess blocks first sets
+
+ In 1.33 vanilla, and all maintenance releases prior to MR14
+ there is a bug in the handling of guess blocks which use the
+ "long" form:
+
+ (alpha)? beta
+
+ inside a (...)*, (...)+, or {...} block.
+
+ This problem does *not* apply to the case where beta is omitted
+ or when the syntactic predicate is on the leading edge of an
+ alternative.
+
+ The problem is that both alpha and beta are stored in the
+ syntax diagram, and that some analysis routines would fail
+ to skip the alpha portion when it was not on the leading edge.
+ Consider the following grammar with -ck 2:
+
+ r : ( (A)? B )* C D
+
+ | A B /* forces -ck 2 computation for old antlr */
+ /* reports ambig for alts 1 & 2 */
+
+ | B C /* forces -ck 2 computation for new antlr */
+ /* reports ambig for alts 1 & 3 */
+ ;
+
+ The prediction expression for the first alternative should be
+ LA(1)={B C} LA(2)={B C D}, but previous versions of antlr
+ would compute the prediction expression as LA(1)={A C} LA(2)={B D}
+
+ Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided
+ a very clear example of the problem and identified the probable cause.
+
+#177. (Changed in MR14) #tokdefs and #token with regular expression
+
+ In MR13 the change described by Item #162 caused an existing
+ feature of antlr to fail. Prior to the change it was possible
+ to give regular expression definitions and actions to tokens
+ which were defined via the #tokdefs directive.
+
+ This now works again.
+
+ Reported by Manfred Kogler (km cast.uni-linz.ac.at).
+
+#176. (Changed in MR14) Support for #line in antlr source code
+
+ Note: this was implemented by Arpad Beszedes (beszedes inf.u-szeged.hu).
+
+ In 1.33MR14 it is possible for a pre-processor to generate #line
+ directives in the antlr source and have those line numbers and file
+ names used in antlr error messages and in the #line directives
+ generated by antlr.
+
+ The #line directive may appear in the following forms:
+
+ #line ll "sss" xx xx ...
+
+ where ll represents a line number, "sss" represents the name of a file
+ enclosed in quotation marks, and xxx are arbitrary integers.
+
+ The following form (without "line") is not supported at the moment:
+
+ # ll "sss" xx xx ...
+
+ The result:
+
+ zzline
+
+ is replaced with ll from the # or #line directive
+
+ FileStr[CurFile]
+
+ is updated with the contents of the string (if any)
+ following the line number
+
+ Note
+ ----
+ The file-name string following the line number can be a complete
+ name with a directory-path. Antlr generates the output files from
+ the input file name (by replacing the extension from the file-name
+ with .c or .cpp).
+
+ If the input file (or the file-name from the line-info) contains
+ a path:
+
+ "../grammar.g"
+
+ the generated source code will be placed in "../grammar.cpp" (i.e.
+ in the parent directory). This is inconvenient in some cases
+ (even the -o switch can not be used) so the path information is
+ removed from the #line directive. Thus, if the line-info was
+
+ #line 2 "../grammar.g"
+
+ then the current file-name will become "grammar.g"
+
+ In this way, the generated source code according to the grammar file
+ will always be in the current directory, except when the -o switch
+ is used.
+
+#175. (Changed in MR14) Bug when guess block appears at start of (...)*
+
+ In 1.33 vanilla and all maintenance releases prior to 1.33MR14
+ there is a bug when a guess block appears at the start of a (...)+.
+ Consider the following k=1 (ck=1) grammar:
+
+ rule :
+ ( (STAR)? ZIP )* ID ;
+
+ Prior to 1.33MR14, the generated code resembled:
+
+ ...
+ zzGUESS_BLOCK
+ while ( 1 ) {
+ if ( ! LA(1)==STAR) break;
+ zzGUESS
+ if ( !zzrv ) {
+ zzmatch(STAR);
+ zzCONSUME;
+ zzGUESS_DONE
+ zzmatch(ZIP);
+ zzCONSUME;
+ ...
+
+ Note that the routine uses STAR for the prediction expression
+ rather than ZIP. With 1.33MR14 the generated code resembles:
+
+ ...
+ while ( 1 ) {
+ if ( ! LA(1)==ZIP) break;
+ ...
+
+ This problem existed only with (...)* blocks and was caused
+ by the slightly more complicated graph which represents (...)*
+ blocks. This caused the analysis routine to compute the first
+ set for the alpha part of the "(alpha)? beta" rather than the
+ beta part.
+
+ Both (...)+ and {...} blocks handled the guess block correctly.
+
+ Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided
+ a very clear example of the problem and identified the probable cause.
+
+#174. (Changed in MR14) Bug when action precedes syntactic predicate
+
+ In 1.33 vanilla, and all maintenance releases prior to MR14,
+ there was a bug when a syntactic predicate was immediately
+ preceded by an action. Consider the following -ck 2 grammar:
+
+ rule :
+ <<int i;>>
+ (alpha)? beta C
+ | A B
+ ;
+
+ alpha : A ;
+ beta : A B;
+
+ Prior to MR14, the code generated for the first alternative
+ resembled:
+
+ ...
+ zzGUESS
+ if ( !zzrv && LA(1)==A && LA(2)==A) {
+ alpha();
+ zzGUESS_DONE
+ beta();
+ zzmatch(C);
+ zzCONSUME;
+ } else {
+ ...
+
+ The prediction expression (i.e. LA(1)==A && LA(2)==A) is clearly
+ wrong because LA(2) should be matched to B (first[2] of beta is {B}).
+
+ With 1.33MR14 the prediction expression is:
+
+ ...
+ if ( !zzrv && LA(1)==A && LA(2)==B) {
+ alpha();
+ zzGUESS_DONE
+ beta();
+ zzmatch(C);
+ zzCONSUME;
+ } else {
+ ...
+
+ This will only affect users in which alpha is shorter than
+ than max(k,ck) and there is an action immediately preceding
+ the syntactic predicate.
+
+ This problem was reported by reported by Arpad Beszedes
+ (beszedes inf.u-szeged.hu) who provided a very clear example
+ of the problem and identified the presence of the init-action
+ as the likely culprit.
+
+#173. (Changed in MR13a) -glms for Microsoft style filenames with -gl
+
+ With the -gl option antlr generates #line directives using the
+ exact name of the input files specified on the command line.
+ An oddity of the Microsoft C and C++ compilers is that they
+ don't accept file names in #line directives containing "\"
+ even though these are names from the native file system.
+
+ With -glms option, the "\" in file names appearing in #line
+ directives is replaced with a "/" in order to conform to
+ Microsoft compiler requirements.
+
+ Reported by Erwin Achermann (erwin.achermann switzerland.org).
+
+#172. (Changed in MR13) \r\n in antlr source counted as one line
+
+ Some MS software uses \r\n to indicate a new line. Antlr
+ now recognizes this in counting lines.
+
+ Reported by Edward L. Hepler (elh ece.vill.edu).
+
+#171. (Changed in MR13) #tokclass L..U now allowed
+
+ The following is now allowed:
+
+ #tokclass ABC { A..B C }
+
+ Reported by Dave Watola (dwatola amtsun.jpl.nasa.gov)
+
+#170. (Changed in MR13) Suppression for predicates with lookahead depth >1
+
+ In MR12 the capability for suppression of predicates with lookahead
+ depth=1 was introduced. With MR13 this had been extended to
+ predicates with lookahead depth > 1 and released for use by users
+ on an experimental basis.
+
+ Consider the following grammar with -ck 2 and the predicate in rule
+ "a" with depth 2:
+
+ r1 : (ab)* "@"
+ ;
+
+ ab : a
+ | b
+ ;
+
+ a : (A B)? => <<p(LATEXT(2))>>? A B C
+ ;
+
+ b : A B C
+ ;
+
+ Normally, the predicate would be hoisted into rule r1 in order to
+ determine whether to call rule "ab". However it should *not* be
+ hoisted because, even if p is false, there is a valid alternative
+ in rule b. With "-mrhoistk on" the predicate will be suppressed.
+
+ If "-info p" command line option is present the following information
+ will appear in the generated code:
+
+ while ( (LA(1)==A)
+ #if 0
+
+ Part (or all) of predicate with depth > 1 suppressed by alternative
+ without predicate
+
+ pred << p(LATEXT(2))>>?
+ depth=k=2 ("=>" guard) rule a line 8 t1.g
+ tree context:
+ (root = A
+ B
+ )
+
+ The token sequence which is suppressed: ( A B )
+ The sequence of references which generate that sequence of tokens:
+
+ 1 to ab r1/1 line 1 t1.g
+ 2 ab ab/1 line 4 t1.g
+ 3 to b ab/2 line 5 t1.g
+ 4 b b/1 line 11 t1.g
+ 5 #token A b/1 line 11 t1.g
+ 6 #token B b/1 line 11 t1.g
+
+ #endif
+
+ A slightly more complicated example:
+
+ r1 : (ab)* "@"
+ ;
+
+ ab : a
+ | b
+ ;
+
+ a : (A B)? => <<p(LATEXT(2))>>? (A B | D E)
+ ;
+
+ b : <<q(LATEXT(2))>>? D E
+ ;
+
+
+ In this case, the sequence (D E) in rule "a" which lies behind
+ the guard is used to suppress the predicate with context (D E)
+ in rule b.
+
+ while ( (LA(1)==A || LA(1)==D)
+ #if 0
+
+ Part (or all) of predicate with depth > 1 suppressed by alternative
+ without predicate
+
+ pred << q(LATEXT(2))>>?
+ depth=k=2 rule b line 11 t2.g
+ tree context:
+ (root = D
+ E
+ )
+
+ The token sequence which is suppressed: ( D E )
+ The sequence of references which generate that sequence of tokens:
+
+ 1 to ab r1/1 line 1 t2.g
+ 2 ab ab/1 line 4 t2.g
+ 3 to a ab/1 line 4 t2.g
+ 4 a a/1 line 8 t2.g
+ 5 #token D a/1 line 8 t2.g
+ 6 #token E a/1 line 8 t2.g
+
+ #endif
+ &&
+ #if 0
+
+ pred << p(LATEXT(2))>>?
+ depth=k=2 ("=>" guard) rule a line 8 t2.g
+ tree context:
+ (root = A
+ B
+ )
+
+ #endif
+
+ (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) ) {
+ ab();
+ ...
+
+#169. (Changed in MR13) Predicate test optimization for depth=1 predicates
+
+ When the MR12 generated a test of a predicate which had depth 1
+ it would use the depth >1 routines, resulting in correct but
+ inefficient behavior. In MR13, a bit test is used.
+
+#168. (Changed in MR13) Token expressions in context guards
+
+ The token expressions appearing in context guards such as:
+
+ (A B)? => <<test(LT(1))>>? someRule
+
+ are computed during an early phase of antlr processing. As
+ a result, prior to MR13, complex expressions such as:
+
+ ~B
+ L..U
+ ~L..U
+ TokClassName
+ ~TokClassName
+
+ were not computed properly. This resulted in incorrect
+ context being computed for such expressions.
+
+ In MR13 these context guards are verified for proper semantics
+ in the initial phase and then re-evaluated after complex token
+ expressions have been computed in order to produce the correct
+ behavior.
+
+ Reported by Arpad Beszedes (beszedes inf.u-szeged.hu).
+
+#167. (Changed in MR13) ~L..U
+
+ Prior to MR13, the complement of a token range was
+ not properly computed.
+
+#166. (Changed in MR13) token expression L..U
+
+ The token U was represented as an unsigned char, restricting
+ the use of L..U to cases where U was assigned a token number
+ less than 256. This is corrected in MR13.
+
+#165. (Changed in MR13) option -newAST
+
+ To create ASTs from an ANTLRTokenPtr antlr usually calls
+ "new AST(ANTLRTokenPtr)". This option generates a call
+ to "newAST(ANTLRTokenPtr)" instead. This allows a user
+ to define a parser member function to create an AST object.
+
+ Similar changes for ASTBase::tmake and ASTBase::link were not
+ thought necessary since they do not create AST objects, only
+ use existing ones.
+
+#164. (Changed in MR13) Unused variable _astp
+
+ For many compilations, we have lived with warnings about
+ the unused variable _astp. It turns out that this variable
+ can *never* be used because the code which references it was
+ commented out.
+
+ This investigation was sparked by a note from Erwin Achermann
+ (erwin.achermann switzerland.org).
+
+#163. (Changed in MR13) Incorrect makefiles for testcpp examples
+
+ All the examples in pccts/testcpp/* had incorrect definitions
+ in the makefiles for the symbol "CCC". Instead of CCC=CC they
+ had CC=$(CCC).
+
+ There was an additional problem in testcpp/1/test.g due to the
+ change in ANTLRToken::getText() to a const member function
+ (Item #137).
+
+ Reported by Maurice Mass (maas cuci.nl).
+
+#162. (Changed in MR13) Combining #token with #tokdefs
+
+ When it became possible to change the print-name of a
+ #token (Item #148) it became useful to give a #token
+ statement whose only purpose was to giving a print name
+ to the #token. Prior to this change this could not be
+ combined with the #tokdefs feature.
+
+#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h
+
+#160. (Changed in MR13) Omissions in list of names for remap.h
+
+ When a user selects the -gp option antlr creates a list
+ of macros in remap.h to rename some of the standard
+ antlr routines from zzXXX to userprefixXXX.
+
+ There were number of omissions from the remap.h name
+ list related to the new trace facility. This was reported,
+ along with a fix, by Bernie Solomon (bernard ug.eds.com).
+
+#159. (Changed in MR13) Violations of classic C rules
+
+ There were a number of violations of classic C style in
+ the distribution kit. This was reported, along with fixes,
+ by Bernie Solomon (bernard ug.eds.com).
+
+#158. (Changed in MR13) #header causes problem for pre-processors
+
+ A user who runs the C pre-processor on antlr source suggested
+ that another syntax be allowed. With MR13 such directives
+ such as #header, #pragma, etc. may be written as "\#header",
+ "\#pragma", etc. For escaping pre-processor directives inside
+ a #header use something like the following:
+
+ \#header
+ <<
+ \#include <stdio.h>
+ >>
+
+#157. (Fixed in MR13) empty error sets for rules with infinite recursion
+
+ When the first set for a rule cannot be computed due to infinite
+ left recursion and it is the only alternative for a block then
+ the error set for the block would be empty. This would result
+ in a fatal error.
+
+ Reported by Darin Creason (creason genedax.com)
+
+#156. (Changed in MR13) DLGLexerBase::getToken() now public
+
+#155. (Changed in MR13) Context behind predicates can suppress
+
+ With -mrhoist enabled the context behind a guarded predicate can
+ be used to suppress other predicates. Consider the following grammar:
+
+ r0 : (r1)+;
+
+ r1 : rp
+ | rq
+ ;
+ rp : <<p LATEXT(1)>>? B ;
+ rq : (A)? => <<q LATEXT(1)>>? (A|B);
+
+ In earlier versions both predicates "p" and "q" would be hoisted into
+ rule r0. With MR12c predicate p is suppressed because the context which
+ follows predicate q includes "B" which can "cover" predicate "p". In
+ other words, in trying to decide in r0 whether to call r1, it doesn't
+ really matter whether p is false or true because, either way, there is
+ a valid choice within r1.
+
+#154. (Changed in MR13) Making hoist suppression explicit using <<nohoist>>
+
+ A common error, even among experienced pccts users, is to code
+ an init-action to inhibit hoisting rather than a leading action.
+ An init-action does not inhibit hoisting.
+
+ This was coded:
+
+ rule1 : <<;>> rule2
+
+ This is what was meant:
+
+ rule1 : <<;>> <<;>> rule2
+
+ With MR13, the user can code:
+
+ rule1 : <<;>> <<nohoist>> rule2
+
+ The following will give an error message:
+
+ rule1 : <<nohoist>> rule2
+
+ If the <<nohoist>> appears as an init-action rather than a leading
+ action an error message is issued. The meaning of an init-action
+ containing "nohoist" is unclear: does it apply to just one
+ alternative or to all alternatives ?
+
+
+
+
+
+
+
+
+ -------------------------------------------------------
+ Note: Items #153 to #1 are now in a separate file named
+ CHANGES_FROM_133_BEFORE_MR13.txt
+ -------------------------------------------------------
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt
new file mode 100644
index 00000000..56bced8c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt
@@ -0,0 +1,3666 @@
+
+ ------------------------------------------------------------
+ This is the second part of a two part file.
+ This is a list of changes to pccts 1.33 prior to MR13
+ For more recent information see CHANGES_FROM_133.txt
+ ------------------------------------------------------------
+
+ DISCLAIMER
+
+ The software and these notes are provided "as is". They may include
+ typographical or technical errors and their authors disclaims all
+ liability of any kind or nature for damages due to error, fault,
+ defect, or deficiency regardless of cause. All warranties of any
+ kind, either express or implied, including, but not limited to, the
+ implied warranties of merchantability and fitness for a particular
+ purpose are disclaimed.
+
+
+#153. (Changed in MR12b) Bug in computation of -mrhoist suppression set
+
+ Consider the following grammar with k=1 and "-mrhoist on":
+
+ r1 : (A)? => ((p>>? x /* l1 */
+ | r2 /* l2 */
+ ;
+ r2 : A /* l4 */
+ | (B)? => <<q>>? y /* l5 */
+ ;
+
+ In earlier versions the mrhoist routine would see that both l1 and
+ l2 contained predicates and would assume that this prevented either
+ from acting to suppress the other predicate. In the example above
+ it didn't realize the A at line l4 is capable of suppressing the
+ predicate at l1 even though alt l2 contains (indirectly) a predicate.
+
+ This is fixed in MR12b.
+
+ Reported by Reinier van den Born (reinier@vnet.ibm.com)
+
+#153. (Changed in MR12a) Bug in computation of -mrhoist suppression set
+
+ An oversight similar to that described in Item #152 appeared in
+ the computation of the set that "covered" a predicate. If a
+ predicate expression included a term such as p=AND(q,r) the context
+ of p was taken to be context(q) & context(r), when it should have
+ been context(q) | context(r). This is fixed in MR12a.
+
+#152. (Changed in MR12) Bug in generation of predicate expressions
+
+ The primary purpose for MR12 is to make quite clear that MR11 is
+ obsolete and to fix the bug related to predicate expressions.
+
+ In MR10 code was added to optimize the code generated for
+ predicate expression tests. Unfortunately, there was a
+ significant oversight in the code which resulted in a bug in
+ the generation of code for predicate expression tests which
+ contained predicates combined using AND:
+
+ r0 : (r1)* "@" ;
+ r1 : (AAA)? => <<p LATEXT(1)>>? r2 ;
+ r2 : (BBB)? => <<q LATEXT(1)>>? Q
+ | (BBB)? => <<r LATEXT(1)>>? Q
+ ;
+
+ In MR11 (and MR10 when using "-mrhoist on") the code generated
+ for r0 to predict r1 would be equivalent to:
+
+ if ( LA(1)==Q &&
+ (LA(1)==AAA && LA(1)==BBB) &&
+ ( p && ( q || r )) ) {
+
+ This is incorrect because it expresses the idea that LA(1)
+ *must* be AAA in order to attempt r1, and *must* be BBB to
+ attempt r2. The result was that r1 became unreachable since
+ both condition can not be simultaneously true.
+
+ The general philosophy of code generation for predicates
+ can be summarized as follows:
+
+ a. If the context is true don't enter an alt
+ for which the corresponding predicate is false.
+
+ If the context is false then it is okay to enter
+ the alt without evaluating the predicate at all.
+
+ b. A predicate created by ORing of predicates has
+ context which is the OR of their individual contexts.
+
+ c. A predicate created by ANDing of predicates has
+ (surprise) context which is the OR of their individual
+ contexts.
+
+ d. Apply these rules recursively.
+
+ e. Remember rule (a)
+
+ The correct code should express the idea that *if* LA(1) is
+ AAA then p must be true to attempt r1, but if LA(1) is *not*
+ AAA then it is okay to attempt r1, provided that *if* LA(1) is
+ BBB then one of q or r must be true.
+
+ if ( LA(1)==Q &&
+ ( !(LA(1)==AAA || LA(1)==BBB) ||
+ ( ! LA(1) == AAA || p) &&
+ ( ! LA(1) == BBB || q || r ) ) ) {
+
+ I believe this is fixed in MR12.
+
+ Reported by Reinier van den Born (reinier@vnet.ibm.com)
+
+#151a. (Changed in MR12) ANTLRParser::getLexer()
+
+ As a result of several requests, I have added public methods to
+ get a pointer to the lexer belonging to a parser.
+
+ ANTLRTokenStream *ANTLRParser::getLexer() const
+
+ Returns a pointer to the lexer being used by the
+ parser. ANTLRTokenStream is the base class of
+ DLGLexer
+
+ ANTLRTokenStream *ANTLRTokenBuffer::getLexer() const
+
+ Returns a pointer to the lexer being used by the
+ ANTLRTokenBuffer. ANTLRTokenStream is the base
+ class of DLGLexer
+
+ You must manually cast the ANTLRTokenStream to your program's
+ lexer class. Because the name of the lexer's class is not fixed.
+ Thus it is impossible to incorporate it into the DLGLexerBase
+ class.
+
+#151b.(Changed in MR12) ParserBlackBox member getLexer()
+
+ The template class ParserBlackBox now has a member getLexer()
+ which returns a pointer to the lexer.
+
+#150. (Changed in MR12) syntaxErrCount and lexErrCount now public
+
+ See Item #127 for more information.
+
+#149. (Changed in MR12) antlr option -info o (letter o for orphan)
+
+ If there is more than one rule which is not referenced by any
+ other rule then all such rules are listed. This is useful for
+ alerting one to rules which are not used, but which can still
+ contribute to ambiguity. For example:
+
+ start : a Z ;
+ unused: a A ;
+ a : (A)+ ;
+
+ will cause an ambiguity report for rule "a" which will be
+ difficult to understand if the user forgets about rule "unused"
+ simply because it is not used in the grammar.
+
+#148. (Changed in MR11) #token names appearing in zztokens,token_tbl
+
+ In a #token statement like the following:
+
+ #token Plus "\+"
+
+ the string "Plus" appears in the zztokens array (C mode) and
+ token_tbl (C++ mode). This string is used in most error
+ messages. In MR11 one has the option of using some other string,
+ (e.g. "+") in those tables.
+
+ In MR11 one can write:
+
+ #token Plus ("+") "\+"
+ #token RP ("(") "\("
+ #token COM ("comment begin") "/\*"
+
+ A #token statement is allowed to appear in more than one #lexclass
+ with different regular expressions. However, the token name appears
+ only once in the zztokens/token_tbl array. This means that only
+ one substitute can be specified for a given #token name. The second
+ attempt to define a substitute name (different from the first) will
+ result in an error message.
+
+#147. (Changed in MR11) Bug in follow set computation
+
+ There is a bug in 1.33 vanilla and all maintenance releases
+ prior to MR11 in the computation of the follow set. The bug is
+ different than that described in Item #82 and probably more
+ common. It was discovered in the ansi.g grammar while testing
+ the "ambiguity aid" (Item #119). The search for a bug started
+ when the ambiguity aid was unable to discover the actual source
+ of an ambiguity reported by antlr.
+
+ The problem appears when an optimization of the follow set
+ computation is used inappropriately. The result is that the
+ follow set used is the "worst case". In other words, the error
+ can lead to false reports of ambiguity. The good news is that
+ if you have a grammar in which you have addressed all reported
+ ambiguities you are ok. The bad news is that you may have spent
+ time fixing ambiguities that were not real, or used k=2 when
+ ck=2 might have been sufficient, and so on.
+
+ The following grammar demonstrates the problem:
+
+ ------------------------------------------------------------
+ expr : ID ;
+
+ start : stmt SEMI ;
+
+ stmt : CASE expr COLON
+ | expr SEMI
+ | plain_stmt
+ ;
+
+ plain_stmt : ID COLON ;
+ ------------------------------------------------------------
+
+ When compiled with k=1 and ck=2 it will report:
+
+ warning: alts 2 and 3 of the rule itself ambiguous upon
+ { IDENTIFIER }, { COLON }
+
+ When antlr analyzes "stmt" it computes the first[1] set of all
+ alternatives. It finds an ambiguity between alts 2 and 3 for ID.
+ It then computes the first[2] set for alternatives 2 and 3 to resolve
+ the ambiguity. In computing the first[2] set of "expr" (which is
+ only one token long) it needs to determine what could follow "expr".
+ Under a certain combination of circumstances antlr forgets that it
+ is trying to analyze "stmt" which can only be followed by SEMI and
+ adds to the first[2] set of "expr" the "global" follow set (including
+ "COLON") which could follow "expr" (under other conditions) in the
+ phrase "CASE expr COLON".
+
+#146. (Changed in MR11) Option -treport for locating "difficult" alts
+
+ It can be difficult to determine which alternatives are causing
+ pccts to work hard to resolve an ambiguity. In some cases the
+ ambiguity is successfully resolved after much CPU time so there
+ is no message at all.
+
+ A rough measure of the amount of work being peformed which is
+ independent of the CPU speed and system load is the number of
+ tnodes created. Using "-info t" gives information about the
+ total number of tnodes created and the peak number of tnodes.
+
+ Tree Nodes: peak 1300k created 1416k lost 0
+
+ It also puts in the generated C or C++ file the number of tnodes
+ created for a rule (at the end of the rule). However this
+ information is not sufficient to locate the alternatives within
+ a rule which are causing the creation of tnodes.
+
+ Using:
+
+ antlr -treport 100000 ....
+
+ causes antlr to list on stdout any alternatives which require the
+ creation of more than 100,000 tnodes, along with the lookahead sets
+ for those alternatives.
+
+ The following is a trivial case from the ansi.g grammar which shows
+ the format of the report. This report might be of more interest
+ in cases where 1,000,000 tuples were created to resolve the ambiguity.
+
+ -------------------------------------------------------------------------
+ There were 0 tuples whose ambiguity could not be resolved
+ by full lookahead
+ There were 157 tnodes created to resolve ambiguity between:
+
+ Choice 1: statement/2 line 475 file ansi.g
+ Choice 2: statement/3 line 476 file ansi.g
+
+ Intersection of lookahead[1] sets:
+
+ IDENTIFIER
+
+ Intersection of lookahead[2] sets:
+
+ LPARENTHESIS COLON AMPERSAND MINUS
+ STAR PLUSPLUS MINUSMINUS ONESCOMPLEMENT
+ NOT SIZEOF OCTALINT DECIMALINT
+ HEXADECIMALINT FLOATONE FLOATTWO IDENTIFIER
+ STRING CHARACTER
+ -------------------------------------------------------------------------
+
+#145. (Documentation) Generation of Expression Trees
+
+ Item #99 was misleading because it implied that the optimization
+ for tree expressions was available only for trees created by
+ predicate expressions and neglected to mention that it required
+ the use of "-mrhoist on". The optimization applies to tree
+ expressions created for grammars with k>1 and for predicates with
+ lookahead depth >1.
+
+ In MR11 the optimized version is always used so the -mrhoist on
+ option need not be specified.
+
+#144. (Changed in MR11) Incorrect test for exception group
+
+ In testing for a rule's exception group the label a pointer
+ is compared against '\0'. The intention is "*pointer".
+
+ Reported by Jeffrey C. Fried (Jeff@Fried.net).
+
+#143. (Changed in MR11) Optional ";" at end of #token statement
+
+ Fixes problem of:
+
+ #token X "x"
+
+ <<
+ parser action
+ >>
+
+ Being confused with:
+
+ #token X "x" <<lexical action>>
+
+#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream
+
+ Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class
+ BufFileInput derived from DLGInputStream which provides a
+ function lookahead(char *string) to test characters in the
+ input stream more than one character ahead.
+
+ The default amount of lookahead is specified by the constructor
+ and defaults to 8 characters. This does *not* include the one
+ character of lookahead maintained internally by DLG in member "ch"
+ and which is not available for testing via BufFileInput::lookahead().
+
+ This is a useful class for overcoming the one-character-lookahead
+ limitation of DLG without resorting to a lexer capable of
+ backtracking (like flex) which is not integrated with antlr as is
+ DLG.
+
+ There are no restrictions on copying or using BufFileInput.* except
+ that the authorship and related information must be retained in the
+ source code.
+
+ The class is located in pccts/h/BufFileInput.* of the kit.
+
+#141. (Changed in MR11) ZZDEBUG_CONSUME for ANTLRParser::consume()
+
+ A debug aid has been added to file ANTLRParser::consume() in
+ file AParser.cpp:
+
+ #ifdef ZZDEBUG_CONSUME_ACTION
+ zzdebug_consume_action();
+ #endif
+
+ Suggested by Sramji Ramanathan (ps@kumaran.com).
+
+#140. (Changed in MR11) #pred to define predicates
+
+ +---------------------------------------------------+
+ | Note: Assume "-prc on" for this entire discussion |
+ +---------------------------------------------------+
+
+ A problem with predicates is that each one is regarded as
+ unique and capable of disambiguating cases where two
+ alternatives have identical lookahead. For example:
+
+ rule : <<pred(LATEXT(1))>>? A
+ | <<pred(LATEXT(1))>>? A
+ ;
+
+ will not cause any error messages or warnings to be issued
+ by earlier versions of pccts. To compare the text of the
+ predicates is an incomplete solution.
+
+ In 1.33MR11 I am introducing the #pred statement in order to
+ solve some problems with predicates. The #pred statement allows
+ one to give a symbolic name to a "predicate literal" or a
+ "predicate expression" in order to refer to it in other predicate
+ expressions or in the rules of the grammar.
+
+ The predicate literal associated with a predicate symbol is C
+ or C++ code which can be used to test the condition. A
+ predicate expression defines a predicate symbol in terms of other
+ predicate symbols using "!", "&&", and "||". A predicate symbol
+ can be defined in terms of a predicate literal, a predicate
+ expression, or *both*.
+
+ When a predicate symbol is defined with both a predicate literal
+ and a predicate expression, the predicate literal is used to generate
+ code, but the predicate expression is used to check for two
+ alternatives with identical predicates in both alternatives.
+
+ Here are some examples of #pred statements:
+
+ #pred IsLabel <<isLabel(LATEXT(1))>>?
+ #pred IsLocalVar <<isLocalVar(LATEXT(1))>>?
+ #pred IsGlobalVar <<isGlobalVar(LATEXT(1)>>?
+ #pred IsVar <<isVar(LATEXT(1))>>? IsLocalVar || IsGlobalVar
+ #pred IsScoped <<isScoped(LATEXT(1))>>? IsLabel || IsLocalVar
+
+ I hope that the use of EBNF notation to describe the syntax of the
+ #pred statement will not cause problems for my readers (joke).
+
+ predStatement : "#pred"
+ CapitalizedName
+ (
+ "<<predicate_literal>>?"
+ | "<<predicate_literal>>?" predOrExpr
+ | predOrExpr
+ )
+ ;
+
+ predOrExpr : predAndExpr ( "||" predAndExpr ) * ;
+
+ predAndExpr : predPrimary ( "&&" predPrimary ) * ;
+
+ predPrimary : CapitalizedName
+ | "!" predPrimary
+ | "(" predOrExpr ")"
+ ;
+
+ What is the purpose of this nonsense ?
+
+ To understand how predicate symbols help, you need to realize that
+ predicate symbols are used in two different ways with two different
+ goals.
+
+ a. Allow simplification of predicates which have been combined
+ during predicate hoisting.
+
+ b. Allow recognition of identical predicates which can't disambiguate
+ alternatives with common lookahead.
+
+ First we will discuss goal (a). Consider the following rule:
+
+ rule0: rule1
+ | ID
+ | ...
+ ;
+
+ rule1: rule2
+ | rule3
+ ;
+
+ rule2: <<isX(LATEXT(1))>>? ID ;
+ rule3: <<!isX(LATEXT(1)>>? ID ;
+
+ When the predicates in rule2 and rule3 are combined by hoisting
+ to create a prediction expression for rule1 the result is:
+
+ if ( LA(1)==ID
+ && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ...
+
+ This is inefficient, but more importantly, can lead to false
+ assumptions that the predicate expression distinguishes the rule1
+ alternative with some other alternative with lookahead ID. In
+ MR11 one can write:
+
+ #pred IsX <<isX(LATEXT(1))>>?
+
+ ...
+
+ rule2: <<IsX>>? ID ;
+ rule3: <<!IsX>>? ID ;
+
+ During hoisting MR11 recognizes this as a special case and
+ eliminates the predicates. The result is a prediction
+ expression like the following:
+
+ if ( LA(1)==ID ) { rule1(); ...
+
+ Please note that the following cases which appear to be equivalent
+ *cannot* be simplified by MR11 during hoisting because the hoisting
+ logic only checks for a "!" in the predicate action, not in the
+ predicate expression for a predicate symbol.
+
+ *Not* equivalent and is not simplified during hoisting:
+
+ #pred IsX <<isX(LATEXT(1))>>?
+ #pred NotX <<!isX(LATEXT(1))>>?
+ ...
+ rule2: <<IsX>>? ID ;
+ rule3: <<NotX>>? ID ;
+
+ *Not* equivalent and is not simplified during hoisting:
+
+ #pred IsX <<isX(LATEXT(1))>>?
+ #pred NotX !IsX
+ ...
+ rule2: <<IsX>>? ID ;
+ rule3: <<NotX>>? ID ;
+
+ Now we will discuss goal (b).
+
+ When antlr discovers that there is a lookahead ambiguity between
+ two alternatives it attempts to resolve the ambiguity by searching
+ for predicates in both alternatives. In the past any predicate
+ would do, even if the same one appeared in both alternatives:
+
+ rule: <<p(LATEXT(1))>>? X
+ | <<p(LATEXT(1))>>? X
+ ;
+
+ The #pred statement is a start towards solving this problem.
+ During ambiguity resolution (*not* predicate hoisting) the
+ predicates for the two alternatives are expanded and compared.
+ Consider the following example:
+
+ #pred Upper <<isUpper(LATEXT(1))>>?
+ #pred Lower <<isLower(LATEXT(1))>>?
+ #pred Alpha <<isAlpha(LATEXT(1))>>? Upper || Lower
+
+ rule0: rule1
+ | <<Alpha>>? ID
+ ;
+
+ rule1:
+ | rule2
+ | rule3
+ ...
+ ;
+
+ rule2: <<Upper>>? ID;
+ rule3: <<Lower>>? ID;
+
+ The definition of #pred Alpha expresses:
+
+ a. to test the predicate use the C code "isAlpha(LATEXT(1))"
+
+ b. to analyze the predicate use the information that
+ Alpha is equivalent to the union of Upper and Lower,
+
+ During ambiguity resolution the definition of Alpha is expanded
+ into "Upper || Lower" and compared with the predicate in the other
+ alternative, which is also "Upper || Lower". Because they are
+ identical MR11 will report a problem.
+
+ -------------------------------------------------------------------------
+ t10.g, line 5: warning: the predicates used to disambiguate rule rule0
+ (file t10.g alt 1 line 5 and alt 2 line 6)
+ are identical when compared without context and may have no
+ resolving power for some lookahead sequences.
+ -------------------------------------------------------------------------
+
+ If you use the "-info p" option the output file will contain:
+
+ +----------------------------------------------------------------------+
+ |#if 0 |
+ | |
+ |The following predicates are identical when compared without |
+ | lookahead context information. For some ambiguous lookahead |
+ | sequences they may not have any power to resolve the ambiguity. |
+ | |
+ |Choice 1: rule0/1 alt 1 line 5 file t10.g |
+ | |
+ | The original predicate for choice 1 with available context |
+ | information: |
+ | |
+ | OR expr |
+ | |
+ | pred << Upper>>? |
+ | depth=k=1 rule rule2 line 14 t10.g |
+ | set context: |
+ | ID |
+ | |
+ | pred << Lower>>? |
+ | depth=k=1 rule rule3 line 15 t10.g |
+ | set context: |
+ | ID |
+ | |
+ | The predicate for choice 1 after expansion (but without context |
+ | information): |
+ | |
+ | OR expr |
+ | |
+ | pred << isUpper(LATEXT(1))>>? |
+ | depth=k=1 rule line 1 t10.g |
+ | |
+ | pred << isLower(LATEXT(1))>>? |
+ | depth=k=1 rule line 2 t10.g |
+ | |
+ | |
+ |Choice 2: rule0/2 alt 2 line 6 file t10.g |
+ | |
+ | The original predicate for choice 2 with available context |
+ | information: |
+ | |
+ | pred << Alpha>>? |
+ | depth=k=1 rule rule0 line 6 t10.g |
+ | set context: |
+ | ID |
+ | |
+ | The predicate for choice 2 after expansion (but without context |
+ | information): |
+ | |
+ | OR expr |
+ | |
+ | pred << isUpper(LATEXT(1))>>? |
+ | depth=k=1 rule line 1 t10.g |
+ | |
+ | pred << isLower(LATEXT(1))>>? |
+ | depth=k=1 rule line 2 t10.g |
+ | |
+ | |
+ |#endif |
+ +----------------------------------------------------------------------+
+
+ The comparison of the predicates for the two alternatives takes
+ place without context information, which means that in some cases
+ the predicates will be considered identical even though they operate
+ on disjoint lookahead sets. Consider:
+
+ #pred Alpha
+
+ rule1: <<Alpha>>? ID
+ | <<Alpha>>? Label
+ ;
+
+ Because the comparison of predicates takes place without context
+ these will be considered identical. The reason for comparing
+ without context is that otherwise it would be necessary to re-evaluate
+ the entire predicate expression for each possible lookahead sequence.
+ This would require more code to be written and more CPU time during
+ grammar analysis, and it is not yet clear whether anyone will even make
+ use of the new #pred facility.
+
+ A temporary workaround might be to use different #pred statements
+ for predicates you know have different context. This would avoid
+ extraneous warnings.
+
+ The above example might be termed a "false positive". Comparison
+ without context will also lead to "false negatives". Consider the
+ following example:
+
+ #pred Alpha
+ #pred Beta
+
+ rule1: <<Alpha>>? A
+ | rule2
+ ;
+
+ rule2: <<Alpha>>? A
+ | <<Beta>>? B
+ ;
+
+ The predicate used for alt 2 of rule1 is (Alpha || Beta). This
+ appears to be different than the predicate Alpha used for alt1.
+ However, the context of Beta is B. Thus when the lookahead is A
+ Beta will have no resolving power and Alpha will be used for both
+ alternatives. Using the same predicate for both alternatives isn't
+ very helpful, but this will not be detected with 1.33MR11.
+
+ To properly handle this the predicate expression would have to be
+ evaluated for each distinct lookahead context.
+
+ To determine whether two predicate expressions are identical is
+ difficult. The routine may fail to identify identical predicates.
+
+ The #pred feature also compares predicates to see if a choice between
+ alternatives which is resolved by a predicate which makes the second
+ choice unreachable. Consider the following example:
+
+ #pred A <<A(LATEXT(1)>>?
+ #pred B <<B(LATEXT(1)>>?
+ #pred A_or_B A || B
+
+ r : s
+ | t
+ ;
+ s : <<A_or_B>>? ID
+ ;
+ t : <<A>>? ID
+ ;
+
+ ----------------------------------------------------------------------------
+ t11.g, line 5: warning: the predicate used to disambiguate the
+ first choice of rule r
+ (file t11.g alt 1 line 5 and alt 2 line 6)
+ appears to "cover" the second predicate when compared without context.
+ The second predicate may have no resolving power for some lookahead
+ sequences.
+ ----------------------------------------------------------------------------
+
+#139. (Changed in MR11) Problem with -gp in C++ mode
+
+ The -gp option to add a prefix to rule names did not work in
+ C++ mode. This has been fixed.
+
+ Reported by Alexey Demakov (demakov@kazbek.ispras.ru).
+
+#138. (Changed in MR11) Additional makefiles for non-MSVC++ MS systems
+
+ Sramji Ramanathan (ps@kumaran.com) has supplied makefiles for
+ building antlr and dlg with Win95/NT development tools that
+ are not based on MSVC5. They are pccts/antlr/AntlrMS.mak and
+ pccts/dlg/DlgMS.mak.
+
+ The first line of the makefiles require a definition of PCCTS_HOME.
+
+ These are in addition to the AntlrMSVC50.* and DlgMSVC50.*
+ supplied by Jeff Vincent (JVincent@novell.com).
+
+#137. (Changed in MR11) Token getType(), getText(), getLine() const members
+
+ --------------------------------------------------------------------
+ If you use ANTLRCommonToken this change probably does not affect you.
+ --------------------------------------------------------------------
+
+ For a long time it has bothered me that these accessor functions
+ in ANTLRAbstractToken were not const member functions. I have
+ refrained from changing them because it require users to modify
+ existing token class definitions which are derived directly
+ from ANTLRAbstractToken. I think it is now time.
+
+ For those who are not used to C++, a "const member function" is a
+ member function which does not modify its own object - the thing
+ to which "this" points. This is quite different from a function
+ which does not modify its arguments
+
+ Most token definitions based on ANTLRAbstractToken have something like
+ the following in order to create concrete definitions of the pure
+ virtual methods in ANTLRAbstractToken:
+
+ class MyToken : public ANTLRAbstractToken {
+ ...
+ ANTLRTokenType getType() {return _type; }
+ int getLine() {return _line; }
+ ANTLRChar * getText() {return _text; }
+ ...
+ }
+
+ The required change is simply to put "const" following the function
+ prototype in the header (.h file) and the definition file (.cpp if
+ it is not inline):
+
+ class MyToken : public ANTLRAbstractToken {
+ ...
+ ANTLRTokenType getType() const {return _type; }
+ int getLine() const {return _line; }
+ ANTLRChar * getText() const {return _text; }
+ ...
+ }
+
+ This was originally proposed a long time ago by Bruce
+ Guenter (bruceg@qcc.sk.ca).
+
+#136. (Changed in MR11) Added getLength() to ANTLRCommonToken
+
+ Classes ANTLRCommonToken and ANTLRCommonTokenNoRefCountToken
+ now have a member function:
+
+ int getLength() const { return strlen(getText()) }
+
+ Suggested by Sramji Ramanathan (ps@kumaran.com).
+
+#135. (Changed in MR11) Raised antlr's own default ZZLEXBUFSIZE to 8k
+
+#134a. (ansi_mr10.zip) T.J. Parr's ANSI C grammar made 1.33MR11 compatible
+
+ There is a typographical error in the definition of BITWISEOREQ:
+
+ #token BITWISEOREQ "!=" should be "\|="
+
+ When this change is combined with the bugfix to the follow set cache
+ problem (Item #147) and a minor rearrangement of the grammar
+ (Item #134b) it becomes a k=1 ck=2 grammar.
+
+#134b. (ansi_mr10.zip) T.J. Parr's ANSI C grammar made 1.33MR11 compatible
+
+ The following changes were made in the ansi.g grammar (along with
+ using -mrhoist on):
+
+ ansi.g
+ ======
+ void tracein(char *) ====> void tracein(const char *)
+ void traceout(char *) ====> void traceout(const char *)
+
+ <LT(1)->getType()==IDENTIFIER ? isTypeName(LT(1)->getText()) : 1>>?
+ ====> <<isTypeName(LT(1)->getText())>>?
+
+ <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \
+ isTypeName(LT(2)->getText()) : 1>>?
+ ====> (LPARENTHESIS IDENTIFIER)? => <<isTypeName(LT(2)->getText())>>?
+
+ <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \
+ isTypeName(LT(2)->getText()) : 1>>?
+ ====> (LPARENTHESIS IDENTIFIER)? => <<isTypeName(LT(2)->getText())>>?
+
+ added to init(): traceOptionValueDefault=0;
+ added to init(): traceOption(-1);
+
+ change rule "statement":
+
+ statement
+ : plain_label_statement
+ | case_label_statement
+ | <<;>> expression SEMICOLON
+ | compound_statement
+ | selection_statement
+ | iteration_statement
+ | jump_statement
+ | SEMICOLON
+ ;
+
+ plain_label_statement
+ : IDENTIFIER COLON statement
+ ;
+
+ case_label_statement
+ : CASE constant_expression COLON statement
+ | DEFAULT COLON statement
+ ;
+
+ support.cpp
+ ===========
+ void tracein(char *) ====> void tracein(const char *)
+ void traceout(char *) ====> void traceout(const char *)
+
+ added to tracein(): ANTLRParser::tracein(r); // call superclass method
+ added to traceout(): ANTLRParser::traceout(r); // call superclass method
+
+ Makefile
+ ========
+ added to AFLAGS: -mrhoist on -prc on
+
+#133. (Changed in 1.33MR11) Make trace options public in ANTLRParser
+
+ In checking T.J. Parr's ANSI C grammar for compatibility with
+ 1.33MR11 discovered that it was inconvenient to have the
+ trace facilities with protected access.
+
+#132. (Changed in 1.33MR11) Recognition of identical predicates in alts
+
+ Prior to 1.33MR11, there would be no ambiguity warning when the
+ very same predicate was used to disambiguate both alternatives:
+
+ test: ref B
+ | ref C
+ ;
+
+ ref : <<pred(LATEXT(1)>>? A
+
+ In 1.33MR11 this will cause the warning:
+
+ warning: the predicates used to disambiguate rule test
+ (file v98.g alt 1 line 1 and alt 2 line 2)
+ are identical and have no resolving power
+
+ ----------------- Note -----------------
+
+ This is different than the following case
+
+ test: <<pred(LATEXT(1))>>? A B
+ | <<pred(LATEXT(1)>>? A C
+ ;
+
+ In this case there are two distinct predicates
+ which have exactly the same text. In the first
+ example there are two references to the same
+ predicate. The problem represented by this
+ grammar will be addressed later.
+
+#131. (Changed in 1.33MR11) Case insensitive command line options
+
+ Command line switches like "-CC" and keywords like "on", "off",
+ and "stdin" are no longer case sensitive in antlr, dlg, and sorcerer.
+
+#130. (Changed in 1.33MR11) Changed ANTLR_VERSION to int from string
+
+ The ANTLR_VERSION was not an integer, making it difficult to
+ perform conditional compilation based on the antlr version.
+
+ Henceforth, ANTLR_VERSION will be:
+
+ (base_version * 10000) + release number
+
+ thus 1.33MR11 will be: 133*100+11 = 13311
+
+ Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE).
+
+#129. (Changed in 1.33MR11) Addition of ANTLR_VERSION to <parserName>.h
+
+ The following code is now inserted into <parserName>.h amd
+ stdpccts.h:
+
+ #ifndef ANTLR_VERSION
+ #define ANTLR_VERSION 13311
+ #endif
+
+ Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE)
+
+#128. (Changed in 1.33MR11) Redundant predicate code in (<<pred>>? ...)+
+
+ Prior to 1.33MR11, the following grammar would generate
+ redundant tests for the "while" condition.
+
+ rule2 : (<<pred>>? X)+ X
+ | B
+ ;
+
+ The code would resemble:
+
+ if (LA(1)==X) {
+ if (pred) {
+ do {
+ if (!pred) {zzfailed_pred(" pred");}
+ zzmatch(X); zzCONSUME;
+ } while (LA(1)==X && pred && pred);
+ } else {...
+
+ With 1.33MR11 the redundant predicate test is omitted.
+
+#127. (Changed in 1.33MR11)
+
+ Count Syntax Errors Count DLG Errors
+ ------------------- ----------------
+
+ C++ mode ANTLRParser:: DLGLexerBase::
+ syntaxErrCount lexErrCount
+ C mode zzSyntaxErrCount zzLexErrCount
+
+ The C mode variables are global and initialized to 0.
+ They are *not* reset to 0 automatically when antlr is
+ restarted.
+
+ The C++ mode variables are public. They are initialized
+ to 0 by the constructors. They are *not* reset to 0 by the
+ ANTLRParser::init() method.
+
+ Suggested by Reinier van den Born (reinier@vnet.ibm.com).
+
+#126. (Changed in 1.33MR11) Addition of #first <<...>>
+
+ The #first <<...>> inserts the specified text in the output
+ files before any other #include statements required by pccts.
+ The only things before the #first text are comments and
+ a #define ANTLR_VERSION.
+
+ Requested by and Esa Pulkkinen (esap@cs.tut.fi) and Alexin
+ Zoltan (alexin@inf.u-szeged.hu).
+
+#125. (Changed in 1.33MR11) Lookahead for (guard)? && <<p>>? predicates
+
+ When implementing the new style of guard predicate (Item #113)
+ in 1.33MR10 I decided to temporarily ignore the problem of
+ computing the "narrowest" lookahead context.
+
+ Consider the following k=1 grammar:
+
+ start : a
+ | b
+ ;
+
+ a : (A)? && <<pred1(LATEXT(1))>>? ab ;
+ b : (B)? && <<pred2(LATEXT(1))>>? ab ;
+
+ ab : A | B ;
+
+ In MR10 the context for both "a" and "b" was {A B} because this is
+ the first set of rule "ab". Normally, this is not a problem because
+ the predicate which follows the guard inhibits any ambiguity report
+ by antlr.
+
+ In MR11 the first set for rule "a" is {A} and for rule "b" it is {B}.
+
+#124. A Note on the New "&&" Style Guarded Predicates
+
+ I've been asked several times, "What is the difference between
+ the old "=>" style guard predicates and the new style "&&" guard
+ predicates, and how do you choose one over the other" ?
+
+ The main difference is that the "=>" does not apply the
+ predicate if the context guard doesn't match, whereas
+ the && form always does. What is the significance ?
+
+ If you have a predicate which is not on the "leading edge"
+ it cannot be hoisted. Suppose you need a predicate that
+ looks at LA(2). You must introduce it manually. The
+ classic example is:
+
+ castExpr :
+ LP typeName RP
+ | ....
+ ;
+
+ typeName : <<isTypeName(LATEXT(1))>>? ID
+ | STRUCT ID
+ ;
+
+ The problem is that typeName isn't on the leading edge
+ of castExpr, so the predicate isTypeName won't be hoisted into
+ castExpr to help make a decision on which production to choose.
+
+ The *first* attempt to fix it is this:
+
+ castExpr :
+ <<isTypeName(LATEXT(2))>>?
+ LP typeName RP
+ | ....
+ ;
+
+ Unfortunately, this won't work because it ignores
+ the problem of STRUCT. The solution is to apply
+ isTypeName() in castExpr if LA(2) is an ID and
+ don't apply it when LA(2) is STRUCT:
+
+ castExpr :
+ (LP ID)? => <<isTypeName(LATEXT(2))>>?
+ LP typeName RP
+ | ....
+ ;
+
+ In conclusion, the "=>" style guarded predicate is
+ useful when:
+
+ a. the tokens required for the predicate
+ are not on the leading edge
+ b. there are alternatives in the expression
+ selected by the predicate for which the
+ predicate is inappropriate
+
+ If (b) were false, then one could use a simple
+ predicate (assuming "-prc on"):
+
+ castExpr :
+ <<isTypeName(LATEXT(2))>>?
+ LP typeName RP
+ | ....
+ ;
+
+ typeName : <<isTypeName(LATEXT(1))>>? ID
+ ;
+
+ So, when do you use the "&&" style guarded predicate ?
+
+ The new-style "&&" predicate should always be used with
+ predicate context. The context guard is in ADDITION to
+ the automatically computed context. Thus it useful for
+ predicates which depend on the token type for reasons
+ other than context.
+
+ The following example is contributed by Reinier van den Born
+ (reinier@vnet.ibm.com).
+
+ +-------------------------------------------------------------------------+
+ | This grammar has two ways to call functions: |
+ | |
+ | - a "standard" call syntax with parens and comma separated args |
+ | - a shell command like syntax (no parens and spacing separated args) |
+ | |
+ | The former also allows a variable to hold the name of the function, |
+ | the latter can also be used to call external commands. |
+ | |
+ | The grammar (simplified) looks like this: |
+ | |
+ | fun_call : ID "(" { expr ("," expr)* } ")" |
+ | /* ID is function name */ |
+ | | "@" ID "(" { expr ("," expr)* } ")" |
+ | /* ID is var containing fun name */ |
+ | ; |
+ | |
+ | command : ID expr* /* ID is function name */ |
+ | | path expr* /* path is external command name */ |
+ | ; |
+ | |
+ | path : ID /* left out slashes and such */ |
+ | | "@" ID /* ID is environment var */ |
+ | ; |
+ | |
+ | expr : .... |
+ | | "(" expr ")"; |
+ | |
+ | call : fun_call |
+ | | command |
+ | ; |
+ | |
+ | Obviously the call is wildly ambiguous. This is more or less how this |
+ | is to be resolved: |
+ | |
+ | A call begins with an ID or an @ followed by an ID. |
+ | |
+ | If it is an ID and if it is an ext. command name -> command |
+ | if followed by a paren -> fun_call |
+ | otherwise -> command |
+ | |
+ | If it is an @ and if the ID is a var name -> fun_call |
+ | otherwise -> command |
+ | |
+ | One can implement these rules quite neatly using && predicates: |
+ | |
+ | call : ("@" ID)? && <<isVarName(LT(2))>>? fun_call |
+ | | (ID)? && <<isExtCmdName>>? command |
+ | | (ID "(")? fun_call |
+ | | command |
+ | ; |
+ | |
+ | This can be done better, so it is not an ideal example, but it |
+ | conveys the principle. |
+ +-------------------------------------------------------------------------+
+
+#123. (Changed in 1.33MR11) Correct definition of operators in ATokPtr.h
+
+ The return value of operators in ANTLRTokenPtr:
+
+ changed: unsigned ... operator !=(...)
+ to: int ... operator != (...)
+ changed: unsigned ... operator ==(...)
+ to: int ... operator == (...)
+
+ Suggested by R.A. Nelson (cowboy@VNET.IBM.COM)
+
+#122. (Changed in 1.33MR11) Member functions to reset DLG in C++ mode
+
+ void DLGFileReset(FILE *f) { input = f; found_eof = 0; }
+ void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; }
+
+ Supplied by R.A. Nelson (cowboy@VNET.IBM.COM)
+
+#121. (Changed in 1.33MR11) Another attempt to fix -o (output dir) option
+
+ Another attempt is made to improve the -o option of antlr, dlg,
+ and sorcerer. This one by JVincent (JVincent@novell.com).
+
+ The current rule:
+
+ a. If -o is not specified than any explicit directory
+ names are retained.
+
+ b. If -o is specified than the -o directory name overrides any
+ explicit directory names.
+
+ c. The directory name of the grammar file is *not* stripped
+ to create the main output file. However it is stil subject
+ to override by the -o directory name.
+
+#120. (Changed in 1.33MR11) "-info f" output to stdout rather than stderr
+
+ Added option 0 (e.g. "-info 0") which is a noop.
+
+#119. (Changed in 1.33MR11) Ambiguity aid for grammars
+
+ The user can ask for additional information on ambiguities reported
+ by antlr to stdout. At the moment, only one ambiguity report can
+ be created in an antlr run.
+
+ This feature is enabled using the "-aa" (Ambiguity Aid) option.
+
+ The following options control the reporting of ambiguities:
+
+ -aa ruleName Selects reporting by name of rule
+ -aa lineNumber Selects reporting by line number
+ (file name not compared)
+
+ -aam Selects "multiple" reporting for a token
+ in the intersection set of the
+ alternatives.
+
+ For instance, the token ID may appear dozens
+ of times in various paths as the program
+ explores the rules which are reachable from
+ the point of an ambiguity. With option -aam
+ every possible path the search program
+ encounters is reported.
+
+ Without -aam only the first encounter is
+ reported. This may result in incomplete
+ information, but the information may be
+ sufficient and much shorter.
+
+ -aad depth Selects the depth of the search.
+ The default value is 1.
+
+ The number of paths to be searched, and the
+ size of the report can grow geometrically
+ with the -ck value if a full search for all
+ contributions to the source of the ambiguity
+ is explored.
+
+ The depth represents the number of tokens
+ in the lookahead set which are matched against
+ the set of ambiguous tokens. A depth of 1
+ means that the search stops when a lookahead
+ sequence of just one token is matched.
+
+ A k=1 ck=6 grammar might generate 5,000 items
+ in a report if a full depth 6 search is made
+ with the Ambiguity Aid. The source of the
+ problem may be in the first token and obscured
+ by the volume of data - I hesitate to call
+ it information.
+
+ When the user selects a depth > 1, the search
+ is first performed at depth=1 for both
+ alternatives, then depth=2 for both alternatives,
+ etc.
+
+ Sample output for rule grammar in antlr.g itself:
+
+ +---------------------------------------------------------------------+
+ | Ambiguity Aid |
+ | |
+ | Choice 1: grammar/70 line 632 file a.g |
+ | Choice 2: grammar/82 line 644 file a.g |
+ | |
+ | Intersection of lookahead[1] sets: |
+ | |
+ | "\}" "class" "#errclass" "#tokclass" |
+ | |
+ | Choice:1 Depth:1 Group:1 ("#errclass") |
+ | 1 in (...)* block grammar/70 line 632 a.g |
+ | 2 to error grammar/73 line 635 a.g |
+ | 3 error error/1 line 894 a.g |
+ | 4 #token "#errclass" error/2 line 895 a.g |
+ | |
+ | Choice:1 Depth:1 Group:2 ("#tokclass") |
+ | 2 to tclass grammar/74 line 636 a.g |
+ | 3 tclass tclass/1 line 937 a.g |
+ | 4 #token "#tokclass" tclass/2 line 938 a.g |
+ | |
+ | Choice:1 Depth:1 Group:3 ("class") |
+ | 2 to class_def grammar/75 line 637 a.g |
+ | 3 class_def class_def/1 line 669 a.g |
+ | 4 #token "class" class_def/3 line 671 a.g |
+ | |
+ | Choice:1 Depth:1 Group:4 ("\}") |
+ | 2 #token "\}" grammar/76 line 638 a.g |
+ | |
+ | Choice:2 Depth:1 Group:5 ("#errclass") |
+ | 1 in (...)* block grammar/83 line 645 a.g |
+ | 2 to error grammar/93 line 655 a.g |
+ | 3 error error/1 line 894 a.g |
+ | 4 #token "#errclass" error/2 line 895 a.g |
+ | |
+ | Choice:2 Depth:1 Group:6 ("#tokclass") |
+ | 2 to tclass grammar/94 line 656 a.g |
+ | 3 tclass tclass/1 line 937 a.g |
+ | 4 #token "#tokclass" tclass/2 line 938 a.g |
+ | |
+ | Choice:2 Depth:1 Group:7 ("class") |
+ | 2 to class_def grammar/95 line 657 a.g |
+ | 3 class_def class_def/1 line 669 a.g |
+ | 4 #token "class" class_def/3 line 671 a.g |
+ | |
+ | Choice:2 Depth:1 Group:8 ("\}") |
+ | 2 #token "\}" grammar/96 line 658 a.g |
+ +---------------------------------------------------------------------+
+
+ For a linear lookahead set ambiguity (where k=1 or for k>1 but
+ when all lookahead sets [i] with i<k all have degree one) the
+ reports appear in the following order:
+
+ for (depth=1 ; depth <= "-aad depth" ; depth++) {
+ for (alternative=1; alternative <=2 ; alternative++) {
+ while (matches-are-found) {
+ group++;
+ print-report
+ };
+ };
+ };
+
+ For reporting a k-tuple ambiguity, the reports appear in the
+ following order:
+
+ for (depth=1 ; depth <= "-aad depth" ; depth++) {
+ while (matches-are-found) {
+ for (alternative=1; alternative <=2 ; alternative++) {
+ group++;
+ print-report
+ };
+ };
+ };
+
+ This is because matches are generated in different ways for
+ linear lookahead and k-tuples.
+
+#118. (Changed in 1.33MR11) DEC VMS makefile and VMS related changes
+
+ Revised makefiles for DEC/VMS operating system for antlr, dlg,
+ and sorcerer.
+
+ Reduced names of routines with external linkage to less than 32
+ characters to conform to DEC/VMS linker limitations.
+
+ Jean-Francois Pieronne discovered problems with dlg and antlr
+ due to the VMS linker not being case sensitive for names with
+ external linkage. In dlg the problem was with "className" and
+ "ClassName". In antlr the problem was with "GenExprSets" and
+ "genExprSets".
+
+ Added genmms, a version of genmk for the DEC/VMS version of make.
+ The source is in directory pccts/support/DECmms.
+
+ All VMS contributions by Jean-Francois Pieronne (jfp@iname.com).
+
+#117. (Changed in 1.33MR10) new EXPERIMENTAL predicate hoisting code
+
+ The hoisting of predicates into rules to create prediction
+ expressions is a problem in antlr. Consider the following
+ example (k=1 with -prc on):
+
+ start : (a)* "@" ;
+ a : b | c ;
+ b : <<isUpper(LATEXT(1))>>? A ;
+ c : A ;
+
+ Prior to 1.33MR10 the code generated for "start" would resemble:
+
+ while {
+ if (LA(1)==A &&
+ (!LA(1)==A || isUpper())) {
+ a();
+ }
+ };
+
+ This code is wrong because it makes rule "c" unreachable from
+ "start". The essence of the problem is that antlr fails to
+ recognize that there can be a valid alternative within "a" even
+ when the predicate <<isUpper(LATEXT(1))>>? is false.
+
+ In 1.33MR10 with -mrhoist the hoisting of the predicate into
+ "start" is suppressed because it recognizes that "c" can
+ cover all the cases where the predicate is false:
+
+ while {
+ if (LA(1)==A) {
+ a();
+ }
+ };
+
+ With the antlr "-info p" switch the user will receive information
+ about the predicate suppression in the generated file:
+
+ --------------------------------------------------------------
+ #if 0
+
+ Hoisting of predicate suppressed by alternative without predicate.
+ The alt without the predicate includes all cases where
+ the predicate is false.
+
+ WITH predicate: line 7 v1.g
+ WITHOUT predicate: line 7 v1.g
+
+ The context set for the predicate:
+
+ A
+
+ The lookahead set for the alt WITHOUT the semantic predicate:
+
+ A
+
+ The predicate:
+
+ pred << isUpper(LATEXT(1))>>?
+ depth=k=1 rule b line 9 v1.g
+ set context:
+ A
+ tree context: null
+
+ Chain of referenced rules:
+
+ #0 in rule start (line 5 v1.g) to rule a
+ #1 in rule a (line 7 v1.g)
+
+ #endif
+ --------------------------------------------------------------
+
+ A predicate can be suppressed by a combination of alternatives
+ which, taken together, cover a predicate:
+
+ start : (a)* "@" ;
+
+ a : b | ca | cb | cc ;
+
+ b : <<isUpper(LATEXT(1))>>? ( A | B | C ) ;
+
+ ca : A ;
+ cb : B ;
+ cc : C ;
+
+ Consider a more complex example in which "c" covers only part of
+ a predicate:
+
+ start : (a)* "@" ;
+
+ a : b
+ | c
+ ;
+
+ b : <<isUpper(LATEXT(1))>>?
+ ( A
+ | X
+ );
+
+ c : A
+ ;
+
+ Prior to 1.33MR10 the code generated for "start" would resemble:
+
+ while {
+ if ( (LA(1)==A || LA(1)==X) &&
+ (! (LA(1)==A || LA(1)==X) || isUpper()) {
+ a();
+ }
+ };
+
+ With 1.33MR10 and -mrhoist the predicate context is restricted to
+ the non-covered lookahead. The code resembles:
+
+ while {
+ if ( (LA(1)==A || LA(1)==X) &&
+ (! (LA(1)==X) || isUpper()) {
+ a();
+ }
+ };
+
+ With the antlr "-info p" switch the user will receive information
+ about the predicate restriction in the generated file:
+
+ --------------------------------------------------------------
+ #if 0
+
+ Restricting the context of a predicate because of overlap
+ in the lookahead set between the alternative with the
+ semantic predicate and one without
+ Without this restriction the alternative without the predicate
+ could not be reached when input matched the context of the
+ predicate and the predicate was false.
+
+ WITH predicate: line 11 v4.g
+ WITHOUT predicate: line 12 v4.g
+
+ The original context set for the predicate:
+
+ A X
+
+ The lookahead set for the alt WITHOUT the semantic predicate:
+
+ A
+
+ The intersection of the two sets
+
+ A
+
+ The original predicate:
+
+ pred << isUpper(LATEXT(1))>>?
+ depth=k=1 rule b line 15 v4.g
+ set context:
+ A X
+ tree context: null
+
+ The new (modified) form of the predicate:
+
+ pred << isUpper(LATEXT(1))>>?
+ depth=k=1 rule b line 15 v4.g
+ set context:
+ X
+ tree context: null
+
+ #endif
+ --------------------------------------------------------------
+
+ The bad news about -mrhoist:
+
+ (a) -mrhoist does not analyze predicates with lookahead
+ depth > 1.
+
+ (b) -mrhoist does not look past a guarded predicate to
+ find context which might cover other predicates.
+
+ For these cases you might want to use syntactic predicates.
+ When a semantic predicate fails during guess mode the guess
+ fails and the next alternative is tried.
+
+ Limitation (a) is illustrated by the following example:
+
+ start : (stmt)* EOF ;
+
+ stmt : cast
+ | expr
+ ;
+ cast : <<isTypename(LATEXT(2))>>? LP ID RP ;
+
+ expr : LP ID RP ;
+
+ This is not much different from the first example, except that
+ it requires two tokens of lookahead context to determine what
+ to do. This predicate is NOT suppressed because the current version
+ is unable to handle predicates with depth > 1.
+
+ A predicate can be combined with other predicates during hoisting.
+ In those cases the depth=1 predicates are still handled. Thus,
+ in the following example the isUpper() predicate will be suppressed
+ by line #4 when hoisted from "bizarre" into "start", but will still
+ be present in "bizarre" in order to predict "stmt".
+
+ start : (bizarre)* EOF ; // #1
+ // #2
+ bizarre : stmt // #3
+ | A // #4
+ ;
+
+ stmt : cast
+ | expr
+ ;
+
+ cast : <<isTypename(LATEXT(2))>>? LP ID RP ;
+
+ expr : LP ID RP ;
+ | <<isUpper(LATEXT(1))>>? A
+
+ Limitation (b) is illustrated by the following example of a
+ context guarded predicate:
+
+ rule : (A)? <<p>>? // #1
+ (A // #2
+ |B // #3
+ ) // #4
+ | <<q>> B // #5
+ ;
+
+ Recall that this means that when the lookahead is NOT A then
+ the predicate "p" is ignored and it attempts to match "A|B".
+ Ideally, the "B" at line #3 should suppress predicate "q".
+ However, the current version does not attempt to look past
+ the guard predicate to find context which might suppress other
+ predicates.
+
+ In some cases -mrhoist will lead to the reporting of ambiguities
+ which were not visible before:
+
+ start : (a)* "@";
+ a : bc | d;
+ bc : b | c ;
+
+ b : <<isUpper(LATEXT(1))>>? A;
+ c : A ;
+
+ d : A ;
+
+ In this case there is a true ambiguity in "a" between "bc" and "d"
+ which can both match "A". Without -mrhoist the predicate in "b"
+ is hoisted into "a" and there is no ambiguity reported. However,
+ with -mrhoist, the predicate in "b" is suppressed by "c" (as it
+ should be) making the ambiguity in "a" apparent.
+
+ The motivations for these changes were hoisting problems reported
+ by Reinier van den Born (reinier@vnet.ibm.com) and several others.
+
+#116. (Changed in 1.33MR10) C++ mode: tracein/traceout rule name is (const char *)
+
+ The prototype for C++ mode routine tracein (and traceout) has changed from
+ "char *" to "const char *".
+
+#115. (Changed in 1.33MR10) Using guess mode with exception handlers in C mode
+
+ The definition of the C mode macros zzmatch_wsig and zzsetmatch_wsig
+ neglected to consider guess mode. When control passed to the rule's
+ parse exception handler the routine would exit without ever closing the
+ guess block. This would lead to unpredictable behavior.
+
+ In 1.33MR10 the behavior of exceptions in C mode and C++ mode should be
+ identical.
+
+#114. (Changed in 1.33MR10) difference in [zz]resynch() between C and C++ modes
+
+ There was a slight difference in the way C and C++ mode resynchronized
+ following a parsing error. The C routine would sometimes skip an extra
+ token before attempting to resynchronize.
+
+ The C routine was changed to match the C++ routine.
+
+#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <<p>>? expr
+
+ The existing context guarded predicate:
+
+ rule : (guard)? => <<p>>? expr
+ | next_alternative
+ ;
+
+ generates code which resembles:
+
+ if (lookahead(expr) && (!guard || pred)) {
+ expr()
+ } else ....
+
+ This is not suitable for some applications because it allows
+ expr() to be invoked when the predicate is false. This is
+ intentional because it is meant to mimic automatically computed
+ predicate context.
+
+ The new context guarded predicate uses the guard information
+ differently because it has a different goal. Consider:
+
+ rule : (guard)? && <<p>>? expr
+ | next_alternative
+ ;
+
+ The new style of context guarded predicate is equivalent to:
+
+ rule : <<guard==true && pred>>? expr
+ | next_alternative
+ ;
+
+ It generates code which resembles:
+
+ if (lookahead(expr) && guard && pred) {
+ expr();
+ } else ...
+
+ Both forms of guarded predicates severely restrict the form of
+ the context guard: it can contain no rule references, no
+ (...)*, no (...)+, and no {...}. It may contain token and
+ token class references, and alternation ("|").
+
+ Addition for 1.33MR11: in the token expression all tokens must
+ be at the same height of the token tree:
+
+ (A ( B | C))? && ... is ok (all height 2)
+ (A ( B | ))? && ... is not ok (some 1, some 2)
+ (A B C D | E F G H)? && ... is ok (all height 4)
+ (A B C D | E )? && ... is not ok (some 4, some 1)
+
+ This restriction is required in order to properly compute the lookahead
+ set for expressions like:
+
+ rule1 : (A B C)? && <<pred>>? rule2 ;
+ rule2 : (A|X) (B|Y) (C|Z);
+
+ This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com)
+
+#112. (Changed in 1.33MR10) failed validation predicate in C guess mode
+
+ John Lilley (jlilley@empathy.com) suggested that failed validation
+ predicates abort a guess rather than reporting a failed error.
+ This was installed in C++ mode (Item #4). Only now was it noticed
+ that the fix was never installed for C mode.
+
+#111. (Changed in 1.33MR10) moved zzTRACEIN to before init action
+
+ When the antlr -gd switch is present antlr generates calls to
+ zzTRACEIN at the start of a rule and zzTRACEOUT at the exit
+ from a rule. Prior to 1.33MR10 Tthe call to zzTRACEIN was
+ after the init-action, which could cause confusion because the
+ init-actions were reported with the name of the enclosing rule,
+ rather than the active rule.
+
+#110. (Changed in 1.33MR10) antlr command line copied to generated file
+
+ The antlr command line is now copied to the generated file near
+ the start.
+
+#109. (Changed in 1.33MR10) improved trace information
+
+ The quality of the trace information provided by the "-gd"
+ switch has been improved significantly. Here is an example
+ of the output from a test program. It shows the rule name,
+ the first token of lookahead, the call depth, and the guess
+ status:
+
+ exit rule gusxx {"?"} depth 2
+ enter rule gusxx {"?"} depth 2
+ enter rule gus1 {"o"} depth 3 guessing
+ guess done - returning to rule gus1 {"o"} at depth 3
+ (guess mode continues - an enclosing guess is still active)
+ guess done - returning to rule gus1 {"Z"} at depth 3
+ (guess mode continues - an enclosing guess is still active)
+ exit rule gus1 {"Z"} depth 3 guessing
+ guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends)
+ enter rule gus1 {"o"} depth 3
+ guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends)
+ guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends)
+ exit rule gus1 {"Z"} depth 3
+ line 1: syntax error at "Z" missing SC
+ ...
+
+ Rule trace reporting is controlled by the value of the integer
+ [zz]traceOptionValue: when it is positive tracing is enabled,
+ otherwise it is disabled. Tracing during guess mode is controlled
+ by the value of the integer [zz]traceGuessOptionValue. When
+ it is positive AND [zz]traceOptionValue is positive rule trace
+ is reported in guess mode.
+
+ The values of [zz]traceOptionValue and [zz]traceGuessOptionValue
+ can be adjusted by subroutine calls listed below.
+
+ Depending on the presence or absence of the antlr -gd switch
+ the variable [zz]traceOptionValueDefault is set to 0 or 1. When
+ the parser is initialized or [zz]traceReset() is called the
+ value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue.
+ The value of [zz]traceGuessOptionValue is always initialized to 1,
+ but, as noted earlier, nothing will be reported unless
+ [zz]traceOptionValue is also positive.
+
+ When the parser state is saved/restored the value of the trace
+ variables are also saved/restored. If a restore causes a change in
+ reporting behavior from on to off or vice versa this will be reported.
+
+ When the -gd option is selected, the macro "#define zzTRACE_RULES"
+ is added to appropriate output files.
+
+ C++ mode
+ --------
+ int traceOption(int delta)
+ int traceGuessOption(int delta)
+ void traceReset()
+ int traceOptionValueDefault
+
+ C mode
+ --------
+ int zzTraceOption(int delta)
+ int zzTraceGuessOption(int delta)
+ void zzTraceReset()
+ int zzTraceOptionValueDefault
+
+ The argument "delta" is added to the traceOptionValue. To
+ turn on trace when inside a particular rule one:
+
+ rule : <<traceOption(+1);>>
+ (
+ rest-of-rule
+ )
+ <<traceOption(-1);>>
+ ; /* fail clause */ <<traceOption(-1);>>
+
+ One can use the same idea to turn *off* tracing within a
+ rule by using a delta of (-1).
+
+ An improvement in the rule trace was suggested by Sramji
+ Ramanathan (ps@kumaran.com).
+
+#108. A Note on Deallocation of Variables Allocated in Guess Mode
+
+ NOTE
+ ------------------------------------------------------
+ This mechanism only works for heap allocated variables
+ ------------------------------------------------------
+
+ The rewrite of the trace provides the machinery necessary
+ to properly free variables or undo actions following a
+ failed guess.
+
+ The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded
+ as part of the zzGUESS macro. When a guess is opened
+ the value of zzrv is 0. When a longjmp() is executed to
+ undo the guess, the value of zzrv will be 1.
+
+ The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded
+ as part of the zzGUESS_DONE macro. This is executed
+ whether the guess succeeds or fails as part of closing
+ the guess.
+
+ The guessSeq is a sequence number which is assigned to each
+ guess and is incremented by 1 for each guess which becomes
+ active. It is needed by the user to associate the start of
+ a guess with the failure and/or completion (closing) of a
+ guess.
+
+ Guesses are nested. They must be closed in the reverse
+ of the order that they are opened.
+
+ In order to free memory used by a variable during a guess
+ a user must write a routine which can be called to
+ register the variable along with the current guess sequence
+ number provided by the zzUSER_GUESS_HOOK macro. If the guess
+ fails, all variables tagged with the corresponding guess
+ sequence number should be released. This is ugly, but
+ it would require a major rewrite of antlr 1.33 to use
+ some mechanism other than setjmp()/longjmp().
+
+ The order of calls for a *successful* guess would be:
+
+ zzUSER_GUESS_HOOK(guessSeq,0);
+ zzUSER_GUESS_DONE_HOOK(guessSeq);
+
+ The order of calls for a *failed* guess would be:
+
+ zzUSER_GUESS_HOOK(guessSeq,0);
+ zzUSER_GUESS_HOOK(guessSeq,1);
+ zzUSER_GUESS_DONE_HOOK(guessSeq);
+
+ The default definitions of these macros are empty strings.
+
+ Here is an example in C++ mode. The zzUSER_GUESS_HOOK and
+ zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine
+ can be used without change in both C and C++ versions.
+
+ ----------------------------------------------------------------------
+ <<
+
+ #include "AToken.h"
+
+ typedef ANTLRCommonToken ANTLRToken;
+
+ #include "DLGLexer.h"
+
+ int main() {
+
+ {
+ DLGFileInput in(stdin);
+ DLGLexer lexer(&in,2000);
+ ANTLRTokenBuffer pipe(&lexer,1);
+ ANTLRCommonToken aToken;
+ P parser(&pipe);
+
+ lexer.setToken(&aToken);
+ parser.init();
+ parser.start();
+ };
+
+ fclose(stdin);
+ fclose(stdout);
+ return 0;
+ }
+
+ >>
+
+ <<
+ char *s=NULL;
+
+ #undef zzUSER_GUESS_HOOK
+ #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv);
+ #undef zzUSER_GUESS_DONE_HOOK
+ #define zzUSER_GUESS_DONE_HOOK(guessSeq) myGuessHook(guessSeq,2);
+
+ void myGuessHook(int guessSeq,int zzrv) {
+ if (zzrv == 0) {
+ fprintf(stderr,"User hook: starting guess #%d\n",guessSeq);
+ } else if (zzrv == 1) {
+ free (s);
+ s=NULL;
+ fprintf(stderr,"User hook: failed guess #%d\n",guessSeq);
+ } else if (zzrv == 2) {
+ free (s);
+ s=NULL;
+ fprintf(stderr,"User hook: ending guess #%d\n",guessSeq);
+ };
+ }
+
+ >>
+
+ #token A "a"
+ #token "[\t \ \n]" <<skip();>>
+
+ class P {
+
+ start : (top)+
+ ;
+
+ top : (which) ? <<fprintf(stderr,"%s is a which\n",s); free(s); s=NULL; >>
+ | other <<fprintf(stderr,"%s is an other\n",s); free(s); s=NULL; >>
+ ; <<if (s != NULL) free(s); s=NULL; >>
+
+ which : which2
+ ;
+
+ which2 : which3
+ ;
+ which3
+ : (label)? <<fprintf(stderr,"%s is a label\n",s);>>
+ | (global)? <<fprintf(stderr,"%s is a global\n",s);>>
+ | (exclamation)? <<fprintf(stderr,"%s is an exclamation\n",s);>>
+ ;
+
+ label : <<s=strdup(LT(1)->getText());>> A ":" ;
+
+ global : <<s=strdup(LT(1)->getText());>> A "::" ;
+
+ exclamation : <<s=strdup(LT(1)->getText());>> A "!" ;
+
+ other : <<s=strdup(LT(1)->getText());>> "other" ;
+
+ }
+ ----------------------------------------------------------------------
+
+ This is a silly example, but illustrates the idea. For the input
+ "a ::" with tracing enabled the output begins:
+
+ ----------------------------------------------------------------------
+ enter rule "start" depth 1
+ enter rule "top" depth 2
+ User hook: starting guess #1
+ enter rule "which" depth 3 guessing
+ enter rule "which2" depth 4 guessing
+ enter rule "which3" depth 5 guessing
+ User hook: starting guess #2
+ enter rule "label" depth 6 guessing
+ guess failed
+ User hook: failed guess #2
+ guess done - returning to rule "which3" at depth 5 (guess mode continues
+ - an enclosing guess is still active)
+ User hook: ending guess #2
+ User hook: starting guess #3
+ enter rule "global" depth 6 guessing
+ exit rule "global" depth 6 guessing
+ guess done - returning to rule "which3" at depth 5 (guess mode continues
+ - an enclosing guess is still active)
+ User hook: ending guess #3
+ enter rule "global" depth 6 guessing
+ exit rule "global" depth 6 guessing
+ exit rule "which3" depth 5 guessing
+ exit rule "which2" depth 4 guessing
+ exit rule "which" depth 3 guessing
+ guess done - returning to rule "top" at depth 2 (guess mode ends)
+ User hook: ending guess #1
+ enter rule "which" depth 3
+ .....
+ ----------------------------------------------------------------------
+
+ Remember:
+
+ (a) Only init-actions are executed during guess mode.
+ (b) A rule can be invoked multiple times during guess mode.
+ (c) If the guess succeeds the rule will be called once more
+ without guess mode so that normal actions will be executed.
+ This means that the init-action might need to distinguish
+ between guess mode and non-guess mode using the variable
+ [zz]guessing.
+
+#107. (Changed in 1.33MR10) construction of ASTs in guess mode
+
+ Prior to 1.33MR10, when using automatic AST construction in C++
+ mode for a rule, an AST would be constructed for elements of the
+ rule even while in guess mode. In MR10 this no longer occurs.
+
+#106. (Changed in 1.33MR10) guess variable confusion
+
+ In C++ mode a guess which failed always restored the parser state
+ using zzGUESS_DONE as part of zzGUESS_FAIL. Prior to 1.33MR10,
+ C mode required an explicit call to zzGUESS_DONE after the
+ call to zzGUESS_FAIL.
+
+ Consider:
+
+ rule : (alpha)? beta
+ | ...
+ ;
+
+ The generated code resembles:
+
+ zzGUESS
+ if (!zzrv && LA(1)==ID) { <==== line #1
+ alpha
+ zzGUESS_DONE
+ beta
+ } else {
+ if (! zzrv) zzGUESS_DONE <==== line #2a
+ ....
+
+ However, in some cases line #2 was rendered:
+
+ if (guessing) zzGUESS_DONE <==== line #2b
+
+ This would work for simple test cases, but would fail in
+ some cases where there was a guess while another guess was active.
+ One kind of failure would be to match up the zzGUESS_DONE at line
+ #2b with the "outer" guess which was still active. The outer
+ guess would "succeed" when only the inner guess should have
+ succeeded.
+
+ In 1.33MR10 the behavior of zzGUESS and zzGUESS_FAIL in C and
+ and C++ mode should be identical.
+
+ The same problem appears in 1.33 vanilla in some places. For
+ example:
+
+ start : { (sub)? } ;
+
+ or:
+
+ start : (
+ B
+ | ( sub )?
+ | C
+ )+
+ ;
+
+ generates incorrect code.
+
+ The general principle is:
+
+ (a) use [zz]guessing only when deciding between a call to zzFAIL
+ or zzGUESS_FAIL
+
+ (b) use zzrv in all other cases
+
+ This problem was discovered while testing changes to item #105.
+ I believe this is now fixed. My apologies.
+
+#105. (Changed in 1.33MR10) guess block as single alt of (...)+
+
+ Prior to 1.33MR10 the following constructs:
+
+ rule_plus : (
+ (sub)?
+ )+
+ ;
+
+ rule_star : (
+ (sub)?
+ )*
+ ;
+
+ generated incorrect code for the guess block (which could result
+ in runtime errors) because of an incorrect optimization of a
+ block with only a single alternative.
+
+ The fix caused some changes to the fix described in Item #49
+ because there are now three code generation sequences for (...)+
+ blocks containing a guess block:
+
+ a. single alternative which is a guess block
+ b. multiple alternatives in which the last is a guess block
+ c. all other cases
+
+ Forms like "rule_star" can have unexpected behavior when there
+ is a syntax error: if the subrule "sub" is not matched *exactly*
+ then "rule_star" will consume no tokens.
+
+ Reported by Esa Pulkkinen (esap@cs.tut.fi).
+
+#104. (Changed in 1.33MR10) -o option for dlg
+
+ There was problem with the code added by item #74 to handle the
+ -o option of dlg. This should fix it.
+
+#103. (Changed in 1.33MR10) ANDed semantic predicates
+
+ Rescinded.
+
+ The optimization was a mistake.
+ The resulting problem is described in Item #150.
+
+#102. (Changed in 1.33MR10) allow "class parser : .... {"
+
+ The syntax of the class statement ("class parser-name {")
+ has been extended to allow for the specification of base
+ classes. An arbitrary number of tokens may now appear
+ between the class name and the "{". They are output
+ again when the class declaration is generated. For
+ example:
+
+ class Parser : public MyBaseClassANTLRparser {
+
+ This was suggested by a user, but I don't have a record
+ of who it was.
+
+#101. (Changed in 1.33MR10) antlr -info command line switch
+
+ -info
+
+ p - extra predicate information in generated file
+
+ t - information about tnode use:
+ at the end of each rule in generated file
+ summary on stderr at end of program
+
+ m - monitor progress
+ prints name of each rule as it is started
+ flushes output at start of each rule
+
+ f - first/follow set information to stdout
+
+ 0 - no operation (added in 1.33MR11)
+
+ The options may be combined and may appear in any order.
+ For example:
+
+ antlr -info ptm -CC -gt -mrhoist on mygrammar.g
+
+#100a. (Changed in 1.33MR10) Predicate tree simplification
+
+ When the same predicates can be referenced in more than one
+ alternative of a block large predicate trees can be formed.
+
+ The difference that these optimizations make is so dramatic
+ that I have decided to use it even when -mrhoist is not selected.
+
+ Consider the following grammar:
+
+ start : ( all )* ;
+
+ all : a
+ | d
+ | e
+ | f
+ ;
+
+ a : c A B
+ | c A C
+ ;
+
+ c : <<AAA(LATEXT(2))>>?
+ ;
+
+ d : <<BBB(LATEXT(2))>>? B C
+ ;
+
+ e : <<CCC(LATEXT(2))>>? B C
+ ;
+
+ f : e X Y
+ ;
+
+ In rule "a" there is a reference to rule "c" in both alternatives.
+ The length of the predicate AAA is k=2 and it can be followed in
+ alternative 1 only by (A B) while in alternative 2 it can be
+ followed only by (A C). Thus they do not have identical context.
+
+ In rule "all" the alternatives which refer to rules "e" and "f" allow
+ elimination of the duplicate reference to predicate CCC.
+
+ The table below summarized the kind of simplification performed by
+ 1.33MR10. In the table, X and Y stand for single predicates
+ (not trees).
+
+ (OR X (OR Y (OR Z))) => (OR X Y Z)
+ (AND X (AND Y (AND Z))) => (AND X Y Z)
+
+ (OR X (... (OR X Y) ... )) => (OR X (... Y ... ))
+ (AND X (... (AND X Y) ... )) => (AND X (... Y ... ))
+ (OR X (... (AND X Y) ... )) => (OR X (... ... ))
+ (AND X (... (OR X Y) ... )) => (AND X (... ... ))
+
+ (AND X) => X
+ (OR X) => X
+
+ In a test with a complex grammar for a real application, a predicate
+ tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)".
+
+ In 1.33MR10 there is a greater effort to release memory used
+ by predicates once they are no longer in use.
+
+#100b. (Changed in 1.33MR10) Suppression of extra predicate tests
+
+ The following optimizations require that -mrhoist be selected.
+
+ It is relatively easy to optimize the code generated for predicate
+ gates when they are of the form:
+
+ (AND X Y Z ...)
+ or (OR X Y Z ...)
+
+ where X, Y, Z, and "..." represent individual predicates (leaves) not
+ predicate trees.
+
+ If the predicate is an AND the contexts of the X, Y, Z, etc. are
+ ANDed together to create a single Tree context for the group and
+ context tests for the individual predicates are suppressed:
+
+ --------------------------------------------------
+ Note: This was incorrect. The contexts should be
+ ORed together. This has been fixed. A more
+ complete description is available in item #152.
+ ---------------------------------------------------
+
+ Optimization 1: (AND X Y Z ...)
+
+ Suppose the context for Xtest is LA(1)==LP and the context for
+ Ytest is LA(1)==LP && LA(2)==ID.
+
+ Without the optimization the code would resemble:
+
+ if (lookaheadContext &&
+ !(LA(1)==LP && LA(1)==LP && LA(2)==ID) ||
+ ( (! LA(1)==LP || Xtest) &&
+ (! (LA(1)==LP || LA(2)==ID) || Xtest)
+ )) {...
+
+ With the -mrhoist optimization the code would resemble:
+
+ if (lookaheadContext &&
+ ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {...
+
+ Optimization 2: (OR X Y Z ...) with identical contexts
+
+ Suppose the context for Xtest is LA(1)==ID and for Ytest
+ the context is also LA(1)==ID.
+
+ Without the optimization the code would resemble:
+
+ if (lookaheadContext &&
+ ! (LA(1)==ID || LA(1)==ID) ||
+ (LA(1)==ID && Xtest) ||
+ (LA(1)==ID && Ytest) {...
+
+ With the -mrhoist optimization the code would resemble:
+
+ if (lookaheadContext &&
+ (! LA(1)==ID) || (Xtest || Ytest) {...
+
+ Optimization 3: (OR X Y Z ...) with distinct contexts
+
+ Suppose the context for Xtest is LA(1)==ID and for Ytest
+ the context is LA(1)==LP.
+
+ Without the optimization the code would resemble:
+
+ if (lookaheadContext &&
+ ! (LA(1)==ID || LA(1)==LP) ||
+ (LA(1)==ID && Xtest) ||
+ (LA(1)==LP && Ytest) {...
+
+ With the -mrhoist optimization the code would resemble:
+
+ if (lookaheadContext &&
+ (zzpf=0,
+ (LA(1)==ID && (zzpf=1) && Xtest) ||
+ (LA(1)==LP && (zzpf=1) && Ytest) ||
+ !zzpf) {
+
+ These may appear to be of similar complexity at first,
+ but the non-optimized version contains two tests of each
+ context while the optimized version contains only one
+ such test, as well as eliminating some of the inverted
+ logic (" !(...) || ").
+
+ Optimization 4: Computation of predicate gate trees
+
+ When generating code for the gates of predicate expressions
+ antlr 1.33 vanilla uses a recursive procedure to generate
+ "&&" and "||" expressions for testing the lookahead. As each
+ layer of the predicate tree is exposed a new set of "&&" and
+ "||" expressions on the lookahead are generated. In many
+ cases the lookahead being tested has already been tested.
+
+ With -mrhoist a lookahead tree is computed for the entire
+ lookahead expression. This means that predicates with identical
+ context or context which is a subset of another predicate's
+ context disappear.
+
+ This is especially important for predicates formed by rules
+ like the following:
+
+ upperCaseVowel : <<isUpperCase(LATEXT(1))>>? vowel;
+ vowel: : <<isVowel(LATEXT(1))>>? LETTERS;
+
+ These predicates are combined using AND since both must be
+ satisfied for rule upperCaseVowel. They have identical
+ context which makes this optimization very effective.
+
+ The affect of Items #100a and #100b together can be dramatic. In
+ a very large (but real world) grammar one particular predicate
+ expression was reduced from an (unreadable) 50 predicate leaves,
+ 195 LA(1) terms, and 5500 characters to an (easily comprehensible)
+ 3 predicate leaves (all different) and a *single* LA(1) term.
+
+#99. (Changed in 1.33MR10) Code generation for expression trees
+
+ Expression trees are used for k>1 grammars and predicates with
+ lookahead depth >1. This optimization must be enabled using
+ "-mrhoist on". (Clarification added for 1.33MR11).
+
+ In the processing of expression trees, antlr can generate long chains
+ of token comparisons. Prior to 1.33MR10 there were many redundant
+ parenthesis which caused problems for compilers which could handle
+ expressions of only limited complexity. For example, to test an
+ expression tree (root R A B C D), antlr would generate something
+ resembling:
+
+ (LA(1)==R && (LA(2)==A || (LA(2)==B || (LA(2)==C || LA(2)==D)))))
+
+ If there were twenty tokens to test then there would be twenty
+ parenthesis at the end of the expression.
+
+ In 1.33MR10 the generated code for tree expressions resembles:
+
+ (LA(1)==R && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D))
+
+ For "complex" expressions the output is indented to reflect the LA
+ number being tested:
+
+ (LA(1)==R
+ && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D
+ || LA(2)==E || LA(2)==F)
+ || LA(1)==S
+ && (LA(2)==G || LA(2)==H))
+
+
+ Suggested by S. Bochnak (S.Bochnak@@microTool.com.pl),
+
+#98. (Changed in 1.33MR10) Option "-info p"
+
+ When the user selects option "-info p" the program will generate
+ detailed information about predicates. If the user selects
+ "-mrhoist on" additional detail will be provided explaining
+ the promotion and suppression of predicates. The output is part
+ of the generated file and sandwiched between #if 0/#endif statements.
+
+ Consider the following k=1 grammar:
+
+ start : ( all ) * ;
+
+ all : ( a
+ | b
+ )
+ ;
+
+ a : c B
+ ;
+
+ c : <<LATEXT(1)>>?
+ | B
+ ;
+
+ b : <<LATEXT(1)>>? X
+ ;
+
+ Below is an excerpt of the output for rule "start" for the three
+ predicate options (off, on, and maintenance release style hoisting).
+
+ For those who do not wish to use the "-mrhoist on" option for code
+ generation the option can be used in a "diagnostic" mode to provide
+ valuable information:
+
+ a. where one should insert null actions to inhibit hoisting
+ b. a chain of rule references which shows where predicates are
+ being hoisted
+
+ ======================================================================
+ Example of "-info p" with "-mrhoist on"
+ ======================================================================
+ #if 0
+
+ Hoisting of predicate suppressed by alternative without predicate.
+ The alt without the predicate includes all cases where the
+ predicate is false.
+
+ WITH predicate: line 11 v36.g
+ WITHOUT predicate: line 12 v36.g
+
+ The context set for the predicate:
+
+ B
+
+ The lookahead set for alt WITHOUT the semantic predicate:
+
+ B
+
+ The predicate:
+
+ pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g
+
+ set context:
+ B
+ tree context: null
+
+ Chain of referenced rules:
+
+ #0 in rule start (line 1 v36.g) to rule all
+ #1 in rule all (line 3 v36.g) to rule a
+ #2 in rule a (line 8 v36.g) to rule c
+ #3 in rule c (line 11 v36.g)
+
+ #endif
+ &&
+ #if 0
+
+ pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g
+
+ set context:
+ X
+ tree context: null
+
+ #endif
+ ======================================================================
+ Example of "-info p" with the default -prc setting ( "-prc off")
+ ======================================================================
+ #if 0
+
+ OR
+ pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g
+
+ set context:
+ nil
+ tree context: null
+
+ pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g
+
+ set context:
+ nil
+ tree context: null
+
+ #endif
+ ======================================================================
+ Example of "-info p" with "-prc on" and "-mrhoist off"
+ ======================================================================
+ #if 0
+
+ OR
+ pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g
+
+ set context:
+ B
+ tree context: null
+
+ pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g
+
+ set context:
+ X
+ tree context: null
+
+ #endif
+ ======================================================================
+
+#97. (Fixed in 1.33MR10) "Predicate applied for more than one ... "
+
+ In 1.33 vanilla, the grammar listed below produced this message for
+ the first alternative (only) of rule "b":
+
+ warning: predicate applied for >1 lookahead 1-sequences
+ [you may only want one lookahead 1-sequence to apply.
+ Try using a context guard '(...)? =>'
+
+ In 1.33MR10 the message is issued for both alternatives.
+
+ top : (a)*;
+ a : b | c ;
+
+ b : <<PPP(LATEXT(1))>>? ( AAA | BBB )
+ | <<QQQ(LATEXT(1))>>? ( XXX | YYY )
+ ;
+
+ c : AAA | XXX;
+
+#96. (Fixed in 1.33MR10) Guard predicates ignored when -prc off
+
+ Prior to 1.33MR10, guard predicate code was not generated unless
+ "-prc on" was selected.
+
+ This was incorrect, since "-prc off" (the default) is supposed to
+ disable only AUTOMATIC computation of predicate context, not the
+ programmer specified context supplied by guard predicates.
+
+#95. (Fixed in 1.33MR10) Predicate guard context length was k, not max(k,ck)
+
+ Prior to 1.33MR10, predicate guards were computed to k tokens rather
+ than max(k,ck). Consider the following grammar:
+
+ a : ( A B C)? => <<AAA(LATEXT(1))>>? (A|X) (B|Y) (C|Z) ;
+
+ The code generated by 1.33 vanilla with "-k 1 -ck 3 -prc on"
+ for the predicate in "a" resembles:
+
+ if ( (! LA(1)==A) || AAA(LATEXT(1))) {...
+
+ With 1.33MR10 and the same options the code resembles:
+
+ if ( (! (LA(1)==A && LA(2)==B && LA(3)==C) || AAA(LATEXT(1))) {...
+
+#94. (Fixed in 1.33MR10) Predicates followed by rule references
+
+ Prior to 1.33MR10, a semantic predicate which referenced a token
+ which was off the end of the rule caused an incomplete context
+ to be computed (with "-prc on") for the predicate under some circum-
+ stances. In some cases this manifested itself as illegal C code
+ (e.g. "LA(2)==[Ep](1)" in the k=2 examples below:
+
+ all : ( a ) *;
+
+ a : <<AAA(LATEXT(2))>>? ID X
+ | <<BBB(LATEXT(2))>>? Y
+ | Z
+ ;
+
+ This might also occur when the semantic predicate was followed
+ by a rule reference which was shorter than the length of the
+ semantic predicate:
+
+ all : ( a ) *;
+
+ a : <<AAA(LATEXT(2))>>? ID X
+ | <<BBB(LATEXT(2))>>? y
+ | Z
+ ;
+
+ y : Y ;
+
+ Depending on circumstance, the resulting context might be too
+ generous because it was too short, or too restrictive because
+ of missing alternatives.
+
+#93. (Changed in 1.33MR10) Definition of Purify macro
+
+ Ofer Ben-Ami (gremlin@cs.huji.ac.il) has supplied a definition
+ for the Purify macro:
+
+ #define PURIFY(r, s) memset((char *) &(r), '\0', (s));
+
+ Note: This may not be the right thing to do for C++ objects that
+ have constructors. Reported by Bonny Rais (bonny@werple.net.au).
+
+ For those cases one should #define PURIFY to an empty macro in the
+ #header or #first actions.
+
+#92. (Fixed in 1.33MR10) Guarded predicates and hoisting
+
+ When a guarded predicate participates in hoisting it is linked into
+ a predicate expression tree. Prior to 1.33MR10 this link was never
+ cleared and the next time the guard was used to construct a new
+ tree the link could contain a spurious reference to another element
+ which had previously been joined to it in the semantic predicate tree.
+
+ For example:
+
+ start : ( all ) *;
+ all : ( a | b ) ;
+
+ start2 : ( all2 ) *;
+ all2 : ( a ) ;
+
+ a : (A)? => <<AAA(LATEXT(1))>>? A ;
+ b : (B)? => <<BBB(LATEXT(1))>>? B ;
+
+ Prior to 1.33MR10 the code for "start2" would include a spurious
+ reference to the BBB predicate which was left from constructing
+ the predicate tree for rule "start" (i.e. or(AAA,BBB) ).
+
+ In 1.33MR10 this problem is avoided by cloning the original guard
+ each time it is linked into a predicate tree.
+
+#91. (Changed in 1.33MR10) Extensive changes to semantic pred hoisting
+
+ ============================================
+ This has been rendered obsolete by Item #117
+ ============================================
+
+#90. (Fixed in 1.33MR10) Semantic pred with LT(i) and i>max(k,ck)
+
+ There is a bug in antlr 1.33 vanilla and all maintenance releases
+ prior to 1.33MR10 which allows semantic predicates to reference
+ an LT(i) or LATEXT(i) where i is larger than max(k,ck). When
+ this occurs antlr will attempt to mark the ith element of an array
+ in which there are only max(k,ck) elements. The result cannot
+ be predicted.
+
+ Using LT(i) or LATEXT(i) for i>max(k,ck) is reported as an error
+ in 1.33MR10.
+
+#89. Rescinded
+
+#88. (Fixed in 1.33MR10) Tokens used in semantic predicates in guess mode
+
+ Consider the behavior of a semantic predicate during guess mode:
+
+ rule : a:A (
+ <<test($a)>>? b:B
+ | c:C
+ );
+
+ Prior to MR10 the assignment of the token or attribute to
+ $a did not occur during guess mode, which would cause the
+ semantic predicate to misbehave because $a would be null.
+
+ In 1.33MR10 a semantic predicate with a reference to an
+ element label (such as $a) forces the assignment to take
+ place even in guess mode.
+
+ In order to work, this fix REQUIRES use of the $label format
+ for token pointers and attributes referenced in semantic
+ predicates.
+
+ The fix does not apply to semantic predicates using the
+ numeric form to refer to attributes (e.g. <<test($1)>>?).
+ The user will receive a warning for this case.
+
+ Reported by Rob Trout (trout@mcs.cs.kent.edu).
+
+#87. (Fixed in 1.33MR10) Malformed guard predicates
+
+ Context guard predicates may contain only references to
+ tokens. They may not contain references to (...)+ and
+ (...)* blocks. This is now checked. This replaces the
+ fatal error message in item #78 with an appropriate
+ (non-fatal) error message.
+
+ In theory, context guards should be allowed to reference
+ rules. However, I have not had time to fix this.
+ Evaluation of the guard takes place before all rules have
+ been read, making it difficult to resolve a forward reference
+ to rule "zzz" - it hasn't been read yet ! To postpone evaluation
+ of the guard until all rules have been read is too much
+ for the moment.
+
+#86. (Fixed in 1.33MR10) Unequal set size in set_sub
+
+ Routine set_sub() in pccts/support/set/set.h did not work
+ correctly when the sets were of unequal sizes. Rewrote
+ set_equ to make it simpler and remove unnecessary and
+ expensive calls to set_deg(). This routine was not used
+ in 1.33 vanilla.
+
+#85. (Changed in 1.33MR10) Allow redefinition of MaxNumFiles
+
+ Raised the maximum number of input files to 99 from 20.
+ Put a #ifndef/#endif around the "#define MaxNumFiles 99".
+
+#84. (Fixed in 1.33MR10) Initialize zzBadTok in macro zzRULE
+
+ Initialize zzBadTok to NULL in zzRULE macro of AParser.h.
+ in order to get rid of warning messages.
+
+#83. (Fixed in 1.33MR10) False warnings with -w2 for #tokclass
+
+ When -w2 is selected antlr gives inappropriate warnings about
+ #tokclass names not having any associated regular expressions.
+ Since a #tokclass is not a "real" token it will never have an
+ associated regular expression and there should be no warning.
+
+ Reported by Derek Pappas (derek.pappas@eng.sun.com)
+
+#82. (Fixed in 1.33MR10) Computation of follow sets with multiple cycles
+
+ Reinier van den Born (reinier@vnet.ibm.com) reported a problem
+ in the computation of follow sets by antlr. The problem (bug)
+ exists in 1.33 vanilla and all maintenance releases prior to 1.33MR10.
+
+ The problem involves the computation of follow sets when there are
+ cycles - rules which have mutual references. I believe the problem
+ is restricted to cases where there is more than one cycle AND
+ elements of those cycles have rules in common. Even when this
+ occurs it may not affect the code generated - but it might. It
+ might also lead to undetected ambiguities.
+
+ There were no changes in antlr or dlg output from the revised version.
+
+ The following fragment demonstrates the problem by giving different
+ follow sets (option -pa) for var_access when built with k=1 and ck=2 on
+ 1.33 vanilla and 1.33MR10:
+
+ echo_statement : ECHO ( echo_expr )*
+ ;
+
+ echo_expr : ( command )?
+ | expression
+ ;
+
+ command : IDENTIFIER
+ { concat }
+ ;
+
+ expression : operand ( OPERATOR operand )*
+ ;
+
+ operand : value
+ | START command END
+ ;
+
+ value : concat
+ | TYPE operand
+ ;
+
+ concat : var_access { CONCAT value }
+ ;
+
+ var_access : IDENTIFIER { INDEX }
+
+ ;
+#81. (Changed in 1.33MR10) C mode use of attributes and ASTs
+
+ Reported by Isaac Clark (irclark@mindspring.com).
+
+ C mode code ignores attributes returned by rules which are
+ referenced using element labels when ASTs are enabled (-gt option).
+
+ 1. start : r:rule t:Token <<$start=$r;>>
+
+ The $r reference will not work when combined with
+ the -gt option.
+
+ 2. start : t:Token <<$start=$t;>>
+
+ The $t reference works in all cases.
+
+ 3. start : rule <<$0=$1;>>
+
+ Numeric labels work in all cases.
+
+ With MR10 the user will receive an error message for case 1 when
+ the -gt option is used.
+
+#80. (Fixed in 1.33MR10) (...)? as last alternative of block
+
+ A construct like the following:
+
+ rule : a
+ | (b)?
+ ;
+
+ does not make sense because there is no alternative when
+ the guess block fails. This is now reported as a warning
+ to the user.
+
+ Previously, there was a code generation error for this case:
+ the guess block was not "closed" when the guess failed.
+ This could cause an infinite loop or other problems. This
+ is now fixed.
+
+ Example problem:
+
+ #header<<
+ #include <stdio.h>
+ #include "charptr.h"
+ >>
+
+ <<
+ #include "charptr.c"
+ main ()
+ {
+ ANTLR(start(),stdin);
+ }
+ >>
+
+ #token "[\ \t]+" << zzskip(); >>
+ #token "[\n]" << zzline++; zzskip(); >>
+
+ #token Word "[a-z]+"
+ #token Number "[0-9]+"
+
+
+ start : (test1)?
+ | (test2)?
+ ;
+ test1 : (Word Word Word Word)?
+ | (Word Word Word Number)?
+ ;
+ test2 : (Word Word Number Word)?
+ | (Word Word Number Number)?
+ ;
+
+ Test data which caused infinite loop:
+
+ a 1 a a
+
+#79. (Changed in 1.33MR10) Use of -fh with multiple parsers
+
+ Previously, antlr always used the pre-processor symbol
+ STDPCCTS_H as a gate for the file stdpccts.h. This
+ caused problems when there were multiple parsers defined
+ because they used the same gate symbol.
+
+ In 1.33MR10, the -fh filename is used to generate the
+ gate file for stdpccts.h. For instance:
+
+ antlr -fh std_parser1.h
+
+ generates the pre-processor symbol "STDPCCTS_std_parser1_H".
+
+ Reported by Ramanathan Santhanam (ps@kumaran.com).
+
+#78. (Changed in 1.33MR9) Guard predicates that refer to rules
+
+ ------------------------
+ Please refer to Item #87
+ ------------------------
+
+ Guard predicates are processed during an early phase
+ of antlr (during parsing) before all data structures
+ are completed.
+
+ There is an apparent bug in earlier versions of 1.33
+ which caused guard predicates which contained references
+ to rules (rather than tokens) to reference a structure
+ which hadn't yet been initialized.
+
+ In some cases (perhaps all cases) references to rules
+ in guard predicates resulted in the use of "garbage".
+
+#79. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com)
+
+ Previously, the maximum length file name was set
+ arbitrarily to 300 characters in antlr, dlg, and sorcerer.
+
+ The config.h file now attempts to define the maximum length
+ filename using _MAX_PATH from stdlib.h before falling back
+ to using the value 300.
+
+#78. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com)
+
+ Put #ifndef/#endif around definition of ZZLEXBUFSIZE in
+ antlr.
+
+#77. (Changed in 1.33MR9) Arithmetic overflow for very large grammars
+
+ In routine HandleAmbiguities() antlr attempts to compute the
+ number of possible elements in a set that is order of
+ number-of-tokens raised to the number-of-lookahead-tokens power.
+ For large grammars or large lookahead (e.g. -ck 7) this can
+ cause arithmetic overflow.
+
+ With 1.33MR9, arithmetic overflow in this computation is reported
+ the first time it happens. The program continues to run and
+ the program branches based on the assumption that the computed
+ value is larger than any number computed by counting actual cases
+ because 2**31 is larger than the number of bits in most computers.
+
+ Before 1.33MR9 overflow was not reported. The behavior following
+ overflow is not predictable by anyone but the original author.
+
+ NOTE
+
+ In 1.33MR10 the warning message is suppressed.
+ The code which detects the overflow allows the
+ computation to continue without an error. The
+ error message itself made made users worry.
+
+#76. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com)
+
+ Jeff Vincent has convinced me to make ANTLRCommonToken and
+ ANTLRCommonNoRefCountToken use variable length strings
+ allocated from the heap rather than fixed length strings.
+ By suitable definition of setText(), the copy constructor,
+ and operator =() it is possible to maintain "copy" semantics.
+ By "copy" semantics I mean that when a token is copied from
+ an existing token it receives its own, distinct, copy of the
+ text allocated from the heap rather than simply a pointer
+ to the original token's text.
+
+ ============================================================
+ W * A * R * N * I * N * G
+ ============================================================
+
+ It is possible that this may cause problems for some users.
+ For those users I have included the old version of AToken.h as
+ pccts/h/AToken_traditional.h.
+
+#75. (Changed in 1.33MR9) Bruce Guenter (bruceg@qcc.sk.ca)
+
+ Make DLGStringInput const correct. Since this is infrequently
+ subclassed, it should affect few users, I hope.
+
+#74. (Changed in 1.33MR9) -o (output directory) option
+
+ Antlr does not properly handle the -o output directory option
+ when the filename of the grammar contains a directory part. For
+ example:
+
+ antlr -o outdir pccts_src/myfile.g
+
+ causes antlr create a file called "outdir/pccts_src/myfile.cpp.
+ It SHOULD create outdir/myfile.cpp
+
+ The suggested code fix has been installed in antlr, dlg, and
+ Sorcerer.
+
+#73. (Changed in 1.33MR9) Hoisting of semantic predicates and -mrhoist
+
+ ============================================
+ This has been rendered obsolete by Item #117
+ ============================================
+
+#72. (Changed in 1.33MR9) virtual saveState()/restoreState()/guess_XXX
+
+ The following methods in ANTLRParser were made virtual at
+ the request of S. Bochnak (S.Bochnak@microTool.com.pl):
+
+ saveState() and restoreState()
+ guess(), guess_fail(), and guess_done()
+
+#71. (Changed in 1.33MR9) Access to omitted command line argument
+
+ If a switch requiring arguments is the last thing on the
+ command line, and the argument is omitted, antlr would core.
+
+ antlr test.g -prc
+
+ instead of
+
+ antlr test.g -prc off
+
+#70. (Changed in 1.33MR9) Addition of MSVC .dsp and .mak build files
+
+ The following MSVC .dsp and .mak files for pccts and sorcerer
+ were contributed by Stanislaw Bochnak (S.Bochnak@microTool.com.pl)
+ and Jeff Vincent (JVincent@novell.com)
+
+ PCCTS Distribution Kit
+ ----------------------
+ pccts/PCCTSMSVC50.dsw
+
+ pccts/antlr/AntlrMSVC50.dsp
+ pccts/antlr/AntlrMSVC50.mak
+
+ pccts/dlg/DlgMSVC50.dsp
+ pccts/dlg/DlgMSVC50.mak
+
+ pccts/support/msvc.dsp
+
+ Sorcerer Distribution Kit
+ -------------------------
+ pccts/sorcerer/SorcererMSVC50.dsp
+ pccts/sorcerer/SorcererMSVC50.mak
+
+ pccts/sorcerer/lib/msvc.dsp
+
+#69. (Changed in 1.33MR9) Change "unsigned int" to plain "int"
+
+ Declaration of max_token_num in misc.c as "unsigned int"
+ caused comparison between signed and unsigned ints giving
+ warning message without any special benefit.
+
+#68. (Changed in 1.33MR9) Add void return for dlg internal_error()
+
+ Get rid of "no return value" message in internal_error()
+ in file dlg/support.c and dlg/dlg.h.
+
+#67. (Changed in Sor) sor.g: lisp() has no return value
+
+ Added a "void" for the return type.
+
+#66. (Added to Sor) sor.g: ZZLEXBUFSIZE enclosed in #ifndef/#endif
+
+ A user needed to be able to change the ZZLEXBUFSIZE for
+ sor. Put the definition of ZZLEXBUFSIZE inside #ifndef/#endif
+
+#65. (Changed in 1.33MR9) PCCTSAST::deepCopy() and ast_dup() bug
+
+ Jeff Vincent (JVincent@novell.com) found that deepCopy()
+ made new copies of only the direct descendents. No new
+ copies were made of sibling nodes, Sibling pointers are
+ set to zero by shallowCopy().
+
+ PCCTS_AST::deepCopy() has been changed to make a
+ deep copy in the traditional sense.
+
+ The deepCopy() routine depends on the behavior of
+ shallowCopy(). In all sor examples I've found,
+ shallowCopy() zeroes the right and down pointers.
+
+ Original Tree Original deepCopy() Revised deepCopy
+ ------------- ------------------- ----------------
+ a->b->c A A
+ | | |
+ d->e->f D D->E->F
+ | | |
+ g->h->i G G->H->I
+ | |
+ j->k J->K
+
+ While comparing deepCopy() for C++ mode with ast_dup for
+ C mode I found a problem with ast_dup().
+
+ Routine ast_dup() has been changed to make a deep copy
+ in the traditional sense.
+
+ Original Tree Original ast_dup() Revised ast_dup()
+ ------------- ------------------- ----------------
+ a->b->c A->B->C A
+ | | |
+ d->e->f D->E->F D->E->F
+ | | |
+ g->h->i G->H->I G->H->I
+ | | |
+ j->k J->K J->K
+
+
+ I believe this affects transform mode sorcerer programs only.
+
+#64. (Changed in 1.33MR9) anltr/hash.h prototype for killHashTable()
+
+#63. (Changed in 1.33MR8) h/charptr.h does not zero pointer after free
+
+ The charptr.h routine now zeroes the pointer after free().
+
+ Reported by Jens Tingleff (jensting@imaginet.fr)
+
+#62. (Changed in 1.33MR8) ANTLRParser::resynch had static variable
+
+ The static variable "consumed" in ANTLRParser::resynch was
+ changed into an instance variable of the class with the
+ name "resynchConsumed".
+
+ Reported by S.Bochnak@microTool.com.pl
+
+#61. (Changed in 1.33MR8) Using rule>[i,j] when rule has no return values
+
+ Previously, the following code would cause antlr to core when
+ it tried to generate code for rule1 because rule2 had no return
+ values ("upward inheritance"):
+
+ rule1 : <<int i; int j>>
+ rule2 > [i,j]
+ ;
+
+ rule2 : Anything ;
+
+ Reported by S.Bochnak@microTool.com.pl
+
+ Verified correct operation of antlr MR8 when missing or extra
+ inheritance arguments for all combinations. When there are
+ missing or extra arguments code will still be generated even
+ though this might cause the invocation of a subroutine with
+ the wrong number of arguments.
+
+#60. (Changed in 1.33MR7) Major changes to exception handling
+
+ There were significant problems in the handling of exceptions
+ in 1.33 vanilla. The general problem is that it can only
+ process one level of exception handler. For example, a named
+ exception handler, an exception handler for an alternative, or
+ an exception for a subrule always went to the rule's exception
+ handler if there was no "catch" which matched the exception.
+
+ In 1.33MR7 the exception handlers properly "nest". If an
+ exception handler does not have a matching "catch" then the
+ nextmost outer exception handler is checked for an appropriate
+ "catch" clause, and so on until an exception handler with an
+ appropriate "catch" is found.
+
+ There are still undesirable features in the way exception
+ handlers are implemented, but I do not have time to fix them
+ at the moment:
+
+ The exception handlers for alternatives are outside the
+ block containing the alternative. This makes it impossible
+ to access variables declared in a block or to resume the
+ parse by "falling through". The parse can still be easily
+ resumed in other ways, but not in the most natural fashion.
+
+ This results in an inconsistency between named exception
+ handlers and exception handlers for alternatives. When
+ an exception handler for an alternative "falls through"
+ it goes to the nextmost outer handler - not the "normal
+ action".
+
+ A major difference between 1.33MR7 and 1.33 vanilla is
+ the default action after an exception is caught:
+
+ 1.33 Vanilla
+ ------------
+ In 1.33 vanilla the signal value is set to zero ("NoSignal")
+ and the code drops through to the code following the exception.
+ For named exception handlers this is the "normal action".
+ For alternative exception handlers this is the rule's handler.
+
+ 1.33MR7
+ -------
+ In 1.33MR7 the signal value is NOT automatically set to zero.
+
+ There are two cases:
+
+ For named exception handlers: if the signal value has been
+ set to zero the code drops through to the "normal action".
+
+ For all other cases the code branches to the nextmost outer
+ exception handler until it reaches the handler for the rule.
+
+ The following macros have been defined for convenience:
+
+ C/C++ Mode Name
+ --------------------
+ (zz)suppressSignal
+ set signal & return signal arg to 0 ("NoSignal")
+ (zz)setSignal(intValue)
+ set signal & return signal arg to some value
+ (zz)exportSignal
+ copy the signal value to the return signal arg
+
+ I'm not sure why PCCTS make a distinction between the local
+ signal value and the return signal argument, but I'm loathe
+ to change the code. The burden of copying the local signal
+ value to the return signal argument can be given to the
+ default signal handler, I suppose.
+
+#59. (Changed in 1.33MR7) Prototypes for some functions
+
+ Added prototypes for the following functions to antlr.h
+
+ zzconsumeUntil()
+ zzconsumeUntilToken()
+
+#58. (Changed in 1.33MR7) Added definition of zzbufsize to dlgauto.h
+
+#57. (Changed in 1.33MR7) Format of #line directive
+
+ Previously, the -gl directive for line 1234 would
+ resemble: "# 1234 filename.g". This caused problems
+ for some compilers/pre-processors. In MR7 it generates
+ "#line 1234 filename.g".
+
+#56. (Added in 1.33MR7) Jan Mikkelsen <janm@zeta.org.au>
+
+ Move PURIFY macro invocation to after rule's init action.
+
+#55. (Fixed in 1.33MR7) Uninitialized variables in ANTLRParser
+
+ Member variables inf_labase and inf_last were not initialized.
+ (See item #50.)
+
+#54. (Fixed in 1.33MR6) Brad Schick (schick@interacess.com)
+
+ Previously, the following constructs generated the same
+ code:
+
+ rule1 : (A B C)?
+ | something-else
+ ;
+
+ rule2 : (A B C)? ()
+ | something-else
+ ;
+
+ In all versions of pccts rule1 guesses (A B C) and then
+ consume all three tokens if the guess succeeds. In MR6
+ rule2 guesses (A B C) but consumes NONE of the tokens
+ when the guess succeeds because "()" matches epsilon.
+
+#53. (Explanation for 1.33MR6) What happens after an exception is caught ?
+
+ The Book is silent about what happens after an exception
+ is caught.
+
+ The following code fragment prints "Error Action" followed
+ by "Normal Action".
+
+ test : Word ex:Number <<printf("Normal Action\n");>>
+ exception[ex]
+ catch NoViableAlt:
+ <<printf("Error Action\n");>>
+ ;
+
+ The reason for "Normal Action" is that the normal flow of the
+ program after a user-written exception handler is to "drop through".
+ In the case of an exception handler for a rule this results in
+ the execution of a "return" statement. In the case of an
+ exception handler attached to an alternative, rule, or token
+ this is the code that would have executed had there been no
+ exception.
+
+ The user can achieve the desired result by using a "return"
+ statement.
+
+ test : Word ex:Number <<printf("Normal Action\n");>>
+ exception[ex]
+ catch NoViableAlt:
+ <<printf("Error Action\n"); return;>>
+ ;
+
+ The most powerful mechanism for recovery from parse errors
+ in pccts is syntactic predicates because they provide
+ backtracking. Exceptions allow "return", "break",
+ "consumeUntil(...)", "goto _handler", "goto _fail", and
+ changing the _signal value.
+
+#52. (Fixed in 1.33MR6) Exceptions without syntactic predicates
+
+ The following generates bad code in 1.33 if no syntactic
+ predicates are present in the grammar.
+
+ test : Word ex:Number <<printf("Normal Action\n");>>
+ exception[ex]
+ catch NoViableAlt:
+ <<printf("Error Action\n");>>
+
+ There is a reference to a guess variable. In C mode
+ this causes a compiler error. In C++ mode it generates
+ an extraneous check on member "guessing".
+
+ In MR6 correct code is generated for both C and C++ mode.
+
+#51. (Added to 1.33MR6) Exception operator "@" used without exceptions
+
+ In MR6 added a warning when the exception operator "@" is
+ used and no exception group is defined. This is probably
+ a case where "\@" or "@" is meant.
+
+#50. (Fixed in 1.33MR6) Gunnar Rxnning (gunnar@candleweb.no)
+ http://www.candleweb.no/~gunnar/
+
+ Routines zzsave_antlr_state and zzrestore_antlr_state don't
+ save and restore all the data needed when switching states.
+
+ Suggested patch applied to antlr.h and err.h for MR6.
+
+#49. (Fixed in 1.33MR6) Sinan Karasu (sinan@boeing.com)
+
+ Generated code failed to turn off guess mode when leaving a
+ (...)+ block which contained a guess block. The result was
+ an infinite loop. For example:
+
+ rule : (
+ (x)?
+ | y
+ )+
+
+ Suggested code fix implemented in MR6. Replaced
+
+ ... else if (zzcnt>1) break;
+
+ with:
+
+ C++ mode:
+ ... else if (zzcnt>1) {if (!zzrv) zzGUESS_DONE; break;};
+ C mode:
+ ... else if (zzcnt>1) {if (zzguessing) zzGUESS_DONE; break;};
+
+#48. (Fixed in 1.33MR6) Invalid exception element causes core
+
+ A label attached to an invalid construct can cause
+ pccts to crash while processing the exception associated
+ with the label. For example:
+
+ rule : t:(B C)
+ exception[t] catch MismatchedToken: <<printf(...);>>
+
+ Version MR6 generates the message:
+
+ reference in exception handler to undefined label 't'
+
+#47. (Fixed in 1.33MR6) Manuel Ornato
+
+ Under some circumstances involving a k >1 or ck >1
+ grammar and a loop block (i.e. (...)* ) pccts will
+ fail to detect a syntax error and loop indefinitely.
+ The problem did not exist in 1.20, but has existed
+ from 1.23 to the present.
+
+ Fixed in MR6.
+
+ ---------------------------------------------------
+ Complete test program
+ ---------------------------------------------------
+ #header<<
+ #include <stdio.h>
+ #include "charptr.h"
+ >>
+
+ <<
+ #include "charptr.c"
+ main ()
+ {
+ ANTLR(global(),stdin);
+ }
+ >>
+
+ #token "[\ \t]+" << zzskip(); >>
+ #token "[\n]" << zzline++; zzskip(); >>
+
+ #token B "b"
+ #token C "c"
+ #token D "d"
+ #token E "e"
+ #token LP "\("
+ #token RP "\)"
+
+ #token ANTLREOF "@"
+
+ global : (
+ (E liste)
+ | liste
+ | listed
+ ) ANTLREOF
+ ;
+
+ listeb : LP ( B ( B | C )* ) RP ;
+ listec : LP ( C ( B | C )* ) RP ;
+ listed : LP ( D ( B | C )* ) RP ;
+ liste : ( listeb | listec )* ;
+
+ ---------------------------------------------------
+ Sample data causing infinite loop
+ ---------------------------------------------------
+ e (d c)
+ ---------------------------------------------------
+
+#46. (Fixed in 1.33MR6) Robert Richter
+ (Robert.Richter@infotech.tu-chemnitz.de)
+
+ This item from the list of known problems was
+ fixed by item #18 (below).
+
+#45. (Fixed in 1.33MR6) Brad Schick (schick@interaccess.com)
+
+ The dependency scanner in VC++ mistakenly sees a
+ reference to an MPW #include file even though properly
+ #ifdef/#endif in config.h. The suggested workaround
+ has been implemented:
+
+ #ifdef MPW
+ .....
+ #define MPW_CursorCtl_Header <CursorCtl.h>
+ #include MPW_CursorCtl_Header
+ .....
+ #endif
+
+#44. (Fixed in 1.33MR6) cast malloc() to (char *) in charptr.c
+
+ Added (char *) cast for systems where malloc returns "void *".
+
+#43. (Added to 1.33MR6) Bruce Guenter (bruceg@qcc.sk.ca)
+
+ Add setLeft() and setUp methods to ASTDoublyLinkedBase
+ for symmetry with setRight() and setDown() methods.
+
+#42. (Fixed in 1.33MR6) Jeff Katcher (jkatcher@nortel.ca)
+
+ C++ style comment in antlr.c corrected.
+
+#41. (Added in 1.33MR6) antlr -stdout
+
+ Using "antlr -stdout ..." forces the text that would
+ normally go to the grammar.c or grammar.cpp file to
+ stdout.
+
+#40. (Added in 1.33MR6) antlr -tab to change tab stops
+
+ Using "antlr -tab number ..." changes the tab stops
+ for the grammar.c or grammar.cpp file. The number
+ must be between 0 and 8. Using 0 gives tab characters,
+ values between 1 and 8 give the appropriate number of
+ space characters.
+
+#39. (Fixed in 1.33MR5) Jan Mikkelsen <janm@zeta.org.au>
+
+ Commas in function prototype still not correct under
+ some circumstances. Suggested code fix installed.
+
+#38. (Fixed in 1.33MR5) ANTLRTokenBuffer constructor
+
+ Have ANTLRTokenBuffer ctor initialize member "parser" to null.
+
+#37. (Fixed in 1.33MR4) Bruce Guenter (bruceg@qcc.sk.ca)
+
+ In ANTLRParser::FAIL(int k,...) released memory pointed to by
+ f[i] (as well as f itself. Should only free f itself.
+
+#36. (Fixed in 1.33MR3) Cortland D. Starrett (cort@shay.ecn.purdue.edu)
+
+ Neglected to properly declare isDLGmaxToken() when fixing problem
+ reported by Andreas Magnusson.
+
+ Undo "_retv=NULL;" change which caused problems for return values
+ from rules whose return values weren't pointers.
+
+ Failed to create bin directory if it didn't exist.
+
+#35. (Fixed in 1.33MR2) Andreas Magnusson
+(Andreas.Magnusson@mailbox.swipnet.se)
+
+ Repair bug introduced by 1.33MR1 for #tokdefs. The original fix
+ placed "DLGmaxToken=9999" and "DLGminToken=0" in the TokenType enum
+ in order to fix a problem with an aggressive compiler assigning an 8
+ bit enum which might be too narrow. This caused #tokdefs to assume
+ that there were 9999 real tokens. The repair to the fix causes antlr to
+ ignore TokenTypes "DLGmaxToken" and "DLGminToken" in a #tokdefs file.
+
+#34. (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue)
+
+ Previously there was no public function for changing the line
+ number maintained by the lexer.
+
+#33. (Fixed in 1.33MR1) Franklin Chen (chen@adi.com)
+
+ Accidental use of EXIT_FAILURE rather than PCCTS_EXIT_FAILURE
+ in pccts/h/AParser.cpp.
+
+#32. (Fixed in 1.33MR1) Franklin Chen (chen@adi.com)
+
+ In PCCTSAST.cpp lines 405 and 466: Change
+
+ free (t)
+ to
+ free ( (char *)t );
+
+ to match prototype.
+
+#31. (Added to 1.33MR1) Pointer to parser in ANTLRTokenBuffer
+ Pointer to parser in DLGLexerBase
+
+ The ANTLRTokenBuffer class now contains a pointer to the
+ parser which is using it. This is established by the
+ ANTLRParser constructor calling ANTLRTokenBuffer::
+ setParser(ANTLRParser *p).
+
+ When ANTLRTokenBuffer::setParser(ANTLRParser *p) is
+ called it saves the pointer to the parser and then
+ calls ANTLRTokenStream::setParser(ANTLRParser *p)
+ so that the lexer can also save a pointer to the
+ parser.
+
+ There is also a function getParser() in each class
+ with the obvious purpose.
+
+ It is possible that these functions will return NULL
+ under some circumstances (e.g. a non-DLG lexer is used).
+
+#30. (Added to 1.33MR1) function tokenName(int token) standard
+
+ The generated parser class now includes the
+ function:
+
+ static const ANTLRChar * tokenName(int token)
+
+ which returns a pointer to the "name" corresponding
+ to the token.
+
+ The base class (ANTLRParser) always includes the
+ member function:
+
+ const ANTLRChar * parserTokenName(int token)
+
+ which can be accessed by objects which have a pointer
+ to an ANTLRParser, but do not know the name of the
+ parser class (e.g. ANTLRTokenBuffer and DLGLexerBase).
+
+#29. (Added to 1.33MR1) Debugging DLG lexers
+
+ If the pre-processor symbol DEBUG_LEXER is defined
+ then DLexerBase will include code for printing out
+ key information about tokens which are recognized.
+
+ The debug feature of the lexer is controlled by:
+
+ int previousDebugValue=lexer.debugLexer(newValue);
+
+ a value of 0 disables output
+ a value of 1 enables output
+
+ Even if the lexer debug code is compiled into DLexerBase
+ it must be enabled before any output is generated. For
+ example:
+
+ DLGFileInput in(stdin);
+ MyDLG lexer(&in,2000);
+
+ lexer.setToken(&aToken);
+
+ #if DEBUG_LEXER
+ lexer.debugLexer(1); // enable debug information
+ #endif
+
+#28. (Added to 1.33MR1) More control over DLG header
+
+ Version 1.33MR1 adds the following directives to PCCTS
+ for C++ mode:
+
+ #lexprefix <<source code>>
+
+ Adds source code to the DLGLexer.h file
+ after the #include "DLexerBase.h" but
+ before the start of the class definition.
+
+ #lexmember <<source code>>
+
+ Adds source code to the DLGLexer.h file
+ as part of the DLGLexer class body. It
+ appears immediately after the start of
+ the class and a "public: statement.
+
+#27. (Fixed in 1.33MR1) Comments in DLG actions
+
+ Previously, DLG would not recognize comments as a special case.
+ Thus, ">>" in the comments would cause errors. This is fixed.
+
+#26. (Fixed in 1.33MR1) Removed static variables from error routines
+
+ Previously, the existence of statically allocated variables
+ in some of the parser's member functions posed a danger when
+ there was more than one parser active.
+
+ Replaced with dynamically allocated/freed variables in 1.33MR1.
+
+#25. (Fixed in 1.33MR1) Use of string literals in semantic predicates
+
+ Previously, it was not possible to place a string literal in
+ a semantic predicate because it was not properly "stringized"
+ for the report of a failed predicate.
+
+#24. (Fixed in 1.33MR1) Continuation lines for semantic predicates
+
+ Previously, it was not possible to continue semantic
+ predicates across a line because it was not properly
+ "stringized" for the report of a failed predicate.
+
+ rule : <<ifXYZ()>>?[ a very
+ long statement ]
+
+#23. (Fixed in 1.33MR1) {...} envelope for failed semantic predicates
+
+ Previously, there was a code generation error for failed
+ semantic predicates:
+
+ rule : <<xyz()>>?[ stmt1; stmt2; ]
+
+ which generated code which resembled:
+
+ if (! xyz()) stmt1; stmt2;
+
+ It now puts the statements in a {...} envelope:
+
+ if (! xyz()) { stmt1; stmt2; };
+
+#22. (Fixed in 1.33MR1) Continuation of #token across lines using "\"
+
+ Previously, it was not possible to continue a #token regular
+ expression across a line. The trailing "\" and newline caused
+ a newline to be inserted into the regular expression by DLG.
+
+ Fixed in 1.33MR1.
+
+#21. (Fixed in 1.33MR1) Use of ">>" (right shift operator in DLG actions
+
+ It is now possible to use the C++ right shift operator ">>"
+ in DLG actions by using the normal escapes:
+
+ #token "shift-right" << value=value \>\> 1;>>
+
+#20. (Version 1.33/19-Jan-97 Karl Eccleson <karle@microrobotics.co.uk>
+ P.A. Keller (P.A.Keller@bath.ac.uk)
+
+ There is a problem due to using exceptions with the -gh option.
+
+ Suggested fix now in 1.33MR1.
+
+#19. (Fixed in 1.33MR1) Tom Piscotti and John Lilley
+
+ There were problems suppressing messages to stdin and stdout
+ when running in a window environment because some functions
+ which uses fprint were not virtual.
+
+ Suggested change now in 1.33MR1.
+
+ I believe all functions containing error messages (excluding those
+ indicating internal inconsistency) have been placed in functions
+ which are virtual.
+
+#18. (Version 1.33/ 22-Nov-96) John Bair (jbair@iftime.com)
+
+ Under some combination of options a required "return _retv" is
+ not generated.
+
+ Suggested fix now in 1.33MR1.
+
+#17. (Version 1.33/3-Sep-96) Ron House (house@helios.usq.edu.au)
+
+ The routine ASTBase::predorder_action omits two "tree->"
+ prefixes, which results in the preorder_action belonging
+ to the wrong node to be invoked.
+
+ Suggested fix now in 1.33MR1.
+
+#16. (Version 1.33/7-Jun-96) Eli Sternheim <eli@interhdl.com>
+
+ Routine consumeUntilToken() does not check for end-of-file
+ condition.
+
+ Suggested fix now in 1.33MR1.
+
+#15. (Version 1.33/8 Apr 96) Asgeir Olafsson <olafsson@cstar.ac.com>
+
+ Problem with tree duplication of doubly linked ASTs in ASTBase.cpp.
+
+ Suggested fix now in 1.33MR1.
+
+#14. (Version 1.33/28-Feb-96) Andreas.Magnusson@mailbox.swipnet.se
+
+ Problem with definition of operator = (const ANTLRTokenPtr rhs).
+
+ Suggested fix now in 1.33MR1.
+
+#13. (Version 1.33/13-Feb-96) Franklin Chen (chen@adi.com)
+
+ Sun C++ Compiler 3.0.1 can't compile testcpp/1 due to goto in
+ block with destructors.
+
+ Apparently fixed. Can't locate "goto".
+
+#12. (Version 1.33/10-Nov-95) Minor problems with 1.33 code
+
+ The following items have been fixed in 1.33MR1:
+
+ 1. pccts/antlr/main.c line 142
+
+ "void" appears in classic C code
+
+ 2. no makefile in support/genmk
+
+ 3. EXIT_FAILURE/_SUCCESS instead of PCCTS_EXIT_FAILURE/_SUCCESS
+
+ pccts/h/PCCTSAST.cpp
+ pccts/h/DLexerBase.cpp
+ pccts/testcpp/6/test.g
+
+ 4. use of "signed int" isn't accepted by AT&T cfront
+
+ pccts/h/PCCTSAST.h line 42
+
+ 5. in call to ANTLRParser::FAIL the var arg err_k is passed as
+ "int" but is declared "unsigned int".
+
+ 6. I believe that a failed validation predicate still does not
+ get put in a "{...}" envelope, despite the release notes.
+
+ 7. The #token ">>" appearing in the DLG grammar description
+ causes DLG to generate the string literal "\>\>" which
+ is non-conforming and will cause some compilers to
+ complain (scan.c function act10 line 143 of source code).
+
+#11. (Version 1.32b6) Dave Kuhlman (dkuhlman@netcom.com)
+
+ Problem with file close in gen.c. Already fixed in 1.33.
+
+#10. (Version 1.32b6/29-Aug-95)
+
+ pccts/antlr/main.c contains a C++ style comments on lines 149
+ and 176 which causes problems for most C compilers.
+
+ Already fixed in 1.33.
+
+#9. (Version 1.32b4/14-Mar-95) dlgauto.h #include "config.h"
+
+ The file pccts/h/dlgauto.h should probably contain a #include
+ "config.h" as it uses the #define symbol __USE_PROTOS.
+
+ Added to 1.33MR1.
+
+#8. (Version 1.32b4/6-Mar-95) Michael T. Richter (mtr@igs.net)
+
+ In C++ output mode anonymous tokens from in-line regular expressions
+ can create enum values which are too wide for the datatype of the enum
+ assigned by the C++ compiler.
+
+ Fixed in 1.33MR1.
+
+#7. (Version 1.32b4/6-Mar-95) C++ does not imply __STDC__
+
+ In err.h the combination of # directives assumes that a C++
+ compiler has __STDC__ defined. This is not necessarily true.
+
+ This problem also appears in the use of __USE_PROTOS which
+ is appropriate for both Standard C and C++ in antlr/gen.c
+ and antlr/lex.c
+
+ Fixed in 1.33MR1.
+
+#6. (Version 1.32 ?/15-Feb-95) Name conflict for "TokenType"
+
+ Already fixed in 1.33.
+
+#5. (23-Jan-95) Douglas_Cuthbertson.JTIDS@jtids_qmail.hanscom.af.mil
+
+ The fail action following a semantic predicate is not enclosed in
+ "{...}". This can lead to problems when the fail action contains
+ more than one statement.
+
+ Fixed in 1.33MR1.
+
+#4 . (Version 1.33/31-Mar-96) jlilley@empathy.com (John Lilley)
+
+ Put briefly, a semantic predicate ought to abort a guess if it fails.
+
+ Correction suggested by J. Lilley has been added to 1.33MR1.
+
+#3 . (Version 1.33) P.A.Keller@bath.ac.uk
+
+ Extra commas are placed in the K&R style argument list for rules
+ when using both exceptions and ASTs.
+
+ Fixed in 1.33MR1.
+
+#2. (Version 1.32b6/2-Oct-95) Brad Schick <schick@interaccess.com>
+
+ Construct #[] generates zzastnew() in C++ mode.
+
+ Already fixed in 1.33.
+
+#1. (Version 1.33) Bob Bailey (robert@oakhill.sps.mot.com)
+
+ Previously, config.h assumed that all PC systems required
+ "short" file names. The user can now override that
+ assumption with "#define LONGFILENAMES".
+
+ Added to 1.33MR1.
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_SUMMARY.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_SUMMARY.txt
new file mode 100644
index 00000000..17a37137
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/CHANGES_SUMMARY.txt
@@ -0,0 +1,2049 @@
+======================================================================
+
+ CHANGES_SUMMARY.TXT
+
+ A QUICK overview of changes from 1.33 in reverse order
+
+ A summary of additions rather than bug fixes and minor code changes.
+
+ Numbers refer to items in CHANGES_FROM_133*.TXT
+ which may contain additional information.
+
+ DISCLAIMER
+
+ The software and these notes are provided "as is". They may include
+ typographical or technical errors and their authors disclaims all
+ liability of any kind or nature for damages due to error, fault,
+ defect, or deficiency regardless of cause. All warranties of any
+ kind, either express or implied, including, but not limited to, the
+ implied warranties of merchantability and fitness for a particular
+ purpose are disclaimed.
+
+======================================================================
+
+#258. You can specify a user-defined base class for your parser
+
+ The base class must constructor must have a signature similar to
+ that of ANTLRParser.
+
+#253. Generation of block preamble (-preamble and -preamble_first)
+
+ The antlr option -preamble causes antlr to insert the code
+ BLOCK_PREAMBLE at the start of each rule and block.
+
+ The antlr option -preamble_first is similar, but inserts the
+ code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol
+ PreambleFirst_123 is equivalent to the first set defined by
+ the #FirstSetSymbol described in Item #248.
+
+#248. Generate symbol for first set of an alternative
+
+ rr : #FirstSetSymbol(rr_FirstSet) ( Foo | Bar ) ;
+
+#216. Defer token fetch for C++ mode
+
+ When the ANTLRParser class is built with the pre-processor option
+ ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred
+ until LA(i) or LT(i) is called.
+
+#215. Use reset() to reset DLGLexerBase
+#188. Added pccts/h/DLG_stream_input.h
+#180. Added ANTLRParser::getEofToken()
+#173. -glms for Microsoft style filenames with -gl
+#170. Suppression for predicates with lookahead depth >1
+
+ Consider the following grammar with -ck 2 and the predicate in rule
+ "a" with depth 2:
+
+ r1 : (ab)* "@"
+ ;
+
+ ab : a
+ | b
+ ;
+
+ a : (A B)? => <<p(LATEXT(2))>>? A B C
+ ;
+
+ b : A B C
+ ;
+
+ Normally, the predicate would be hoisted into rule r1 in order to
+ determine whether to call rule "ab". However it should *not* be
+ hoisted because, even if p is false, there is a valid alternative
+ in rule b. With "-mrhoistk on" the predicate will be suppressed.
+
+ If "-info p" command line option is present the following information
+ will appear in the generated code:
+
+ while ( (LA(1)==A)
+ #if 0
+
+ Part (or all) of predicate with depth > 1 suppressed by alternative
+ without predicate
+
+ pred << p(LATEXT(2))>>?
+ depth=k=2 ("=>" guard) rule a line 8 t1.g
+ tree context:
+ (root = A
+ B
+ )
+
+ The token sequence which is suppressed: ( A B )
+ The sequence of references which generate that sequence of tokens:
+
+ 1 to ab r1/1 line 1 t1.g
+ 2 ab ab/1 line 4 t1.g
+ 3 to b ab/2 line 5 t1.g
+ 4 b b/1 line 11 t1.g
+ 5 #token A b/1 line 11 t1.g
+ 6 #token B b/1 line 11 t1.g
+
+ #endif
+
+ A slightly more complicated example:
+
+ r1 : (ab)* "@"
+ ;
+
+ ab : a
+ | b
+ ;
+
+ a : (A B)? => <<p(LATEXT(2))>>? (A B | D E)
+ ;
+
+ b : <<q(LATEXT(2))>>? D E
+ ;
+
+
+ In this case, the sequence (D E) in rule "a" which lies behind
+ the guard is used to suppress the predicate with context (D E)
+ in rule b.
+
+ while ( (LA(1)==A || LA(1)==D)
+ #if 0
+
+ Part (or all) of predicate with depth > 1 suppressed by alternative
+ without predicate
+
+ pred << q(LATEXT(2))>>?
+ depth=k=2 rule b line 11 t2.g
+ tree context:
+ (root = D
+ E
+ )
+
+ The token sequence which is suppressed: ( D E )
+ The sequence of references which generate that sequence of tokens:
+
+ 1 to ab r1/1 line 1 t2.g
+ 2 ab ab/1 line 4 t2.g
+ 3 to a ab/1 line 4 t2.g
+ 4 a a/1 line 8 t2.g
+ 5 #token D a/1 line 8 t2.g
+ 6 #token E a/1 line 8 t2.g
+
+ #endif
+ &&
+ #if 0
+
+ pred << p(LATEXT(2))>>?
+ depth=k=2 ("=>" guard) rule a line 8 t2.g
+ tree context:
+ (root = A
+ B
+ )
+
+ #endif
+
+ (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) ) {
+ ab();
+ ...
+
+#165. (Changed in MR13) option -newAST
+
+ To create ASTs from an ANTLRTokenPtr antlr usually calls
+ "new AST(ANTLRTokenPtr)". This option generates a call
+ to "newAST(ANTLRTokenPtr)" instead. This allows a user
+ to define a parser member function to create an AST object.
+
+#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h
+
+#158. (Changed in MR13) #header causes problem for pre-processors
+
+ A user who runs the C pre-processor on antlr source suggested
+ that another syntax be allowed. With MR13 such directives
+ such as #header, #pragma, etc. may be written as "\#header",
+ "\#pragma", etc. For escaping pre-processor directives inside
+ a #header use something like the following:
+
+ \#header
+ <<
+ \#include <stdio.h>
+ >>
+
+#155. (Changed in MR13) Context behind predicates can suppress
+
+ With -mrhoist enabled the context behind a guarded predicate can
+ be used to suppress other predicates. Consider the following grammar:
+
+ r0 : (r1)+;
+
+ r1 : rp
+ | rq
+ ;
+ rp : <<p LATEXT(1)>>? B ;
+ rq : (A)? => <<q LATEXT(1)>>? (A|B);
+
+ In earlier versions both predicates "p" and "q" would be hoisted into
+ rule r0. With MR12c predicate p is suppressed because the context which
+ follows predicate q includes "B" which can "cover" predicate "p". In
+ other words, in trying to decide in r0 whether to call r1, it doesn't
+ really matter whether p is false or true because, either way, there is
+ a valid choice within r1.
+
+#154. (Changed in MR13) Making hoist suppression explicit using <<nohoist>>
+
+ A common error, even among experienced pccts users, is to code
+ an init-action to inhibit hoisting rather than a leading action.
+ An init-action does not inhibit hoisting.
+
+ This was coded:
+
+ rule1 : <<;>> rule2
+
+ This is what was meant:
+
+ rule1 : <<;>> <<;>> rule2
+
+ With MR13, the user can code:
+
+ rule1 : <<;>> <<nohoist>> rule2
+
+ The following will give an error message:
+
+ rule1 : <<nohoist>> rule2
+
+ If the <<nohoist>> appears as an init-action rather than a leading
+ action an error message is issued. The meaning of an init-action
+ containing "nohoist" is unclear: does it apply to just one
+ alternative or to all alternatives ?
+
+#151a. Addition of ANTLRParser::getLexer(), ANTLRTokenStream::getLexer()
+
+ You must manually cast the ANTLRTokenStream to your program's
+ lexer class. Because the name of the lexer's class is not fixed.
+ Thus it is impossible to incorporate it into the DLGLexerBase
+ class.
+
+#151b.(Changed in MR12) ParserBlackBox member getLexer()
+
+#150. (Changed in MR12) syntaxErrCount and lexErrCount now public
+
+#149. (Changed in MR12) antlr option -info o (letter o for orphan)
+
+ If there is more than one rule which is not referenced by any
+ other rule then all such rules are listed. This is useful for
+ alerting one to rules which are not used, but which can still
+ contribute to ambiguity.
+
+#148. (Changed in MR11) #token names appearing in zztokens,token_tbl
+
+ One can write:
+
+ #token Plus ("+") "\+"
+ #token RP ("(") "\("
+ #token COM ("comment begin") "/\*"
+
+ The string in parenthesis will be used in syntax error messages.
+
+#146. (Changed in MR11) Option -treport for locating "difficult" alts
+
+ It can be difficult to determine which alternatives are causing
+ pccts to work hard to resolve an ambiguity. In some cases the
+ ambiguity is successfully resolved after much CPU time so there
+ is no message at all.
+
+ A rough measure of the amount of work being peformed which is
+ independent of the CPU speed and system load is the number of
+ tnodes created. Using "-info t" gives information about the
+ total number of tnodes created and the peak number of tnodes.
+
+ Tree Nodes: peak 1300k created 1416k lost 0
+
+ It also puts in the generated C or C++ file the number of tnodes
+ created for a rule (at the end of the rule). However this
+ information is not sufficient to locate the alternatives within
+ a rule which are causing the creation of tnodes.
+
+ Using:
+
+ antlr -treport 100000 ....
+
+ causes antlr to list on stdout any alternatives which require the
+ creation of more than 100,000 tnodes, along with the lookahead sets
+ for those alternatives.
+
+ The following is a trivial case from the ansi.g grammar which shows
+ the format of the report. This report might be of more interest
+ in cases where 1,000,000 tuples were created to resolve the ambiguity.
+
+ -------------------------------------------------------------------------
+ There were 0 tuples whose ambiguity could not be resolved
+ by full lookahead
+ There were 157 tnodes created to resolve ambiguity between:
+
+ Choice 1: statement/2 line 475 file ansi.g
+ Choice 2: statement/3 line 476 file ansi.g
+
+ Intersection of lookahead[1] sets:
+
+ IDENTIFIER
+
+ Intersection of lookahead[2] sets:
+
+ LPARENTHESIS COLON AMPERSAND MINUS
+ STAR PLUSPLUS MINUSMINUS ONESCOMPLEMENT
+ NOT SIZEOF OCTALINT DECIMALINT
+ HEXADECIMALINT FLOATONE FLOATTWO IDENTIFIER
+ STRING CHARACTER
+ -------------------------------------------------------------------------
+
+#143. (Changed in MR11) Optional ";" at end of #token statement
+
+ Fixes problem of:
+
+ #token X "x"
+
+ <<
+ parser action
+ >>
+
+ Being confused with:
+
+ #token X "x" <<lexical action>>
+
+#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream
+
+ Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class
+ BufFileInput derived from DLGInputStream which provides a
+ function lookahead(char *string) to test characters in the
+ input stream more than one character ahead.
+ The class is located in pccts/h/BufFileInput.* of the kit.
+
+#140. #pred to define predicates
+
+ +---------------------------------------------------+
+ | Note: Assume "-prc on" for this entire discussion |
+ +---------------------------------------------------+
+
+ A problem with predicates is that each one is regarded as
+ unique and capable of disambiguating cases where two
+ alternatives have identical lookahead. For example:
+
+ rule : <<pred(LATEXT(1))>>? A
+ | <<pred(LATEXT(1))>>? A
+ ;
+
+ will not cause any error messages or warnings to be issued
+ by earlier versions of pccts. To compare the text of the
+ predicates is an incomplete solution.
+
+ In 1.33MR11 I am introducing the #pred statement in order to
+ solve some problems with predicates. The #pred statement allows
+ one to give a symbolic name to a "predicate literal" or a
+ "predicate expression" in order to refer to it in other predicate
+ expressions or in the rules of the grammar.
+
+ The predicate literal associated with a predicate symbol is C
+ or C++ code which can be used to test the condition. A
+ predicate expression defines a predicate symbol in terms of other
+ predicate symbols using "!", "&&", and "||". A predicate symbol
+ can be defined in terms of a predicate literal, a predicate
+ expression, or *both*.
+
+ When a predicate symbol is defined with both a predicate literal
+ and a predicate expression, the predicate literal is used to generate
+ code, but the predicate expression is used to check for two
+ alternatives with identical predicates in both alternatives.
+
+ Here are some examples of #pred statements:
+
+ #pred IsLabel <<isLabel(LATEXT(1))>>?
+ #pred IsLocalVar <<isLocalVar(LATEXT(1))>>?
+ #pred IsGlobalVar <<isGlobalVar(LATEXT(1)>>?
+ #pred IsVar <<isVar(LATEXT(1))>>? IsLocalVar || IsGlobalVar
+ #pred IsScoped <<isScoped(LATEXT(1))>>? IsLabel || IsLocalVar
+
+ I hope that the use of EBNF notation to describe the syntax of the
+ #pred statement will not cause problems for my readers (joke).
+
+ predStatement : "#pred"
+ CapitalizedName
+ (
+ "<<predicate_literal>>?"
+ | "<<predicate_literal>>?" predOrExpr
+ | predOrExpr
+ )
+ ;
+
+ predOrExpr : predAndExpr ( "||" predAndExpr ) * ;
+
+ predAndExpr : predPrimary ( "&&" predPrimary ) * ;
+
+ predPrimary : CapitalizedName
+ | "!" predPrimary
+ | "(" predOrExpr ")"
+ ;
+
+ What is the purpose of this nonsense ?
+
+ To understand how predicate symbols help, you need to realize that
+ predicate symbols are used in two different ways with two different
+ goals.
+
+ a. Allow simplification of predicates which have been combined
+ during predicate hoisting.
+
+ b. Allow recognition of identical predicates which can't disambiguate
+ alternatives with common lookahead.
+
+ First we will discuss goal (a). Consider the following rule:
+
+ rule0: rule1
+ | ID
+ | ...
+ ;
+
+ rule1: rule2
+ | rule3
+ ;
+
+ rule2: <<isX(LATEXT(1))>>? ID ;
+ rule3: <<!isX(LATEXT(1)>>? ID ;
+
+ When the predicates in rule2 and rule3 are combined by hoisting
+ to create a prediction expression for rule1 the result is:
+
+ if ( LA(1)==ID
+ && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ...
+
+ This is inefficient, but more importantly, can lead to false
+ assumptions that the predicate expression distinguishes the rule1
+ alternative with some other alternative with lookahead ID. In
+ MR11 one can write:
+
+ #pred IsX <<isX(LATEXT(1))>>?
+
+ ...
+
+ rule2: <<IsX>>? ID ;
+ rule3: <<!IsX>>? ID ;
+
+ During hoisting MR11 recognizes this as a special case and
+ eliminates the predicates. The result is a prediction
+ expression like the following:
+
+ if ( LA(1)==ID ) { rule1(); ...
+
+ Please note that the following cases which appear to be equivalent
+ *cannot* be simplified by MR11 during hoisting because the hoisting
+ logic only checks for a "!" in the predicate action, not in the
+ predicate expression for a predicate symbol.
+
+ *Not* equivalent and is not simplified during hoisting:
+
+ #pred IsX <<isX(LATEXT(1))>>?
+ #pred NotX <<!isX(LATEXT(1))>>?
+ ...
+ rule2: <<IsX>>? ID ;
+ rule3: <<NotX>>? ID ;
+
+ *Not* equivalent and is not simplified during hoisting:
+
+ #pred IsX <<isX(LATEXT(1))>>?
+ #pred NotX !IsX
+ ...
+ rule2: <<IsX>>? ID ;
+ rule3: <<NotX>>? ID ;
+
+ Now we will discuss goal (b).
+
+ When antlr discovers that there is a lookahead ambiguity between
+ two alternatives it attempts to resolve the ambiguity by searching
+ for predicates in both alternatives. In the past any predicate
+ would do, even if the same one appeared in both alternatives:
+
+ rule: <<p(LATEXT(1))>>? X
+ | <<p(LATEXT(1))>>? X
+ ;
+
+ The #pred statement is a start towards solving this problem.
+ During ambiguity resolution (*not* predicate hoisting) the
+ predicates for the two alternatives are expanded and compared.
+ Consider the following example:
+
+ #pred Upper <<isUpper(LATEXT(1))>>?
+ #pred Lower <<isLower(LATEXT(1))>>?
+ #pred Alpha <<isAlpha(LATEXT(1))>>? Upper || Lower
+
+ rule0: rule1
+ | <<Alpha>>? ID
+ ;
+
+ rule1:
+ | rule2
+ | rule3
+ ...
+ ;
+
+ rule2: <<Upper>>? ID;
+ rule3: <<Lower>>? ID;
+
+ The definition of #pred Alpha expresses:
+
+ a. to test the predicate use the C code "isAlpha(LATEXT(1))"
+
+ b. to analyze the predicate use the information that
+ Alpha is equivalent to the union of Upper and Lower,
+
+ During ambiguity resolution the definition of Alpha is expanded
+ into "Upper || Lower" and compared with the predicate in the other
+ alternative, which is also "Upper || Lower". Because they are
+ identical MR11 will report a problem.
+
+ -------------------------------------------------------------------------
+ t10.g, line 5: warning: the predicates used to disambiguate rule rule0
+ (file t10.g alt 1 line 5 and alt 2 line 6)
+ are identical when compared without context and may have no
+ resolving power for some lookahead sequences.
+ -------------------------------------------------------------------------
+
+ If you use the "-info p" option the output file will contain:
+
+ +----------------------------------------------------------------------+
+ |#if 0 |
+ | |
+ |The following predicates are identical when compared without |
+ | lookahead context information. For some ambiguous lookahead |
+ | sequences they may not have any power to resolve the ambiguity. |
+ | |
+ |Choice 1: rule0/1 alt 1 line 5 file t10.g |
+ | |
+ | The original predicate for choice 1 with available context |
+ | information: |
+ | |
+ | OR expr |
+ | |
+ | pred << Upper>>? |
+ | depth=k=1 rule rule2 line 14 t10.g |
+ | set context: |
+ | ID |
+ | |
+ | pred << Lower>>? |
+ | depth=k=1 rule rule3 line 15 t10.g |
+ | set context: |
+ | ID |
+ | |
+ | The predicate for choice 1 after expansion (but without context |
+ | information): |
+ | |
+ | OR expr |
+ | |
+ | pred << isUpper(LATEXT(1))>>? |
+ | depth=k=1 rule line 1 t10.g |
+ | |
+ | pred << isLower(LATEXT(1))>>? |
+ | depth=k=1 rule line 2 t10.g |
+ | |
+ | |
+ |Choice 2: rule0/2 alt 2 line 6 file t10.g |
+ | |
+ | The original predicate for choice 2 with available context |
+ | information: |
+ | |
+ | pred << Alpha>>? |
+ | depth=k=1 rule rule0 line 6 t10.g |
+ | set context: |
+ | ID |
+ | |
+ | The predicate for choice 2 after expansion (but without context |
+ | information): |
+ | |
+ | OR expr |
+ | |
+ | pred << isUpper(LATEXT(1))>>? |
+ | depth=k=1 rule line 1 t10.g |
+ | |
+ | pred << isLower(LATEXT(1))>>? |
+ | depth=k=1 rule line 2 t10.g |
+ | |
+ | |
+ |#endif |
+ +----------------------------------------------------------------------+
+
+ The comparison of the predicates for the two alternatives takes
+ place without context information, which means that in some cases
+ the predicates will be considered identical even though they operate
+ on disjoint lookahead sets. Consider:
+
+ #pred Alpha
+
+ rule1: <<Alpha>>? ID
+ | <<Alpha>>? Label
+ ;
+
+ Because the comparison of predicates takes place without context
+ these will be considered identical. The reason for comparing
+ without context is that otherwise it would be necessary to re-evaluate
+ the entire predicate expression for each possible lookahead sequence.
+ This would require more code to be written and more CPU time during
+ grammar analysis, and it is not yet clear whether anyone will even make
+ use of the new #pred facility.
+
+ A temporary workaround might be to use different #pred statements
+ for predicates you know have different context. This would avoid
+ extraneous warnings.
+
+ The above example might be termed a "false positive". Comparison
+ without context will also lead to "false negatives". Consider the
+ following example:
+
+ #pred Alpha
+ #pred Beta
+
+ rule1: <<Alpha>>? A
+ | rule2
+ ;
+
+ rule2: <<Alpha>>? A
+ | <<Beta>>? B
+ ;
+
+ The predicate used for alt 2 of rule1 is (Alpha || Beta). This
+ appears to be different than the predicate Alpha used for alt1.
+ However, the context of Beta is B. Thus when the lookahead is A
+ Beta will have no resolving power and Alpha will be used for both
+ alternatives. Using the same predicate for both alternatives isn't
+ very helpful, but this will not be detected with 1.33MR11.
+
+ To properly handle this the predicate expression would have to be
+ evaluated for each distinct lookahead context.
+
+ To determine whether two predicate expressions are identical is
+ difficult. The routine may fail to identify identical predicates.
+
+ The #pred feature also compares predicates to see if a choice between
+ alternatives which is resolved by a predicate which makes the second
+ choice unreachable. Consider the following example:
+
+ #pred A <<A(LATEXT(1)>>?
+ #pred B <<B(LATEXT(1)>>?
+ #pred A_or_B A || B
+
+ r : s
+ | t
+ ;
+ s : <<A_or_B>>? ID
+ ;
+ t : <<A>>? ID
+ ;
+
+ ----------------------------------------------------------------------------
+ t11.g, line 5: warning: the predicate used to disambiguate the
+ first choice of rule r
+ (file t11.g alt 1 line 5 and alt 2 line 6)
+ appears to "cover" the second predicate when compared without context.
+ The second predicate may have no resolving power for some lookahead
+ sequences.
+ ----------------------------------------------------------------------------
+
+#132. (Changed in 1.33MR11) Recognition of identical predicates in alts
+
+ Prior to 1.33MR11, there would be no ambiguity warning when the
+ very same predicate was used to disambiguate both alternatives:
+
+ test: ref B
+ | ref C
+ ;
+
+ ref : <<pred(LATEXT(1)>>? A
+
+ In 1.33MR11 this will cause the warning:
+
+ warning: the predicates used to disambiguate rule test
+ (file v98.g alt 1 line 1 and alt 2 line 2)
+ are identical and have no resolving power
+
+ ----------------- Note -----------------
+
+ This is different than the following case
+
+ test: <<pred(LATEXT(1))>>? A B
+ | <<pred(LATEXT(1)>>? A C
+ ;
+
+ In this case there are two distinct predicates
+ which have exactly the same text. In the first
+ example there are two references to the same
+ predicate. The problem represented by this
+ grammar will be addressed later.
+
+
+#127. (Changed in 1.33MR11)
+
+ Count Syntax Errors Count DLG Errors
+ ------------------- ----------------
+
+ C++ mode ANTLRParser:: DLGLexerBase::
+ syntaxErrCount lexErrCount
+ C mode zzSyntaxErrCount zzLexErrCount
+
+ The C mode variables are global and initialized to 0.
+ They are *not* reset to 0 automatically when antlr is
+ restarted.
+
+ The C++ mode variables are public. They are initialized
+ to 0 by the constructors. They are *not* reset to 0 by the
+ ANTLRParser::init() method.
+
+ Suggested by Reinier van den Born (reinier@vnet.ibm.com).
+
+#126. (Changed in 1.33MR11) Addition of #first <<...>>
+
+ The #first <<...>> inserts the specified text in the output
+ files before any other #include statements required by pccts.
+ The only things before the #first text are comments and
+ a #define ANTLR_VERSION.
+
+ Requested by and Esa Pulkkinen (esap@cs.tut.fi) and Alexin
+ Zoltan (alexin@inf.u-szeged.hu).
+
+#124. A Note on the New "&&" Style Guarded Predicates
+
+ I've been asked several times, "What is the difference between
+ the old "=>" style guard predicates and the new style "&&" guard
+ predicates, and how do you choose one over the other" ?
+
+ The main difference is that the "=>" does not apply the
+ predicate if the context guard doesn't match, whereas
+ the && form always does. What is the significance ?
+
+ If you have a predicate which is not on the "leading edge"
+ it is cannot be hoisted. Suppose you need a predicate that
+ looks at LA(2). You must introduce it manually. The
+ classic example is:
+
+ castExpr :
+ LP typeName RP
+ | ....
+ ;
+
+ typeName : <<isTypeName(LATEXT(1))>>? ID
+ | STRUCT ID
+ ;
+
+ The problem is that isTypeName() isn't on the leading edge
+ of typeName, so it won't be hoisted into castExpr to help
+ make a decision on which production to choose.
+
+ The *first* attempt to fix it is this:
+
+ castExpr :
+ <<isTypeName(LATEXT(2))>>?
+ LP typeName RP
+ | ....
+ ;
+
+ Unfortunately, this won't work because it ignores
+ the problem of STRUCT. The solution is to apply
+ isTypeName() in castExpr if LA(2) is an ID and
+ don't apply it when LA(2) is STRUCT:
+
+ castExpr :
+ (LP ID)? => <<isTypeName(LATEXT(2))>>?
+ LP typeName RP
+ | ....
+ ;
+
+ In conclusion, the "=>" style guarded predicate is
+ useful when:
+
+ a. the tokens required for the predicate
+ are not on the leading edge
+ b. there are alternatives in the expression
+ selected by the predicate for which the
+ predicate is inappropriate
+
+ If (b) were false, then one could use a simple
+ predicate (assuming "-prc on"):
+
+ castExpr :
+ <<isTypeName(LATEXT(2))>>?
+ LP typeName RP
+ | ....
+ ;
+
+ typeName : <<isTypeName(LATEXT(1))>>? ID
+ ;
+
+ So, when do you use the "&&" style guarded predicate ?
+
+ The new-style "&&" predicate should always be used with
+ predicate context. The context guard is in ADDITION to
+ the automatically computed context. Thus it useful for
+ predicates which depend on the token type for reasons
+ other than context.
+
+ The following example is contributed by Reinier van den Born
+ (reinier@vnet.ibm.com).
+
+ +-------------------------------------------------------------------------+
+ | This grammar has two ways to call functions: |
+ | |
+ | - a "standard" call syntax with parens and comma separated args |
+ | - a shell command like syntax (no parens and spacing separated args) |
+ | |
+ | The former also allows a variable to hold the name of the function, |
+ | the latter can also be used to call external commands. |
+ | |
+ | The grammar (simplified) looks like this: |
+ | |
+ | fun_call : ID "(" { expr ("," expr)* } ")" |
+ | /* ID is function name */ |
+ | | "@" ID "(" { expr ("," expr)* } ")" |
+ | /* ID is var containing fun name */ |
+ | ; |
+ | |
+ | command : ID expr* /* ID is function name */ |
+ | | path expr* /* path is external command name */ |
+ | ; |
+ | |
+ | path : ID /* left out slashes and such */ |
+ | | "@" ID /* ID is environment var */ |
+ | ; |
+ | |
+ | expr : .... |
+ | | "(" expr ")"; |
+ | |
+ | call : fun_call |
+ | | command |
+ | ; |
+ | |
+ | Obviously the call is wildly ambiguous. This is more or less how this |
+ | is to be resolved: |
+ | |
+ | A call begins with an ID or an @ followed by an ID. |
+ | |
+ | If it is an ID and if it is an ext. command name -> command |
+ | if followed by a paren -> fun_call |
+ | otherwise -> command |
+ | |
+ | If it is an @ and if the ID is a var name -> fun_call |
+ | otherwise -> command |
+ | |
+ | One can implement these rules quite neatly using && predicates: |
+ | |
+ | call : ("@" ID)? && <<isVarName(LT(2))>>? fun_call |
+ | | (ID)? && <<isExtCmdName>>? command |
+ | | (ID "(")? fun_call |
+ | | command |
+ | ; |
+ | |
+ | This can be done better, so it is not an ideal example, but it |
+ | conveys the principle. |
+ +-------------------------------------------------------------------------+
+
+#122. (Changed in 1.33MR11) Member functions to reset DLG in C++ mode
+
+ void DLGFileReset(FILE *f) { input = f; found_eof = 0; }
+ void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; }
+
+ Supplied by R.A. Nelson (cowboy@VNET.IBM.COM)
+
+#119. (Changed in 1.33MR11) Ambiguity aid for grammars
+
+ The user can ask for additional information on ambiguities reported
+ by antlr to stdout. At the moment, only one ambiguity report can
+ be created in an antlr run.
+
+ This feature is enabled using the "-aa" (Ambiguity Aid) option.
+
+ The following options control the reporting of ambiguities:
+
+ -aa ruleName Selects reporting by name of rule
+ -aa lineNumber Selects reporting by line number
+ (file name not compared)
+
+ -aam Selects "multiple" reporting for a token
+ in the intersection set of the
+ alternatives.
+
+ For instance, the token ID may appear dozens
+ of times in various paths as the program
+ explores the rules which are reachable from
+ the point of an ambiguity. With option -aam
+ every possible path the search program
+ encounters is reported.
+
+ Without -aam only the first encounter is
+ reported. This may result in incomplete
+ information, but the information may be
+ sufficient and much shorter.
+
+ -aad depth Selects the depth of the search.
+ The default value is 1.
+
+ The number of paths to be searched, and the
+ size of the report can grow geometrically
+ with the -ck value if a full search for all
+ contributions to the source of the ambiguity
+ is explored.
+
+ The depth represents the number of tokens
+ in the lookahead set which are matched against
+ the set of ambiguous tokens. A depth of 1
+ means that the search stops when a lookahead
+ sequence of just one token is matched.
+
+ A k=1 ck=6 grammar might generate 5,000 items
+ in a report if a full depth 6 search is made
+ with the Ambiguity Aid. The source of the
+ problem may be in the first token and obscured
+ by the volume of data - I hesitate to call
+ it information.
+
+ When the user selects a depth > 1, the search
+ is first performed at depth=1 for both
+ alternatives, then depth=2 for both alternatives,
+ etc.
+
+ Sample output for rule grammar in antlr.g itself:
+
+ +---------------------------------------------------------------------+
+ | Ambiguity Aid |
+ | |
+ | Choice 1: grammar/70 line 632 file a.g |
+ | Choice 2: grammar/82 line 644 file a.g |
+ | |
+ | Intersection of lookahead[1] sets: |
+ | |
+ | "\}" "class" "#errclass" "#tokclass" |
+ | |
+ | Choice:1 Depth:1 Group:1 ("#errclass") |
+ | 1 in (...)* block grammar/70 line 632 a.g |
+ | 2 to error grammar/73 line 635 a.g |
+ | 3 error error/1 line 894 a.g |
+ | 4 #token "#errclass" error/2 line 895 a.g |
+ | |
+ | Choice:1 Depth:1 Group:2 ("#tokclass") |
+ | 2 to tclass grammar/74 line 636 a.g |
+ | 3 tclass tclass/1 line 937 a.g |
+ | 4 #token "#tokclass" tclass/2 line 938 a.g |
+ | |
+ | Choice:1 Depth:1 Group:3 ("class") |
+ | 2 to class_def grammar/75 line 637 a.g |
+ | 3 class_def class_def/1 line 669 a.g |
+ | 4 #token "class" class_def/3 line 671 a.g |
+ | |
+ | Choice:1 Depth:1 Group:4 ("\}") |
+ | 2 #token "\}" grammar/76 line 638 a.g |
+ | |
+ | Choice:2 Depth:1 Group:5 ("#errclass") |
+ | 1 in (...)* block grammar/83 line 645 a.g |
+ | 2 to error grammar/93 line 655 a.g |
+ | 3 error error/1 line 894 a.g |
+ | 4 #token "#errclass" error/2 line 895 a.g |
+ | |
+ | Choice:2 Depth:1 Group:6 ("#tokclass") |
+ | 2 to tclass grammar/94 line 656 a.g |
+ | 3 tclass tclass/1 line 937 a.g |
+ | 4 #token "#tokclass" tclass/2 line 938 a.g |
+ | |
+ | Choice:2 Depth:1 Group:7 ("class") |
+ | 2 to class_def grammar/95 line 657 a.g |
+ | 3 class_def class_def/1 line 669 a.g |
+ | 4 #token "class" class_def/3 line 671 a.g |
+ | |
+ | Choice:2 Depth:1 Group:8 ("\}") |
+ | 2 #token "\}" grammar/96 line 658 a.g |
+ +---------------------------------------------------------------------+
+
+ For a linear lookahead set ambiguity (where k=1 or for k>1 but
+ when all lookahead sets [i] with i<k all have degree one) the
+ reports appear in the following order:
+
+ for (depth=1 ; depth <= "-aad depth" ; depth++) {
+ for (alternative=1; alternative <=2 ; alternative++) {
+ while (matches-are-found) {
+ group++;
+ print-report
+ };
+ };
+ };
+
+ For reporting a k-tuple ambiguity, the reports appear in the
+ following order:
+
+ for (depth=1 ; depth <= "-aad depth" ; depth++) {
+ while (matches-are-found) {
+ for (alternative=1; alternative <=2 ; alternative++) {
+ group++;
+ print-report
+ };
+ };
+ };
+
+ This is because matches are generated in different ways for
+ linear lookahead and k-tuples.
+
+#117. (Changed in 1.33MR10) new EXPERIMENTAL predicate hoisting code
+
+ The hoisting of predicates into rules to create prediction
+ expressions is a problem in antlr. Consider the following
+ example (k=1 with -prc on):
+
+ start : (a)* "@" ;
+ a : b | c ;
+ b : <<isUpper(LATEXT(1))>>? A ;
+ c : A ;
+
+ Prior to 1.33MR10 the code generated for "start" would resemble:
+
+ while {
+ if (LA(1)==A &&
+ (!LA(1)==A || isUpper())) {
+ a();
+ }
+ };
+
+ This code is wrong because it makes rule "c" unreachable from
+ "start". The essence of the problem is that antlr fails to
+ recognize that there can be a valid alternative within "a" even
+ when the predicate <<isUpper(LATEXT(1))>>? is false.
+
+ In 1.33MR10 with -mrhoist the hoisting of the predicate into
+ "start" is suppressed because it recognizes that "c" can
+ cover all the cases where the predicate is false:
+
+ while {
+ if (LA(1)==A) {
+ a();
+ }
+ };
+
+ With the antlr "-info p" switch the user will receive information
+ about the predicate suppression in the generated file:
+
+ --------------------------------------------------------------
+ #if 0
+
+ Hoisting of predicate suppressed by alternative without predicate.
+ The alt without the predicate includes all cases where
+ the predicate is false.
+
+ WITH predicate: line 7 v1.g
+ WITHOUT predicate: line 7 v1.g
+
+ The context set for the predicate:
+
+ A
+
+ The lookahead set for the alt WITHOUT the semantic predicate:
+
+ A
+
+ The predicate:
+
+ pred << isUpper(LATEXT(1))>>?
+ depth=k=1 rule b line 9 v1.g
+ set context:
+ A
+ tree context: null
+
+ Chain of referenced rules:
+
+ #0 in rule start (line 5 v1.g) to rule a
+ #1 in rule a (line 7 v1.g)
+
+ #endif
+ --------------------------------------------------------------
+
+ A predicate can be suppressed by a combination of alternatives
+ which, taken together, cover a predicate:
+
+ start : (a)* "@" ;
+
+ a : b | ca | cb | cc ;
+
+ b : <<isUpper(LATEXT(1))>>? ( A | B | C ) ;
+
+ ca : A ;
+ cb : B ;
+ cc : C ;
+
+ Consider a more complex example in which "c" covers only part of
+ a predicate:
+
+ start : (a)* "@" ;
+
+ a : b
+ | c
+ ;
+
+ b : <<isUpper(LATEXT(1))>>?
+ ( A
+ | X
+ );
+
+ c : A
+ ;
+
+ Prior to 1.33MR10 the code generated for "start" would resemble:
+
+ while {
+ if ( (LA(1)==A || LA(1)==X) &&
+ (! (LA(1)==A || LA(1)==X) || isUpper()) {
+ a();
+ }
+ };
+
+ With 1.33MR10 and -mrhoist the predicate context is restricted to
+ the non-covered lookahead. The code resembles:
+
+ while {
+ if ( (LA(1)==A || LA(1)==X) &&
+ (! (LA(1)==X) || isUpper()) {
+ a();
+ }
+ };
+
+ With the antlr "-info p" switch the user will receive information
+ about the predicate restriction in the generated file:
+
+ --------------------------------------------------------------
+ #if 0
+
+ Restricting the context of a predicate because of overlap
+ in the lookahead set between the alternative with the
+ semantic predicate and one without
+ Without this restriction the alternative without the predicate
+ could not be reached when input matched the context of the
+ predicate and the predicate was false.
+
+ WITH predicate: line 11 v4.g
+ WITHOUT predicate: line 12 v4.g
+
+ The original context set for the predicate:
+
+ A X
+
+ The lookahead set for the alt WITHOUT the semantic predicate:
+
+ A
+
+ The intersection of the two sets
+
+ A
+
+ The original predicate:
+
+ pred << isUpper(LATEXT(1))>>?
+ depth=k=1 rule b line 15 v4.g
+ set context:
+ A X
+ tree context: null
+
+ The new (modified) form of the predicate:
+
+ pred << isUpper(LATEXT(1))>>?
+ depth=k=1 rule b line 15 v4.g
+ set context:
+ X
+ tree context: null
+
+ #endif
+ --------------------------------------------------------------
+
+ The bad news about -mrhoist:
+
+ (a) -mrhoist does not analyze predicates with lookahead
+ depth > 1.
+
+ (b) -mrhoist does not look past a guarded predicate to
+ find context which might cover other predicates.
+
+ For these cases you might want to use syntactic predicates.
+ When a semantic predicate fails during guess mode the guess
+ fails and the next alternative is tried.
+
+ Limitation (a) is illustrated by the following example:
+
+ start : (stmt)* EOF ;
+
+ stmt : cast
+ | expr
+ ;
+ cast : <<isTypename(LATEXT(2))>>? LP ID RP ;
+
+ expr : LP ID RP ;
+
+ This is not much different from the first example, except that
+ it requires two tokens of lookahead context to determine what
+ to do. This predicate is NOT suppressed because the current version
+ is unable to handle predicates with depth > 1.
+
+ A predicate can be combined with other predicates during hoisting.
+ In those cases the depth=1 predicates are still handled. Thus,
+ in the following example the isUpper() predicate will be suppressed
+ by line #4 when hoisted from "bizarre" into "start", but will still
+ be present in "bizarre" in order to predict "stmt".
+
+ start : (bizarre)* EOF ; // #1
+ // #2
+ bizarre : stmt // #3
+ | A // #4
+ ;
+
+ stmt : cast
+ | expr
+ ;
+
+ cast : <<isTypename(LATEXT(2))>>? LP ID RP ;
+
+ expr : LP ID RP ;
+ | <<isUpper(LATEXT(1))>>? A
+
+ Limitation (b) is illustrated by the following example of a
+ context guarded predicate:
+
+ rule : (A)? <<p>>? // #1
+ (A // #2
+ |B // #3
+ ) // #4
+ | <<q>> B // #5
+ ;
+
+ Recall that this means that when the lookahead is NOT A then
+ the predicate "p" is ignored and it attempts to match "A|B".
+ Ideally, the "B" at line #3 should suppress predicate "q".
+ However, the current version does not attempt to look past
+ the guard predicate to find context which might suppress other
+ predicates.
+
+ In some cases -mrhoist will lead to the reporting of ambiguities
+ which were not visible before:
+
+ start : (a)* "@";
+ a : bc | d;
+ bc : b | c ;
+
+ b : <<isUpper(LATEXT(1))>>? A;
+ c : A ;
+
+ d : A ;
+
+ In this case there is a true ambiguity in "a" between "bc" and "d"
+ which can both match "A". Without -mrhoist the predicate in "b"
+ is hoisted into "a" and there is no ambiguity reported. However,
+ with -mrhoist, the predicate in "b" is suppressed by "c" (as it
+ should be) making the ambiguity in "a" apparent.
+
+ The motivations for these changes were hoisting problems reported
+ by Reinier van den Born (reinier@vnet.ibm.com) and several others.
+
+#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <<p>>? expr
+
+ The existing context guarded predicate:
+
+ rule : (guard)? => <<p>>? expr
+ | next_alternative
+ ;
+
+ generates code which resembles:
+
+ if (lookahead(expr) && (!guard || pred)) {
+ expr()
+ } else ....
+
+ This is not suitable for some applications because it allows
+ expr() to be invoked when the predicate is false. This is
+ intentional because it is meant to mimic automatically computed
+ predicate context.
+
+ The new context guarded predicate uses the guard information
+ differently because it has a different goal. Consider:
+
+ rule : (guard)? && <<p>>? expr
+ | next_alternative
+ ;
+
+ The new style of context guarded predicate is equivalent to:
+
+ rule : <<guard==true && pred>>? expr
+ | next_alternative
+ ;
+
+ It generates code which resembles:
+
+ if (lookahead(expr) && guard && pred) {
+ expr();
+ } else ...
+
+ Both forms of guarded predicates severely restrict the form of
+ the context guard: it can contain no rule references, no
+ (...)*, no (...)+, and no {...}. It may contain token and
+ token class references, and alternation ("|").
+
+ Addition for 1.33MR11: in the token expression all tokens must
+ be at the same height of the token tree:
+
+ (A ( B | C))? && ... is ok (all height 2)
+ (A ( B | ))? && ... is not ok (some 1, some 2)
+ (A B C D | E F G H)? && ... is ok (all height 4)
+ (A B C D | E )? && ... is not ok (some 4, some 1)
+
+ This restriction is required in order to properly compute the lookahead
+ set for expressions like:
+
+ rule1 : (A B C)? && <<pred>>? rule2 ;
+ rule2 : (A|X) (B|Y) (C|Z);
+
+ This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com)
+
+#109. (Changed in 1.33MR10) improved trace information
+
+ The quality of the trace information provided by the "-gd"
+ switch has been improved significantly. Here is an example
+ of the output from a test program. It shows the rule name,
+ the first token of lookahead, the call depth, and the guess
+ status:
+
+ exit rule gusxx {"?"} depth 2
+ enter rule gusxx {"?"} depth 2
+ enter rule gus1 {"o"} depth 3 guessing
+ guess done - returning to rule gus1 {"o"} at depth 3
+ (guess mode continues - an enclosing guess is still active)
+ guess done - returning to rule gus1 {"Z"} at depth 3
+ (guess mode continues - an enclosing guess is still active)
+ exit rule gus1 {"Z"} depth 3 guessing
+ guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends)
+ enter rule gus1 {"o"} depth 3
+ guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends)
+ guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends)
+ exit rule gus1 {"Z"} depth 3
+ line 1: syntax error at "Z" missing SC
+ ...
+
+ Rule trace reporting is controlled by the value of the integer
+ [zz]traceOptionValue: when it is positive tracing is enabled,
+ otherwise it is disabled. Tracing during guess mode is controlled
+ by the value of the integer [zz]traceGuessOptionValue. When
+ it is positive AND [zz]traceOptionValue is positive rule trace
+ is reported in guess mode.
+
+ The values of [zz]traceOptionValue and [zz]traceGuessOptionValue
+ can be adjusted by subroutine calls listed below.
+
+ Depending on the presence or absence of the antlr -gd switch
+ the variable [zz]traceOptionValueDefault is set to 0 or 1. When
+ the parser is initialized or [zz]traceReset() is called the
+ value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue.
+ The value of [zz]traceGuessOptionValue is always initialized to 1,
+ but, as noted earlier, nothing will be reported unless
+ [zz]traceOptionValue is also positive.
+
+ When the parser state is saved/restored the value of the trace
+ variables are also saved/restored. If a restore causes a change in
+ reporting behavior from on to off or vice versa this will be reported.
+
+ When the -gd option is selected, the macro "#define zzTRACE_RULES"
+ is added to appropriate output files.
+
+ C++ mode
+ --------
+ int traceOption(int delta)
+ int traceGuessOption(int delta)
+ void traceReset()
+ int traceOptionValueDefault
+
+ C mode
+ --------
+ int zzTraceOption(int delta)
+ int zzTraceGuessOption(int delta)
+ void zzTraceReset()
+ int zzTraceOptionValueDefault
+
+ The argument "delta" is added to the traceOptionValue. To
+ turn on trace when inside a particular rule one:
+
+ rule : <<traceOption(+1);>>
+ (
+ rest-of-rule
+ )
+ <<traceOption(-1);>>
+ ; /* fail clause */ <<traceOption(-1);>>
+
+ One can use the same idea to turn *off* tracing within a
+ rule by using a delta of (-1).
+
+ An improvement in the rule trace was suggested by Sramji
+ Ramanathan (ps@kumaran.com).
+
+#108. A Note on Deallocation of Variables Allocated in Guess Mode
+
+ NOTE
+ ------------------------------------------------------
+ This mechanism only works for heap allocated variables
+ ------------------------------------------------------
+
+ The rewrite of the trace provides the machinery necessary
+ to properly free variables or undo actions following a
+ failed guess.
+
+ The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded
+ as part of the zzGUESS macro. When a guess is opened
+ the value of zzrv is 0. When a longjmp() is executed to
+ undo the guess, the value of zzrv will be 1.
+
+ The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded
+ as part of the zzGUESS_DONE macro. This is executed
+ whether the guess succeeds or fails as part of closing
+ the guess.
+
+ The guessSeq is a sequence number which is assigned to each
+ guess and is incremented by 1 for each guess which becomes
+ active. It is needed by the user to associate the start of
+ a guess with the failure and/or completion (closing) of a
+ guess.
+
+ Guesses are nested. They must be closed in the reverse
+ of the order that they are opened.
+
+ In order to free memory used by a variable during a guess
+ a user must write a routine which can be called to
+ register the variable along with the current guess sequence
+ number provided by the zzUSER_GUESS_HOOK macro. If the guess
+ fails, all variables tagged with the corresponding guess
+ sequence number should be released. This is ugly, but
+ it would require a major rewrite of antlr 1.33 to use
+ some mechanism other than setjmp()/longjmp().
+
+ The order of calls for a *successful* guess would be:
+
+ zzUSER_GUESS_HOOK(guessSeq,0);
+ zzUSER_GUESS_DONE_HOOK(guessSeq);
+
+ The order of calls for a *failed* guess would be:
+
+ zzUSER_GUESS_HOOK(guessSeq,0);
+ zzUSER_GUESS_HOOK(guessSeq,1);
+ zzUSER_GUESS_DONE_HOOK(guessSeq);
+
+ The default definitions of these macros are empty strings.
+
+ Here is an example in C++ mode. The zzUSER_GUESS_HOOK and
+ zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine
+ can be used without change in both C and C++ versions.
+
+ ----------------------------------------------------------------------
+ <<
+
+ #include "AToken.h"
+
+ typedef ANTLRCommonToken ANTLRToken;
+
+ #include "DLGLexer.h"
+
+ int main() {
+
+ {
+ DLGFileInput in(stdin);
+ DLGLexer lexer(&in,2000);
+ ANTLRTokenBuffer pipe(&lexer,1);
+ ANTLRCommonToken aToken;
+ P parser(&pipe);
+
+ lexer.setToken(&aToken);
+ parser.init();
+ parser.start();
+ };
+
+ fclose(stdin);
+ fclose(stdout);
+ return 0;
+ }
+
+ >>
+
+ <<
+ char *s=NULL;
+
+ #undef zzUSER_GUESS_HOOK
+ #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv);
+ #undef zzUSER_GUESS_DONE_HOOK
+ #define zzUSER_GUESS_DONE_HOOK(guessSeq) myGuessHook(guessSeq,2);
+
+ void myGuessHook(int guessSeq,int zzrv) {
+ if (zzrv == 0) {
+ fprintf(stderr,"User hook: starting guess #%d\n",guessSeq);
+ } else if (zzrv == 1) {
+ free (s);
+ s=NULL;
+ fprintf(stderr,"User hook: failed guess #%d\n",guessSeq);
+ } else if (zzrv == 2) {
+ free (s);
+ s=NULL;
+ fprintf(stderr,"User hook: ending guess #%d\n",guessSeq);
+ };
+ }
+
+ >>
+
+ #token A "a"
+ #token "[\t \ \n]" <<skip();>>
+
+ class P {
+
+ start : (top)+
+ ;
+
+ top : (which) ? <<fprintf(stderr,"%s is a which\n",s); free(s); s=NULL; >>
+ | other <<fprintf(stderr,"%s is an other\n",s); free(s); s=NULL; >>
+ ; <<if (s != NULL) free(s); s=NULL; >>
+
+ which : which2
+ ;
+
+ which2 : which3
+ ;
+ which3
+ : (label)? <<fprintf(stderr,"%s is a label\n",s);>>
+ | (global)? <<fprintf(stderr,"%s is a global\n",s);>>
+ | (exclamation)? <<fprintf(stderr,"%s is an exclamation\n",s);>>
+ ;
+
+ label : <<s=strdup(LT(1)->getText());>> A ":" ;
+
+ global : <<s=strdup(LT(1)->getText());>> A "::" ;
+
+ exclamation : <<s=strdup(LT(1)->getText());>> A "!" ;
+
+ other : <<s=strdup(LT(1)->getText());>> "other" ;
+
+ }
+ ----------------------------------------------------------------------
+
+ This is a silly example, but illustrates the idea. For the input
+ "a ::" with tracing enabled the output begins:
+
+ ----------------------------------------------------------------------
+ enter rule "start" depth 1
+ enter rule "top" depth 2
+ User hook: starting guess #1
+ enter rule "which" depth 3 guessing
+ enter rule "which2" depth 4 guessing
+ enter rule "which3" depth 5 guessing
+ User hook: starting guess #2
+ enter rule "label" depth 6 guessing
+ guess failed
+ User hook: failed guess #2
+ guess done - returning to rule "which3" at depth 5 (guess mode continues
+ - an enclosing guess is still active)
+ User hook: ending guess #2
+ User hook: starting guess #3
+ enter rule "global" depth 6 guessing
+ exit rule "global" depth 6 guessing
+ guess done - returning to rule "which3" at depth 5 (guess mode continues
+ - an enclosing guess is still active)
+ User hook: ending guess #3
+ enter rule "global" depth 6 guessing
+ exit rule "global" depth 6 guessing
+ exit rule "which3" depth 5 guessing
+ exit rule "which2" depth 4 guessing
+ exit rule "which" depth 3 guessing
+ guess done - returning to rule "top" at depth 2 (guess mode ends)
+ User hook: ending guess #1
+ enter rule "which" depth 3
+ .....
+ ----------------------------------------------------------------------
+
+ Remember:
+
+ (a) Only init-actions are executed during guess mode.
+ (b) A rule can be invoked multiple times during guess mode.
+ (c) If the guess succeeds the rule will be called once more
+ without guess mode so that normal actions will be executed.
+ This means that the init-action might need to distinguish
+ between guess mode and non-guess mode using the variable
+ [zz]guessing.
+
+#101. (Changed in 1.33MR10) antlr -info command line switch
+
+ -info
+
+ p - extra predicate information in generated file
+
+ t - information about tnode use:
+ at the end of each rule in generated file
+ summary on stderr at end of program
+
+ m - monitor progress
+ prints name of each rule as it is started
+ flushes output at start of each rule
+
+ f - first/follow set information to stdout
+
+ 0 - no operation (added in 1.33MR11)
+
+ The options may be combined and may appear in any order.
+ For example:
+
+ antlr -info ptm -CC -gt -mrhoist on mygrammar.g
+
+#100a. (Changed in 1.33MR10) Predicate tree simplification
+
+ When the same predicates can be referenced in more than one
+ alternative of a block large predicate trees can be formed.
+
+ The difference that these optimizations make is so dramatic
+ that I have decided to use it even when -mrhoist is not selected.
+
+ Consider the following grammar:
+
+ start : ( all )* ;
+
+ all : a
+ | d
+ | e
+ | f
+ ;
+
+ a : c A B
+ | c A C
+ ;
+
+ c : <<AAA(LATEXT(2))>>?
+ ;
+
+ d : <<BBB(LATEXT(2))>>? B C
+ ;
+
+ e : <<CCC(LATEXT(2))>>? B C
+ ;
+
+ f : e X Y
+ ;
+
+ In rule "a" there is a reference to rule "c" in both alternatives.
+ The length of the predicate AAA is k=2 and it can be followed in
+ alternative 1 only by (A B) while in alternative 2 it can be
+ followed only by (A C). Thus they do not have identical context.
+
+ In rule "all" the alternatives which refer to rules "e" and "f" allow
+ elimination of the duplicate reference to predicate CCC.
+
+ The table below summarized the kind of simplification performed by
+ 1.33MR10. In the table, X and Y stand for single predicates
+ (not trees).
+
+ (OR X (OR Y (OR Z))) => (OR X Y Z)
+ (AND X (AND Y (AND Z))) => (AND X Y Z)
+
+ (OR X (... (OR X Y) ... )) => (OR X (... Y ... ))
+ (AND X (... (AND X Y) ... )) => (AND X (... Y ... ))
+ (OR X (... (AND X Y) ... )) => (OR X (... ... ))
+ (AND X (... (OR X Y) ... )) => (AND X (... ... ))
+
+ (AND X) => X
+ (OR X) => X
+
+ In a test with a complex grammar for a real application, a predicate
+ tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)".
+
+ In 1.33MR10 there is a greater effort to release memory used
+ by predicates once they are no longer in use.
+
+#100b. (Changed in 1.33MR10) Suppression of extra predicate tests
+
+ The following optimizations require that -mrhoist be selected.
+
+ It is relatively easy to optimize the code generated for predicate
+ gates when they are of the form:
+
+ (AND X Y Z ...)
+ or (OR X Y Z ...)
+
+ where X, Y, Z, and "..." represent individual predicates (leaves) not
+ predicate trees.
+
+ If the predicate is an AND the contexts of the X, Y, Z, etc. are
+ ANDed together to create a single Tree context for the group and
+ context tests for the individual predicates are suppressed:
+
+ --------------------------------------------------
+ Note: This was incorrect. The contexts should be
+ ORed together. This has been fixed. A more
+ complete description is available in item #152.
+ ---------------------------------------------------
+
+ Optimization 1: (AND X Y Z ...)
+
+ Suppose the context for Xtest is LA(1)==LP and the context for
+ Ytest is LA(1)==LP && LA(2)==ID.
+
+ Without the optimization the code would resemble:
+
+ if (lookaheadContext &&
+ !(LA(1)==LP && LA(1)==LP && LA(2)==ID) ||
+ ( (! LA(1)==LP || Xtest) &&
+ (! (LA(1)==LP || LA(2)==ID) || Xtest)
+ )) {...
+
+ With the -mrhoist optimization the code would resemble:
+
+ if (lookaheadContext &&
+ ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {...
+
+ Optimization 2: (OR X Y Z ...) with identical contexts
+
+ Suppose the context for Xtest is LA(1)==ID and for Ytest
+ the context is also LA(1)==ID.
+
+ Without the optimization the code would resemble:
+
+ if (lookaheadContext &&
+ ! (LA(1)==ID || LA(1)==ID) ||
+ (LA(1)==ID && Xtest) ||
+ (LA(1)==ID && Ytest) {...
+
+ With the -mrhoist optimization the code would resemble:
+
+ if (lookaheadContext &&
+ (! LA(1)==ID) || (Xtest || Ytest) {...
+
+ Optimization 3: (OR X Y Z ...) with distinct contexts
+
+ Suppose the context for Xtest is LA(1)==ID and for Ytest
+ the context is LA(1)==LP.
+
+ Without the optimization the code would resemble:
+
+ if (lookaheadContext &&
+ ! (LA(1)==ID || LA(1)==LP) ||
+ (LA(1)==ID && Xtest) ||
+ (LA(1)==LP && Ytest) {...
+
+ With the -mrhoist optimization the code would resemble:
+
+ if (lookaheadContext &&
+ (zzpf=0,
+ (LA(1)==ID && (zzpf=1) && Xtest) ||
+ (LA(1)==LP && (zzpf=1) && Ytest) ||
+ !zzpf) {
+
+ These may appear to be of similar complexity at first,
+ but the non-optimized version contains two tests of each
+ context while the optimized version contains only one
+ such test, as well as eliminating some of the inverted
+ logic (" !(...) || ").
+
+ Optimization 4: Computation of predicate gate trees
+
+ When generating code for the gates of predicate expressions
+ antlr 1.33 vanilla uses a recursive procedure to generate
+ "&&" and "||" expressions for testing the lookahead. As each
+ layer of the predicate tree is exposed a new set of "&&" and
+ "||" expressions on the lookahead are generated. In many
+ cases the lookahead being tested has already been tested.
+
+ With -mrhoist a lookahead tree is computed for the entire
+ lookahead expression. This means that predicates with identical
+ context or context which is a subset of another predicate's
+ context disappear.
+
+ This is especially important for predicates formed by rules
+ like the following:
+
+ upperCaseVowel : <<isUpperCase(LATEXT(1))>>? vowel;
+ vowel: : <<isVowel(LATEXT(1))>>? LETTERS;
+
+ These predicates are combined using AND since both must be
+ satisfied for rule upperCaseVowel. They have identical
+ context which makes this optimization very effective.
+
+ The affect of Items #100a and #100b together can be dramatic. In
+ a very large (but real world) grammar one particular predicate
+ expression was reduced from an (unreadable) 50 predicate leaves,
+ 195 LA(1) terms, and 5500 characters to an (easily comprehensible)
+ 3 predicate leaves (all different) and a *single* LA(1) term.
+
+#98. (Changed in 1.33MR10) Option "-info p"
+
+ When the user selects option "-info p" the program will generate
+ detailed information about predicates. If the user selects
+ "-mrhoist on" additional detail will be provided explaining
+ the promotion and suppression of predicates. The output is part
+ of the generated file and sandwiched between #if 0/#endif statements.
+
+ Consider the following k=1 grammar:
+
+ start : ( all ) * ;
+
+ all : ( a
+ | b
+ )
+ ;
+
+ a : c B
+ ;
+
+ c : <<LATEXT(1)>>?
+ | B
+ ;
+
+ b : <<LATEXT(1)>>? X
+ ;
+
+ Below is an excerpt of the output for rule "start" for the three
+ predicate options (off, on, and maintenance release style hoisting).
+
+ For those who do not wish to use the "-mrhoist on" option for code
+ generation the option can be used in a "diagnostic" mode to provide
+ valuable information:
+
+ a. where one should insert null actions to inhibit hoisting
+ b. a chain of rule references which shows where predicates are
+ being hoisted
+
+ ======================================================================
+ Example of "-info p" with "-mrhoist on"
+ ======================================================================
+ #if 0
+
+ Hoisting of predicate suppressed by alternative without predicate.
+ The alt without the predicate includes all cases where the
+ predicate is false.
+
+ WITH predicate: line 11 v36.g
+ WITHOUT predicate: line 12 v36.g
+
+ The context set for the predicate:
+
+ B
+
+ The lookahead set for alt WITHOUT the semantic predicate:
+
+ B
+
+ The predicate:
+
+ pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g
+
+ set context:
+ B
+ tree context: null
+
+ Chain of referenced rules:
+
+ #0 in rule start (line 1 v36.g) to rule all
+ #1 in rule all (line 3 v36.g) to rule a
+ #2 in rule a (line 8 v36.g) to rule c
+ #3 in rule c (line 11 v36.g)
+
+ #endif
+ &&
+ #if 0
+
+ pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g
+
+ set context:
+ X
+ tree context: null
+
+ #endif
+ ======================================================================
+ Example of "-info p" with the default -prc setting ( "-prc off")
+ ======================================================================
+ #if 0
+
+ OR
+ pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g
+
+ set context:
+ nil
+ tree context: null
+
+ pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g
+
+ set context:
+ nil
+ tree context: null
+
+ #endif
+ ======================================================================
+ Example of "-info p" with "-prc on" and "-mrhoist off"
+ ======================================================================
+ #if 0
+
+ OR
+ pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g
+
+ set context:
+ B
+ tree context: null
+
+ pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g
+
+ set context:
+ X
+ tree context: null
+
+ #endif
+ ======================================================================
+
+#60. (Changed in 1.33MR7) Major changes to exception handling
+
+ There were significant problems in the handling of exceptions
+ in 1.33 vanilla. The general problem is that it can only
+ process one level of exception handler. For example, a named
+ exception handler, an exception handler for an alternative, or
+ an exception for a subrule always went to the rule's exception
+ handler if there was no "catch" which matched the exception.
+
+ In 1.33MR7 the exception handlers properly "nest". If an
+ exception handler does not have a matching "catch" then the
+ nextmost outer exception handler is checked for an appropriate
+ "catch" clause, and so on until an exception handler with an
+ appropriate "catch" is found.
+
+ There are still undesirable features in the way exception
+ handlers are implemented, but I do not have time to fix them
+ at the moment:
+
+ The exception handlers for alternatives are outside the
+ block containing the alternative. This makes it impossible
+ to access variables declared in a block or to resume the
+ parse by "falling through". The parse can still be easily
+ resumed in other ways, but not in the most natural fashion.
+
+ This results in an inconsistency between named exception
+ handlers and exception handlers for alternatives. When
+ an exception handler for an alternative "falls through"
+ it goes to the nextmost outer handler - not the "normal
+ action".
+
+ A major difference between 1.33MR7 and 1.33 vanilla is
+ the default action after an exception is caught:
+
+ 1.33 Vanilla
+ ------------
+ In 1.33 vanilla the signal value is set to zero ("NoSignal")
+ and the code drops through to the code following the exception.
+ For named exception handlers this is the "normal action".
+ For alternative exception handlers this is the rule's handler.
+
+ 1.33MR7
+ -------
+ In 1.33MR7 the signal value is NOT automatically set to zero.
+
+ There are two cases:
+
+ For named exception handlers: if the signal value has been
+ set to zero the code drops through to the "normal action".
+
+ For all other cases the code branches to the nextmost outer
+ exception handler until it reaches the handler for the rule.
+
+ The following macros have been defined for convenience:
+
+ C/C++ Mode Name
+ --------------------
+ (zz)suppressSignal
+ set signal & return signal arg to 0 ("NoSignal")
+ (zz)setSignal(intValue)
+ set signal & return signal arg to some value
+ (zz)exportSignal
+ copy the signal value to the return signal arg
+
+ I'm not sure why PCCTS make a distinction between the local
+ signal value and the return signal argument, but I'm loathe
+ to change the code. The burden of copying the local signal
+ value to the return signal argument can be given to the
+ default signal handler, I suppose.
+
+#53. (Explanation for 1.33MR6) What happens after an exception is caught ?
+
+ The Book is silent about what happens after an exception
+ is caught.
+
+ The following code fragment prints "Error Action" followed
+ by "Normal Action".
+
+ test : Word ex:Number <<printf("Normal Action\n");>>
+ exception[ex]
+ catch NoViableAlt:
+ <<printf("Error Action\n");>>
+ ;
+
+ The reason for "Normal Action" is that the normal flow of the
+ program after a user-written exception handler is to "drop through".
+ In the case of an exception handler for a rule this results in
+ the execution of a "return" statement. In the case of an
+ exception handler attached to an alternative, rule, or token
+ this is the code that would have executed had there been no
+ exception.
+
+ The user can achieve the desired result by using a "return"
+ statement.
+
+ test : Word ex:Number <<printf("Normal Action\n");>>
+ exception[ex]
+ catch NoViableAlt:
+ <<printf("Error Action\n"); return;>>
+ ;
+
+ The most powerful mechanism for recovery from parse errors
+ in pccts is syntactic predicates because they provide
+ backtracking. Exceptions allow "return", "break",
+ "consumeUntil(...)", "goto _handler", "goto _fail", and
+ changing the _signal value.
+
+#41. (Added in 1.33MR6) antlr -stdout
+
+ Using "antlr -stdout ..." forces the text that would
+ normally go to the grammar.c or grammar.cpp file to
+ stdout.
+
+#40. (Added in 1.33MR6) antlr -tab to change tab stops
+
+ Using "antlr -tab number ..." changes the tab stops
+ for the grammar.c or grammar.cpp file. The number
+ must be between 0 and 8. Using 0 gives tab characters,
+ values between 1 and 8 give the appropriate number of
+ space characters.
+
+#34. (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue)
+
+ Previously there was no public function for changing the line
+ number maintained by the lexer.
+
+#28. (Added to 1.33MR1) More control over DLG header
+
+ Version 1.33MR1 adds the following directives to PCCTS
+ for C++ mode:
+
+ #lexprefix <<source code>>
+
+ Adds source code to the DLGLexer.h file
+ after the #include "DLexerBase.h" but
+ before the start of the class definition.
+
+ #lexmember <<source code>>
+
+ Adds source code to the DLGLexer.h file
+ as part of the DLGLexer class body. It
+ appears immediately after the start of
+ the class and a "public: statement.
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/KNOWN_PROBLEMS.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/KNOWN_PROBLEMS.txt
new file mode 100644
index 00000000..8c4bef7a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/KNOWN_PROBLEMS.txt
@@ -0,0 +1,241 @@
+
+ =======================================================
+ Known Problems In PCCTS - Last revised 14 November 1998
+ =======================================================
+
+#17. The dlg fix for handling characters up to 255 is incorrect.
+
+ See item #207.
+
+ Reported by Frank Hartmann.
+
+#16. A note about "&&" predicates (Mike Dimmick)
+
+ Mike Dimmick has pointed out a potential pitfall in the use of the
+ "&&" style predicate. Consider:
+
+ r0: (g)? => <<P>>? r1
+ | ...
+ ;
+ r1: A | B;
+
+ If the context guard g is not a subset of the lookahead context for r1
+ (in other words g is neither A nor B) then the code may execute r1
+ even when the lookahead context is not satisfied. This is an error
+ by the person coding the grammar, and the error should be reported to
+ the user, but it isn't. expect. Some examples I've run seem to
+ indicate that such an error actually results in the rule becoming
+ unreachable.
+
+ When g is properly coded the code is correct, the problem is when g
+ is not properly coded.
+
+ A second problem reported by Mike Dimmick is that the test for a
+ failed validation predicate is equivalent to a test on the predicate
+ along. In other words, if the "&&" has not been hoisted then it may
+ falsely report a validation error.
+
+#15. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions
+
+ An bug (or at least an oddity) is that a reference to LT(1), LA(1),
+ or LATEXT(1) in an action which immediately follows a token match
+ in a rule refers to the token matched, not the token which is in
+ the lookahead buffer. Consider:
+
+ r : abc <<action alpha>> D <<action beta>> E;
+
+ In this case LT(1) in action alpha will refer to the next token in
+ the lookahead buffer ("D"), but LT(1) in action beta will refer to
+ the token matched by D - the preceding token.
+
+ A warning has been added which warns users about this when an action
+ following a token match contains a reference to LT(1), LA(1), or LATEXT(1).
+
+ This behavior should be changed, but it appears in too many programs
+ now. Another problem, perhaps more significant, is that the obvious
+ fix (moving the consume() call to before the action) could change the
+ order in which input is requested and output appears in existing programs.
+
+ This problem was reported, along with a fix by Benjamin Mandel
+ (beny@sd.co.il). However, I felt that changing the behavior was too
+ dangerous for existing code.
+
+#14. Parsing bug in dlg
+
+ THM: I have been unable to reproduce this problem.
+
+ Reported by Rick Howard Mijenix Corporation (rickh@mijenix.com).
+
+ The regular expression parser (in rexpr.c) fails while
+ trying to parse the following regular expression:
+
+ {[a-zA-Z]:}(\\\\[a-zA-Z0-9]*)+
+
+ See my comment in the following excerpt from rexpr.c:
+
+ /*
+ * <regExpr> ::= <andExpr> ( '|' {<andExpr>} )*
+ *
+ * Return -1 if syntax error
+ * Return 0 if none found
+ * Return 1 if a regExrp was found
+ */
+ static
+ regExpr(g)
+ GraphPtr g;
+ {
+ Graph g1, g2;
+
+ if ( andExpr(&g1) == -1 )
+ {
+ return -1;
+ }
+
+ while ( token == '|' )
+ {
+ int a;
+ next();
+ a = andExpr(&g2);
+ if ( a == -1 ) return -1; /* syntax error below */
+ else if ( !a ) return 1; /* empty alternative */
+ g1 = BuildNFA_AorB(g1, g2);
+ }
+
+ if ( token!='\0' ) return -1;
+ *****
+ ***** It appears to fail here becuause token is 125 - the closing '}'
+ ***** If I change it to:
+ ***** if ( token!='\0' && token!='}' && token!= ')' ) return -1;
+ *****
+ ***** It succeeds, but I'm not sure this is the corrrect approach.
+ *****
+ *g = g1;
+ return 1;
+ }
+
+#13. dlg reports an invalid range for: [\0x00-\0xff]
+
+ Diagnosed by Piotr Eljasiak (eljasiak@no-spam.zt.gdansk.tpsa.pl):
+
+ Fixed in MR16.
+
+#12. Strings containing comment actions
+
+ Sequences that looked like C style comments appearing in string
+ literals are improperly parsed by antlr/dlg.
+
+ << fprintf(out," /* obsolete */ ");
+
+ For this case use:
+
+ << fprintf(out," \/\* obsolete \*\/ ");
+
+ Reported by K.J. Cummings (cummings@peritus.com).
+
+#11. User hook for deallocation of variables on guess fail
+
+ The mechanism outlined in Item #108 works only for
+ heap allocated variables.
+
+#10. Label re-initialization in ( X {y:Y} )*
+
+ If a label assignment is optional and appears in a
+ (...)* or (...)+ block it will not be reset to NULL
+ when it is skipped by a subsequent iteration.
+
+ Consider the example:
+
+ ( X { y:Y })* Z
+
+ with input:
+
+ X Y X Z
+
+ The first time through the block Y will be matched and
+ y will be set to point to the token. On the second
+ iteration of the (...)* block there is no match for Y.
+ But y will not be reset to NULL, as the user might
+ expect, it will contain a reference to the Y that was
+ matched in the first iteration.
+
+ The work-around is to manually reset y:
+
+ ( X << y = NULL; >> { y:Y } )* Z
+
+ or
+
+ ( X ( y:Y | << y = NULL; >> /* epsilon */ ) )* Z
+
+ Reported by Jeff Vincent (JVincent@novell.com).
+
+#9. PCCTAST.h PCCTSAST::setType() is a noop
+
+#8. #tokdefs with ~Token and .
+
+ THM: I have been unable to reproduce this problem.
+
+ When antlr uses #tokdefs to define tokens the fields of
+ #errclass and #tokclass do not get properly defined.
+ When it subsequently attempts to take the complement of
+ the set of tokens (using ~Token or .) it can refer to
+ tokens which don't have names, generating a fatal error.
+
+#7. DLG crashes on some invalid inputs
+
+ THM: In MR20 have fixed the most common cases.
+
+ The following token definition will cause DLG to crash.
+
+ #token "()"
+
+ Reported by Mengue Olivier (dolmen@bigfoot.com).
+
+#6. On MS systems \n\r is treated as two new lines
+
+ Fixed.
+
+#5. Token expressions in #tokclass
+
+ #errclass does not support TOK1..TOK2 or ~TOK syntax.
+ #tokclass does not support ~TOKEN syntax
+
+ A workaround for #errclass TOK1..TOK2 is to use a
+ #tokclass.
+
+ Reported by Dave Watola (dwatola@amtsun.jpl.nasa.gov)
+
+#4. A #tokdef must appear "early" in the grammar file.
+
+ The "early" section of the grammar file is the only
+ place where the following directives may appear:
+
+ #header
+ #first
+ #tokdefs
+ #parser
+
+ Any other kind of statement signifiies the end of the
+ "early" section.
+
+#3. Use of PURIFY macro for C++ mode
+
+ Item #93 of the CHANGES_FROM_1.33 describes the use of
+ the PURIFY macro to zero arguments to be passed by
+ upward inheritance.
+
+ #define PURIFY(r, s) memset((char *) &(r), '\0', (s));
+
+ This may not be the right thing to do for C++ objects that
+ have constructors. Reported by Bonny Rais (bonny@werple.net.au).
+
+ For those cases one should #define PURIFY to be an empty macro
+ in the #header or #first actions.
+
+#2. Fixed in 1.33MR10 - See CHANGES_FROM_1.33 Item #80.
+
+#1. The quality of support for systems with 8.3 file names leaves
+ much to be desired. Since the kit is distributed using the
+ long file names and the make file uses long file names it requires
+ some effort to generate. This will probably not be changed due
+ to the large number of systems already written using the long
+ file names.
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/MPW_Read_Me b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/MPW_Read_Me
new file mode 100644
index 00000000..14587fc3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/MPW_Read_Me
@@ -0,0 +1,21 @@
+
+1. You can control the creator type of generated files by changing a value of
+ #if control statement.
+
+
+ pccts:h:pcctscfg.h
+
+ line 225-231
+
+ #if 0
+ #define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */
+ #endif
+ #if 0
+ #define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */
+ #endif
+ #if 0
+ #define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */
+ #endif
+
+2. If you want to build 68K version. You must convert all source files to Macintosh
+ format before compile.
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/Makefile
new file mode 100644
index 00000000..577d6cb6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/Makefile
@@ -0,0 +1,15 @@
+#
+# Main makefile for PCCTS 1.33MR33 /* MRXXX */
+#
+pccts:
+ pushd . & cd antlr & $(MAKE) /nologo /f AntlrMS.mak & popd
+ pushd . & cd dlg & $(MAKE) /nologo /f DlgMS.mak & popd
+
+clean:
+ pushd . & cd antlr & $(MAKE) /nologo /f AntlrMS.mak clean & popd
+ pushd . & cd dlg & $(MAKE) /nologo /f DlgMS.mak clean & popd
+
+cleanall:
+ pushd . & cd antlr & $(MAKE) /nologo /f AntlrMS.mak cleanall & popd
+ pushd . & cd dlg & $(MAKE) /nologo /f DlgMS.mak cleanall & popd
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.bcc b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.bcc
new file mode 100644
index 00000000..535bba2e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.bcc
@@ -0,0 +1,184 @@
+March 95
+Version 1.32 of pccts
+
+At the moment this file is available via anonymous FTP at
+
+ Node: marvin.ecn.purdue.edu
+ File: pub/pccts/1.32/NOTES.BCC
+
+Mail corrections or additions to David Seidel <71333.1575@compuserve.com>
+===============================================================================
+Notes on Building PCCTS 1.32 with Borland C++
+
+David Seidel, Innovative Data Concepts Incorporated
+CompuServe: 71333,1575
+Internet: 71333.1575@compuserve.com
+ dseidel@delphi.com
+
+I have gotten ANTLR and DLG to succesfully build with BCC 4.0, but have found
+from experience that ANTLR, in particular, is likely to run out of memory
+with grammars over a certain size, or with larger values for the -k and -ck
+options. Now that BCC 4.02 and the new Borland Power Pack for DOS is now
+available, I feel that there is no excuse not to build these tools as
+32-bit executables, as they ought to be.
+
+For people without the Power Pack, the makefiles below should be fairly easily
+modified to build 16-bit real-mode executables, but I don't really recommend
+it. As an alternative, you might consider the highly regarded DJGPP compiler
+(a DOS port of the Gnu GCC compiler, with a DOS extender included). Hopefully
+some other PCCTS who has DJGPP can provode whatever advice is necessary. The
+Watcom compiler is also an excellent possibility (albeit a commercial one),
+and I hope to make available Watcom makefiles in the near future.
+
+Here are the makefiles I am using. Both makefiles use a compiler configuration
+file that contains compiler switches such as optimization settings. I call
+this file bor32.cfg and keep a copy in both the ANTLR and DLG subdirectories.
+
+==== File: bor32.cfg (cut here) ===============================================
+-w-
+-RT-
+-x-
+-N-
+-k-
+-d
+-O2-e-l
+-Z
+-D__STDC__=1
+==== End of file bor32.cfg (cut here) =========================================
+
+==== File: antlr\bor32.mak (cut here) =========================================
+#
+# ANTLR 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by
+# David Seidel
+# Innovative Data Concepts Incorporated
+# 71333.1575@compuserve.com (or) dseidel@delphi.com
+#
+# Notes: 1. Compiler switches (optimization etc.) are contained in the
+# file bor32.cfg.
+# 2. This makefile requires Borland C++ 4.02 or greater with
+# the DOS Power Pack add-on package.
+# 3. Change the BCCDIR macro below to the topmost directory in
+# which BCC is installed on your system.
+#
+
+BCCDIR = d:\bc4
+CC = bcc32
+SET = ..\support\set
+PCCTS_H = ..\h
+ANTLR = ..\bin\antlr
+DLG = ..\bin\dlg
+CFLAGS = -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \
+ +bor32.cfg
+LIBS = dpmi32 cw32
+OBJ_EXT = obj
+OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj fset.obj \
+ gen.obj globals.obj hash.obj lex.obj main.obj misc.obj pred.obj dialog.obj \
+ set.obj
+
+.c.obj:
+ $(CC) -c $(CFLAGS) {$&.c }
+
+antlr.exe: $(OBJS)
+ tlink32 @&&|
+-Tpe -ax -c -s -L$(BCCDIR)\lib +
+$(BCCDIR)\lib\c0x32 $**
+$@
+
+$(LIBS)
+;
+|
+ copy *.exe ..\bin
+
+
+# *********** Target list of PC machines ***********
+#
+# Don't worry about the ambiguity messages coming from antlr
+# for making antlr.c etc... [should be 10 of them, I think]
+#
+
+# leave this commented out for initial build!
+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g
+# $(ANTLR) antlr.g
+
+antlr.$(OBJ_EXT): antlr.c mode.h tokens.h
+
+scan.$(OBJ_EXT): scan.c mode.h tokens.h
+
+# leave this commented out for initial build!
+#scan.c mode.h: parser.dlg
+# $(DLG) -C2 parser.dlg scan.c
+
+set.$(OBJ_EXT): $(SET)\set.c
+ $(CC) -c $(CFLAGS) $(SET)\set.c
+
+==== End of file antlr\bor32.mak (cut here) ===================================
+
+==== File: dlg\bor32.mak (cut here) ===========================================
+#
+# DLG 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by
+# David Seidel
+# Innovative Data Concepts Incorporated
+# 71333.1575@compuserve.com (or) dseidel@delphi.com
+#
+# Notes: 1. Compiler switches (optimization etc.) are contained in the
+# file bor32.cfg.
+# 2. This makefile requires Borland C++ 4.02 or greater with
+# the DOS Power Pack add-on package.
+# 3. Change the BCCDIR macro below to the topmost directory in
+# which BCC is installed on your system.
+#
+
+
+BCCDIR = d:\bc4
+CC = bcc32
+SET = ..\support\set
+PCCTS_H = ..\h
+ANTLR = ..\bin\antlr
+DLG = ..\bin\dlg
+CFLAGS = -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \
+ +bor32.cfg
+LIBS = dpmi32 cw32
+OBJ_EXT = obj
+OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \
+ output.obj relabel.obj automata.obj set.obj
+
+.c.obj:
+ $(CC) -c $(CFLAGS) {$&.c }
+
+dlg.exe : $(OBJS)
+ tlink32 @&&|
+-Tpe -ax -c -s -L$(BCCDIR)\lib +
+c0x32 $**
+$@
+
+$(LIBS)
+;
+|
+ copy *.exe ..\bin
+
+dlg_p.obj: dlg_p.c
+
+dlg_a.obj: dlg_a.c
+
+main.obj: main.c
+
+err.obj: err.c
+
+support.obj: support.c
+
+output.obj: output.c
+
+relabel.obj: relabel.c
+
+automata.obj: automata.c
+
+set.$(OBJ_EXT): $(SET)\set.c
+ $(CC) -c $(CFLAGS) $(SET)\set.c
+
+==== End of file dlg\bor32.mak (cut here) =====================================
+
+
+
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.msvc b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.msvc
new file mode 100644
index 00000000..04809293
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/NOTES.msvc
@@ -0,0 +1,189 @@
+
+ Microsoft Visual C Stuff
+
+
+[Tom Moog 2-Oct-98
+
+ Users of Microsoft Visual C++ should download a separate
+ ready-to-run zip file from my web site. It contains
+ binaries, static library, and a sample project.
+]
+
+[
+ Two notes added by Tom Moog 23-Sep-97. I believe the *.dsp and
+ *.mak files that were once at the end of this file are now obsolete.
+
+ The following MSVC .dsp and .mak files for pccts and sorcerer
+ were contributed by Stanislaw Bochnak (S.Bochnak@microtool.com.pl)
+ and Jeff Vincent (jvincent@novell.com)
+
+ PCCTS Distribution Kit
+ ----------------------
+ pccts/antlr/AntlrMSVC50.dsp
+ pccts/antlr/AntlrMSVC50.mak
+
+ pccts/dlg/DlgMSVC50.dsp
+ pccts/dlg/DlgMSVC50.mak
+
+ pccts/support/genmk/watgenmk.mak
+ pccts/support/msvc.dsp
+
+ Sorcerer Distribution Kit
+ -------------------------
+ pccts/sorcerer/SorcererMSVC50.dsp
+ pccts/sorcerer/SorcererMSVC50.mak
+
+ pccts/sorcerer/lib/msvc.dsp
+
+ I do not have an MS based computer. If you discover problems
+ please report them so as to save trouble for others in the future.
+]
+
+[
+ Modified by Terence Parr (September 1995) to change .C to .cpp
+]
+
+[
+ This file contains notes on MSVC for Windows NT console execs by Dave
+ Seidel and an explanation of flags etc.. by John Hall; good luck,
+ Terence
+]
+
+===============================================================================
+Date: Sat, 31 Dec 1994 11:40:36 -0500 (EST)
+From: David Seidel <75342.2034@compuserve.com>
+
+I've succesfully build 1.31b3 with djgpp for DOS and MSVC 2.0 for Windows
+NT. The only (minor) problem I had was that GNU make (version 3.71, in the
+djgpp port) complained about "multiple targets" in both the antlr and dlg
+makefiles. I got around the error by, in each makefile, commenting out the
+$(SRC) dependency, for example:
+
+ antlr: $(OBJ) #$(SRC)
+
+I don't know why this is happenning, since you haven't changed that part of
+the makefile at all, and I think this used to work ok...
+
+Here are the makefiles I built from within the MSVC 2.0 environment for antlr
+and dlg and Windows NT console executables. Please feel free to pass them
+on. Of course, as soon as 1.31 "goes gold", I will send you nice new
+binaries. I'm not going to bother to keep doing both Borland and djgpp for
+DOS however. Instead, I'll just keep the djgpp version up to date and also
+provide WinNT binaries.
+
+Dave
+===============================================================================
+
+ How to port PCCTS 1.10 (and 1.32 hopefully) to Visual C++
+
+ By
+
+ John Hall <jhall@ivy.wpi.edu>
+
+Here is how to compile an ANTLR grammar in Visual C++. These steps
+describe how to have your ANTLR grammar parse the input file the user
+selects when they choose File Open in your Windows application. (Even
+if you aren't using Visual C++, the steps should be portable enough to
+other compilers.)
+
+ * Make sure that ANTLR and DLG generate ANSI code (use the -ga
+ switch).
+
+ * Set the following compiler flags in Visual C++ (these are in the
+ Memory Model category of the compiler options in the Project
+ Options menu):
+
+ FLAG MEANING
+ ==== ==============================================================
+ /AL Large memory model (multiple data segments; data items must be
+ smaller than 64K).
+
+ /Gtn Allocates all items whose size is greater than or equal to n
+ in a new data segment. (I let n be 256: /Gt256.)
+
+ /Gx- All references to data items are done with far addressing in
+ case they are placed in a far segment.
+
+ * Add the following member variable to the attributes section of your
+ derived CDocument class (you will need to make sure you also
+ include stdio.h):
+
+ FILE *fp;
+
+ * Add the following method to your derived CDocument class:
+
+ BOOL CAppDoc::OnOpenDocument(const char* pszPathName)
+ {
+ // Call CDocument's OnOpenDocument to do housekeeping for us
+ // DON'T add anything to the loading section of Serialize
+ if (!CDocument::OnOpenDocument(pszPathName))
+ return FALSE;
+
+ // Open input file
+ if ((fp = fopen(pszPathName, "r")) == NULL)
+ return FALSE;
+
+ // Parse input file
+ ANTLR(start(), fp);
+
+ // Close input file
+ fclose(fp);
+ return TRUE;
+ }
+
+ (Note: additional code may be necessary, depending on your parser.
+ For example, if your parser uses PCCTS's symbol table library, you
+ will need to insert calls to zzs_init and zzs_done.)
+
+ * Compile the generated C files as C++ files. (I renamed the files
+ to have a .CPP extension to fool Visual C++ into thinking they were
+ C++ files. One might also use the /Tp switch, but that switch
+ requires you separately include the filename.) [I used this step
+ as an easy out for all the external linking errors I was getting
+ that I couldn't fix by declaring things extern "C".]
+
+ * Make sure the __STDC__ portion of the generated files gets
+ compiled. (Either define __STDC__ yourself or else change all
+ occurrences of __STDC__ to __cplusplus in the generated files. You
+ can define __STDC__ in the Preprocessor category of the compiler
+ options.)
+
+ ================================================================
+ = Note 23-Sep-97: This is probably not necessary any more. =
+ = With 1.33MRxxx the use of __STDC__ was replaced with the =
+ = macro __USE_PROTOS to control the compilation of prototypes. =
+ ================================================================
+
+That last step is important for Visual C++, but may not apply to other
+compilers. For C++ compilers, whether __STDC__ is defined is
+implementation dependent (ARM, page 379). Apparently, Visual C++ does
+not to define it; it also does not support "old style" C function
+definitions (which is okay, according to page 404 of the ARM). Those
+two things together caused problems when trying to port the code.
+When it saw this:
+
+#ifdef __STDC__
+void
+globals(AST **_root)
+#else
+globals(_root)
+AST **_root;
+#endif
+
+it skipped the __STDC__ section and tried to process the "old style"
+function definition, where it choked.
+
+When you finally get your parser to compile and link without error,
+you may get General Protection Fault errors at run time. The problem
+I had was that a NULL was passed to a variable argument function
+without an explicit cast. The function grabbed a pointer (32-bits)
+off the stack using va_arg, but the NULL was passed silently as the
+integer 0 (16 bits), making the resulting pointer was invalid. (This
+was in PCCTS's sample C parser.)
+
+There is one other thing I might suggest to help you avoid a run-time
+error. Make sure you redefine the default error reporting function,
+zzsyn. To do this, put "#define USER_ZZSYN" in your #header section
+and put your own zzsyn somewhere. You can then pop up a MessageBox or
+print the error to some output window.
+===============================================================================
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/README b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/README
new file mode 100644
index 00000000..3d1da253
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/README
@@ -0,0 +1,159 @@
+
+ Parr Research Corporation
+ with
+ Purdue University Electrical Engineering
+ and
+ University of Minnesota, AHPCRC
+
+ Terence Parr
+ Russell Quong
+ Will Cohen
+ Hank Dietz
+
+
+A central place for information about PCCTS 1.33 is:
+
+ http://www.polhode.com/pccts.html
+
+The maintenance release is available from:
+
+ http://www.polhode.com/pccts133mr.zip
+
+There is a ready-to-run version for win32 for Microsoft Visual Studio
+at the same site. It is available from:
+
+ http://www.polhode.com/win32.zip
+
+New users should visit http://www.polhode.com/pccts.html in
+order to get the following document:
+
+ "Notes For New Users of PCCTS"
+
+This is a Postscript file of about 40 pages which is extremely
+useful for someone starting out. It is a based on 1.33mr21
+
+When you have a little more experience, be sure to review the
+following documents in the distribution kit:
+
+ CHANGES_FROM_133.txt
+ CHANGES_FROM_133_BEFORE_MR13.txt
+ KNOWN_PROBLEMS.txt
+
+-------------------------------------------------------------------------
+ INSTALLATION (Unix)
+-------------------------------------------------------------------------
+0. Download http://www.polhode.com/pccts133mr.zip
+
+1. Unzip the distribution kit to your preferred location.
+ If there are newline problems try using zip -a ...
+
+2. cd to the main pccts directory.
+
+3. make
+
+ This will create:
+
+ antlr
+ dlg
+ sorcerer
+ genmk
+
+4. Copy to /usr/local/bin or /usr/local/bin if you like. If you
+ don't wish to then add pccts/bin to your path.
+
+5. To get an up-to-date list of program options execute the
+ program with no command line options. To get up-to-date
+ documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt
+ at:
+
+ http://www.polhode.com/pccts.html
+
+6. You need not create a library. The makefile created by genmk
+ assumes that the files are not part of a library.
+
+ If you wish to create a library from elements of pccts/h:
+
+ If the first letter of the filename is lowercase (uppercase) it is
+ related to the code generated using the pccts C mode (C++ mode).
+ Some of the .c and .cpp files in the h directory are not meant to
+ be placed in a library and will not compile because they are meant
+ to be #include in pccts generated files which are grammar specific.
+
+ For C++ users place the following elements in the library:
+
+ AParser.cpp
+ ASTBase.cpp
+ ATokenBuffer.cpp
+ BufFileInput.cpp (optional)
+ DLexerBase.cpp
+ PCCTSAST.cpp
+ SList.cpp
+
+-------------------------------------------------------------------------
+ INSTALLATION (Win32)
+-------------------------------------------------------------------------
+
+I've tried to keep the win32 kit to the minimum necessary to get
+up and running. The complete kit contains additional information
+(some historical), source code, and DevStudio projects for
+rebuilding pccts from the source code.
+
+The kit is now distributed with both MSVC 5 and MSVC6 style projects.
+
+0. Download http://www.polhode.com/win32.zip.
+
+ You may also wish to download:
+
+ http://www.polhode.com/CHANGES_FROM_133.txt
+ http://www.polhode.com/CHANGES_FROM_133_BEFORE_MR13.txt
+ http://www.polhode.com/KNOWN_PROBLEMS.txt
+
+1. Unzip the distribution kit to your preferred location.
+
+ This will create:
+
+ a pccts directory tree
+ pccts/bin/*.exe
+ pccts/lib/*.lib
+ pccts/h/*
+ sorcerer/lib/*
+ sorcerer/h/*
+
+ an example directory tree
+ pccts\example\calcAST\*
+ pccts\example\simple\*
+
+2. Define the environment variable PCCTS to point to the main
+ pccts directory.
+
+3. Try building the simple project: pccts\example\simple\simple50.dsw
+ or simple60.dsw.
+
+4. Try building the complex project: pccts\example\calcAST\calcAST50.dsw
+ or calcAST60.dsw.
+
+-------------------------------------------------------------------------
+ INSTALLATION (DEC/VMS)
+-------------------------------------------------------------------------
+
+DEC/VMS support added by Piéronne Jean-François (jfp@altavista.net)
+
+0. Download http://www.polhode.com/pccts133mr.zip
+
+1. Unzip the distribution kit to your preferred location.
+
+2. set default to the main pccts directory.
+
+3. @makefile.vms
+
+ This will create in directory [.bin]:
+
+ antlr.exe
+ dlg.exe
+ sorcerer.exe
+ genmk.exe
+
+5. To get an up-to-date list of program options execute the
+ program with no command line options. To get up-to-date
+ documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt
+ at http://www.polhode.com/pccts.html.
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/RIGHTS b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/RIGHTS
new file mode 100644
index 00000000..5a3e2e76
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/RIGHTS
@@ -0,0 +1,26 @@
+
+SOFTWARE RIGHTS
+
+We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+Set (PCCTS) -- PCCTS is in the public domain. An individual or
+company may do whatever they wish with source code distributed with
+PCCTS or the code generated by PCCTS, including the incorporation of
+PCCTS, or its output, into commerical software.
+
+We encourage users to develop software with PCCTS. However, we do ask
+that credit is given to us for developing PCCTS. By "credit", we mean
+that if you incorporate our source code into one of your programs
+(commercial product, research project, or otherwise) that you
+acknowledge this fact somewhere in the documentation, research report,
+etc... If you like PCCTS and have developed a nice tool with the
+output, please mention that you developed it using PCCTS. In
+addition, we ask that this header remain intact in our source code.
+As long as these guidelines are kept, we expect to continue enhancing
+this system and expect to make other tools available as they are
+completed.
+
+ANTLR 1.33
+Terence Parr
+Parr Research Corporation
+with Purdue University and AHPCRC, University of Minnesota
+1989-1995
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrDDK.mak b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrDDK.mak
new file mode 100644
index 00000000..9c6cad59
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrDDK.mak
@@ -0,0 +1,233 @@
+# PCCTS directory
+
+# You will need to set the LIB variable similar to this.
+# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib"
+
+# PCCTS_HOME=<your PCCTS_HOME>
+PCCTS_HOME=$(WORKSPACE)\Tools\CCode\Source\Pccts
+ANTLR_SRC=$(PCCTS_HOME)\antlr
+PCCTS_H=$(PCCTS_HOME)\h
+
+
+# Support directories
+SET=$(PCCTS_HOME)\support\set
+
+
+# Compiler stuff
+CC = cl
+CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \
+ -D "ZZLEXBUFSIZE=65536" -D "LONGFILENAMES" /Zi /W3 -D__USE_PROTOS /wd4700
+
+ANTLR_OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+ fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+ misc.obj pred.obj egman.obj mrhoist.obj fcache.obj
+
+SUPPORT_OBJS = set.obj
+
+# Dependencies
+
+$(WORKSPACE)\Tools\bin\antlr.exe: $(ANTLR_OBJS) $(SUPPORT_OBJS)
+ $(CC) $(CFLAGS) -o antlr.exe bufferoverflowu.lib $(ANTLR_OBJS) $(SUPPORT_OBJS)
+ del *.obj
+ move antlr.exe $(WORKSPACE)\Tools\bin
+
+
+antlr.obj: $(ANTLR_SRC)\antlr.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\mode.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\antlr.c
+
+scan.obj: $(ANTLR_SRC)\scan.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgauto.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\mode.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\scan.c
+
+err.obj: $(ANTLR_SRC)\err.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(PCCTS_H)\err.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\err.c
+
+bits.obj: $(ANTLR_SRC)\bits.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\bits.c
+
+build.obj: $(ANTLR_SRC)\build.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\build.c
+
+fset2.obj: $(ANTLR_SRC)\fset2.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset2.c
+
+fset.obj: $(ANTLR_SRC)\fset.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset.c
+
+gen.obj: $(ANTLR_SRC)\gen.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\gen.c
+
+globals.obj: $(ANTLR_SRC)\globals.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\globals.c
+
+hash.obj: $(ANTLR_SRC)\hash.c \
+ $(PCCTS_H)\config.h \
+ $(ANTLR_SRC)\hash.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\hash.c
+
+lex.obj: $(ANTLR_SRC)\lex.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\lex.c
+
+main.obj: $(ANTLR_SRC)\main.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\mode.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\stdpccts.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\main.c
+
+misc.obj: $(ANTLR_SRC)\misc.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\misc.c
+
+pred.obj: $(ANTLR_SRC)\pred.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\pred.c
+
+egman.obj: $(ANTLR_SRC)\egman.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\egman.c
+
+mrhoist.obj: $(ANTLR_SRC)\mrhoist.c \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\mrhoist.c
+
+fcache.obj: $(ANTLR_SRC)\fcache.c \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fcache.c
+
+set.obj: $(SET)\set.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+
+ $(CC) -c $(CFLAGS) $(SET)\set.c
+
+clean:
+ del *.obj
+
+distclean:
+ del *.obj
+ del $(WORKSPACE)\Tools\bin\antlr.exe
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrMS.mak b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrMS.mak
new file mode 100644
index 00000000..c659ac28
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrMS.mak
@@ -0,0 +1,239 @@
+# PCCTS directory
+
+# You will need to set the LIB variable similar to this.
+# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib"
+
+# PCCTS_HOME=<your PCCTS_HOME>
+PCCTS_HOME=$(BASE_TOOLS_PATH)\Source\C\VfrCompile\Pccts
+ANTLR_SRC=$(PCCTS_HOME)\antlr
+PCCTS_H=$(PCCTS_HOME)\h
+
+
+# Support directories
+SET=$(PCCTS_HOME)\support\set
+
+
+# Compiler stuff
+CC = cl
+CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \
+ -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /Zi /W3 -D__USE_PROTOS /wd4700 \
+ /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE
+
+ANTLR_OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+ fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+ misc.obj pred.obj egman.obj mrhoist.obj fcache.obj
+
+SUPPORT_OBJS = set.obj
+
+# Dependencies
+
+$(EDK_TOOLS_PATH)\Bin\Win32\antlr.exe: $(ANTLR_OBJS) $(SUPPORT_OBJS)
+ $(CC) $(CFLAGS) -Feantlr.exe $(ANTLR_OBJS) $(SUPPORT_OBJS)
+ -@if not exist $(EDK_TOOLS_PATH)\Bin\Win32 mkdir $(EDK_TOOLS_PATH)\Bin\Win32
+ copy antlr.exe $(EDK_TOOLS_PATH)\Bin\Win32
+
+
+antlr.obj: $(ANTLR_SRC)\antlr.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\mode.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\antlr.c
+
+scan.obj: $(ANTLR_SRC)\scan.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgauto.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\mode.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\scan.c
+
+err.obj: $(ANTLR_SRC)\err.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(PCCTS_H)\err.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\err.c
+
+bits.obj: $(ANTLR_SRC)\bits.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\bits.c
+
+build.obj: $(ANTLR_SRC)\build.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\build.c
+
+fset2.obj: $(ANTLR_SRC)\fset2.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset2.c
+
+fset.obj: $(ANTLR_SRC)\fset.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset.c
+
+gen.obj: $(ANTLR_SRC)\gen.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\gen.c
+
+globals.obj: $(ANTLR_SRC)\globals.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\globals.c
+
+hash.obj: $(ANTLR_SRC)\hash.c \
+ $(PCCTS_H)\config.h \
+ $(ANTLR_SRC)\hash.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\hash.c
+
+lex.obj: $(ANTLR_SRC)\lex.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\lex.c
+
+main.obj: $(ANTLR_SRC)\main.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\mode.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\stdpccts.h \
+ $(ANTLR_SRC)\syn.h \
+ $(ANTLR_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\main.c
+
+misc.obj: $(ANTLR_SRC)\misc.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\misc.c
+
+pred.obj: $(ANTLR_SRC)\pred.c \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\pred.c
+
+egman.obj: $(ANTLR_SRC)\egman.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\egman.c
+
+mrhoist.obj: $(ANTLR_SRC)\mrhoist.c \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\mrhoist.c
+
+fcache.obj: $(ANTLR_SRC)\fcache.c \
+ $(ANTLR_SRC)\generic.h \
+ $(ANTLR_SRC)\hash.h \
+ $(ANTLR_SRC)\proto.h \
+ $(ANTLR_SRC)\syn.h \
+
+ $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fcache.c
+
+set.obj: $(SET)\set.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+
+ $(CC) -c $(CFLAGS) $(SET)\set.c
+
+clean:
+ -del *.obj
+ -del *.ilk
+ -del *.pdb
+
+cleanall:
+ -del *.obj
+ -del *.ilk
+ -del *.pdb
+ -del *.exe
+ -del $(EDK_TOOLS_PATH)\Bin\Win32\antlr.exe
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrPPC.mak b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrPPC.mak
new file mode 100644
index 00000000..437dbe4d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/AntlrPPC.mak
@@ -0,0 +1,101 @@
+# Target: antlrPPC
+# Sources: ::support:set:set.c
+# antlr.c
+# bits.c
+# build.c
+# egman.c
+# err.c
+# fcache.c
+# fset2.c
+# fset.c
+# gen.c
+# globals.c
+# hash.c
+# lex.c
+# main.c
+# misc.c
+# mrhoist.c
+# pred.c
+# scan.c
+# Created: Sunday, May 17, 1998 10:24:53 PM
+# Author: Kenji Tanaka
+MAKEFILE = antlrPPC.make
+¥MondoBuild¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified
+Includes = ¶
+ -i "::h:" ¶
+ -i "::support:set:"
+Sym¥PPC =
+ObjDir¥PPC = :Obj:
+PPCCOptions = {Includes} {Sym¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN
+Objects¥PPC = ¶
+ "{ObjDir¥PPC}set.c.x" ¶
+ "{ObjDir¥PPC}antlr.c.x" ¶
+ "{ObjDir¥PPC}bits.c.x" ¶
+ "{ObjDir¥PPC}build.c.x" ¶
+ "{ObjDir¥PPC}egman.c.x" ¶
+ "{ObjDir¥PPC}err.c.x" ¶
+ "{ObjDir¥PPC}fcache.c.x" ¶
+ "{ObjDir¥PPC}fset2.c.x" ¶
+ "{ObjDir¥PPC}fset.c.x" ¶
+ "{ObjDir¥PPC}gen.c.x" ¶
+ "{ObjDir¥PPC}globals.c.x" ¶
+ "{ObjDir¥PPC}hash.c.x" ¶
+ "{ObjDir¥PPC}lex.c.x" ¶
+ "{ObjDir¥PPC}main.c.x" ¶
+ "{ObjDir¥PPC}misc.c.x" ¶
+ "{ObjDir¥PPC}mrhoist.c.x" ¶
+ "{ObjDir¥PPC}pred.c.x" ¶
+ "{ObjDir¥PPC}scan.c.x"
+antlrPPC ÄÄ {¥MondoBuild¥} {Objects¥PPC}
+ PPCLink ¶
+ -o {Targ} {Sym¥PPC} ¶
+ {Objects¥PPC} ¶
+ -t 'MPST' ¶
+ -c 'MPS ' ¶
+ "{SharedLibraries}InterfaceLib" ¶
+ "{SharedLibraries}StdCLib" ¶
+ #"{SharedLibraries}MathLib" ¶
+ "{PPCLibraries}StdCRuntime.o" ¶
+ "{PPCLibraries}PPCCRuntime.o" ¶
+ "{PPCLibraries}PPCToolLibs.o"
+"{ObjDir¥PPC}set.c.x" Ä {¥MondoBuild¥} "::support:set:set.c"
+ {PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}antlr.c.x" Ä {¥MondoBuild¥} antlr.c
+ {PPCC} antlr.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}bits.c.x" Ä {¥MondoBuild¥} bits.c
+ {PPCC} bits.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}build.c.x" Ä {¥MondoBuild¥} build.c
+ {PPCC} build.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}egman.c.x" Ä {¥MondoBuild¥} egman.c
+ {PPCC} egman.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}err.c.x" Ä {¥MondoBuild¥} err.c
+ {PPCC} err.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}fcache.c.x" Ä {¥MondoBuild¥} fcache.c
+ {PPCC} fcache.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}fset2.c.x" Ä {¥MondoBuild¥} fset2.c
+ {PPCC} fset2.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}fset.c.x" Ä {¥MondoBuild¥} fset.c
+ {PPCC} fset.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}gen.c.x" Ä {¥MondoBuild¥} gen.c
+ {PPCC} gen.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}globals.c.x" Ä {¥MondoBuild¥} globals.c
+ {PPCC} globals.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}hash.c.x" Ä {¥MondoBuild¥} hash.c
+ {PPCC} hash.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}lex.c.x" Ä {¥MondoBuild¥} lex.c
+ {PPCC} lex.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}main.c.x" Ä {¥MondoBuild¥} main.c
+ {PPCC} main.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}misc.c.x" Ä {¥MondoBuild¥} misc.c
+ {PPCC} misc.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}mrhoist.c.x" Ä {¥MondoBuild¥} mrhoist.c
+ {PPCC} mrhoist.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}pred.c.x" Ä {¥MondoBuild¥} pred.c
+ {PPCC} pred.c -o {Targ} {PPCCOptions}
+"{ObjDir¥PPC}scan.c.x" Ä {¥MondoBuild¥} scan.c
+ {PPCC} scan.c -o {Targ} {PPCCOptions}
+
+antlrPPC ÄÄ antlr.r
+ Rez antlr.r -o antlrPPC -a
+Install Ä antlrPPC
+ Duplicate -y antlrPPC "{MPW}"Tools:antlr
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/README b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/README
new file mode 100644
index 00000000..d6364eca
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/README
@@ -0,0 +1,19 @@
+ ANTLR 1.33
+
+This directory contains the files necessary to build ANTLR.
+
+If you do a "make scrub", ANTLR will have to run on antlr.g and DLG
+will have to run on parser.dlg. Either
+
+(1) ANTLR uses the previous antlr in that directory to rebuild itself
+(2) Needs to find antlr on the search path
+
+You will find that running "antlr -gh antlr.g" will result in about
+10 ambiguity warnings. These are normal. Don't worry.
+
+If you do a "make clean" right after installation, ANTLR and DLG should
+not need to run; only the C files will compile.
+
+Don't forget to go into the makefile to uncomment the appropriate
+definitions for your OS/architecture/compiler or see the appropriate
+NOTES.?? file.
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.1 b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.1
new file mode 100644
index 00000000..6ace1b2a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.1
@@ -0,0 +1,209 @@
+.TH ANTLR 1 "September 1995" "ANTLR" "PCCTS Manual Pages"
+.SH NAME
+antlr \- ANother Tool for Language Recognition
+.SH SYNTAX
+.LP
+\fBantlr\fR [\fIoptions\fR] \fIgrammar_files\fR
+.SH DESCRIPTION
+.PP
+\fIAntlr\fP converts an extended form of context-free grammar into a
+set of C functions which directly implement an efficient form of
+deterministic recursive-descent LL(k) parser. Context-free grammars
+may be augmented with predicates to allow semantics to influence
+parsing; this allows a form of context-sensitive parsing. Selective
+backtracking is also available to handle non-LL(k) and even
+non-LALR(k) constructs. \fIAntlr\fP also produces a definition of a
+lexer which can be automatically converted into C code for a DFA-based
+lexer by \fIdlg\fR. Hence, \fIantlr\fR serves a function much like
+that of \fIyacc\fR, however, it is notably more flexible and is more
+integrated with a lexer generator (\fIantlr\fR directly generates
+\fIdlg\fR code, whereas \fIyacc\fR and \fIlex\fR are given independent
+descriptions). Unlike \fIyacc\fR which accepts LALR(1) grammars,
+\fIantlr\fR accepts LL(k) grammars in an extended BNF notation \(em
+which eliminates the need for precedence rules.
+.PP
+Like \fIyacc\fR grammars, \fIantlr\fR grammars can use
+automatically-maintained symbol attribute values referenced as dollar
+variables. Further, because \fIantlr\fR generates top-down parsers,
+arbitrary values may be inherited from parent rules (passed like
+function parameters). \fIAntlr\fP also has a mechanism for creating
+and manipulating abstract-syntax-trees.
+.PP
+There are various other niceties in \fIantlr\fR, including the ability to
+spread one grammar over multiple files or even multiple grammars in a single
+file, the ability to generate a version of the grammar with actions stripped
+out (for documentation purposes), and lots more.
+.SH OPTIONS
+.IP "\fB-ck \fIn\fR"
+Use up to \fIn\fR symbols of lookahead when using compressed (linear
+approximation) lookahead. This type of lookahead is very cheap to
+compute and is attempted before full LL(k) lookahead, which is of
+exponential complexity in the worst case. In general, the compressed
+lookahead can be much deeper (e.g, \f(CW-ck 10\fP) than the full
+lookahead (which usually must be less than 4).
+.IP \fB-CC\fP
+Generate C++ output from both ANTLR and DLG.
+.IP \fB-cr\fP
+Generate a cross-reference for all rules. For each rule, print a list
+of all other rules that reference it.
+.IP \fB-e1\fP
+Ambiguities/errors shown in low detail (default).
+.IP \fB-e2\fP
+Ambiguities/errors shown in more detail.
+.IP \fB-e3\fP
+Ambiguities/errors shown in excruciating detail.
+.IP "\fB-fe\fP file"
+Rename \fBerr.c\fP to file.
+.IP "\fB-fh\fP file"
+Rename \fBstdpccts.h\fP header (turns on \fB-gh\fP) to file.
+.IP "\fB-fl\fP file"
+Rename lexical output, \fBparser.dlg\fP, to file.
+.IP "\fB-fm\fP file"
+Rename file with lexical mode definitions, \fBmode.h\fP, to file.
+.IP "\fB-fr\fP file"
+Rename file which remaps globally visible symbols, \fBremap.h\fP, to file.
+.IP "\fB-ft\fP file"
+Rename \fBtokens.h\fP to file.
+.IP \fB-ga\fP
+Generate ANSI-compatible code (default case). This has not been
+rigorously tested to be ANSI XJ11 C compliant, but it is close. The
+normal output of \fIantlr\fP is currently compilable under both K&R,
+ANSI C, and C++\(emthis option does nothing because \fIantlr\fP
+generates a bunch of #ifdef's to do the right thing depending on the
+language.
+.IP \fB-gc\fP
+Indicates that \fIantlr\fP should generate no C code, i.e., only
+perform analysis on the grammar.
+.IP \fB-gd\fP
+C code is inserted in each of the \fIantlr\fR generated parsing functions to
+provide for user-defined handling of a detailed parse trace. The inserted
+code consists of calls to the user-supplied macros or functions called
+\fBzzTRACEIN\fR and \fBzzTRACEOUT\fP. The only argument is a
+\fIchar *\fR pointing to a C-style string which is the grammar rule
+recognized by the current parsing function. If no definition is given
+for the trace functions, upon rule entry and exit, a message will be
+printed indicating that a particular rule as been entered or exited.
+.IP \fB-ge\fP
+Generate an error class for each non-terminal.
+.IP \fB-gh\fP
+Generate \fBstdpccts.h\fP for non-ANTLR-generated files to include.
+This file contains all defines needed to describe the type of parser
+generated by \fIantlr\fP (e.g. how much lookahead is used and whether
+or not trees are constructed) and contains the \fBheader\fP action
+specified by the user.
+.IP \fB-gk\fP
+Generate parsers that delay lookahead fetches until needed. Without
+this option, \fIantlr\fP generates parsers which always have \fIk\fP
+tokens of lookahead available.
+.IP \fB-gl\fP
+Generate line info about grammar actions in C parser of the form
+\fB#\ \fIline\fP\ "\fIfile\fP"\fR which makes error messages from
+the C/C++ compiler make more sense as they will \*Qpoint\*U into the
+grammar file not the resulting C file. Debugging is easier as well,
+because you will step through the grammar not C file.
+.IP \fB-gs\fR
+Do not generate sets for token expression lists; instead generate a
+\fB||\fP-separated sequence of \fBLA(1)==\fItoken_number\fR. The
+default is to generate sets.
+.IP \fB-gt\fP
+Generate code for Abstract-Syntax Trees.
+.IP \fB-gx\fP
+Do not create the lexical analyzer files (dlg-related). This option
+should be given when the user wishes to provide a customized lexical
+analyzer. It may also be used in \fImake\fR scripts to cause only the
+parser to be rebuilt when a change not affecting the lexical structure
+is made to the input grammars.
+.IP "\fB-k \fIn\fR"
+Set k of LL(k) to \fIn\fR; i.e. set tokens of look-ahead (default==1).
+.IP "\fB-o\fP dir
+Directory where output files should go (default="."). This is very
+nice for keeping the source directory clear of ANTLR and DLG spawn.
+.IP \fB-p\fP
+The complete grammar, collected from all input grammar files and
+stripped of all comments and embedded actions, is listed to
+\fBstdout\fP. This is intended to aid in viewing the entire grammar
+as a whole and to eliminate the need to keep actions concisely stated
+so that the grammar is easier to read. Hence, it is preferable to
+embed even complex actions directly in the grammar, rather than to
+call them as subroutines, since the subroutine call overhead will be
+saved.
+.IP \fB-pa\fP
+This option is the same as \fB-p\fP except that the output is
+annotated with the first sets determined from grammar analysis.
+.IP "\fB-prc on\fR
+Turn on the computation and hoisting of predicate context.
+.IP "\fB-prc off\fR
+Turn off the computation and hoisting of predicate context. This
+option makes 1.10 behave like the 1.06 release with option \fB-pr\fR
+on. Context computation is off by default.
+.IP "\fB-rl \fIn\fR
+Limit the maximum number of tree nodes used by grammar analysis to
+\fIn\fP. Occasionally, \fIantlr\fP is unable to analyze a grammar
+submitted by the user. This rare situation can only occur when the
+grammar is large and the amount of lookahead is greater than one. A
+nonlinear analysis algorithm is used by PCCTS to handle the general
+case of LL(k) parsing. The average complexity of analysis, however, is
+near linear due to some fancy footwork in the implementation which
+reduces the number of calls to the full LL(k) algorithm. An error
+message will be displayed, if this limit is reached, which indicates
+the grammar construct being analyzed when \fIantlr\fP hit a
+non-linearity. Use this option if \fIantlr\fP seems to go out to
+lunch and your disk start thrashing; try \fIn\fP=10000 to start. Once
+the offending construct has been identified, try to remove the
+ambiguity that \fIantlr\fP was trying to overcome with large lookahead
+analysis. The introduction of (...)? backtracking blocks eliminates
+some of these problems\ \(em \fIantlr\fP does not analyze alternatives
+that begin with (...)? (it simply backtracks, if necessary, at run
+time).
+.IP \fB-w1\fR
+Set low warning level. Do not warn if semantic predicates and/or
+(...)? blocks are assumed to cover ambiguous alternatives.
+.IP \fB-w2\fR
+Ambiguous parsing decisions yield warnings even if semantic predicates
+or (...)? blocks are used. Warn if predicate context computed and
+semantic predicates incompletely disambiguate alternative productions.
+.IP \fB-\fR
+Read grammar from standard input and generate \fBstdin.c\fP as the
+parser file.
+.SH "SPECIAL CONSIDERATIONS"
+.PP
+\fIAntlr\fP works... we think. There is no implicit guarantee of
+anything. We reserve no \fBlegal\fP rights to the software known as
+the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the
+public domain. An individual or company may do whatever they wish
+with source code distributed with PCCTS or the code generated by
+PCCTS, including the incorporation of PCCTS, or its output, into
+commercial software. We encourage users to develop software with
+PCCTS. However, we do ask that credit is given to us for developing
+PCCTS. By "credit", we mean that if you incorporate our source code
+into one of your programs (commercial product, research project, or
+otherwise) that you acknowledge this fact somewhere in the
+documentation, research report, etc... If you like PCCTS and have
+developed a nice tool with the output, please mention that you
+developed it using PCCTS. As long as these guidelines are followed,
+we expect to continue enhancing this system and expect to make other
+tools available as they are completed.
+.SH FILES
+.IP *.c
+output C parser.
+.IP *.cpp
+output C++ parser when C++ mode is used.
+.IP \fBparser.dlg\fP
+output \fIdlg\fR lexical analyzer.
+.IP \fBerr.c\fP
+token string array, error sets and error support routines. Not used in
+C++ mode.
+.IP \fBremap.h\fP
+file that redefines all globally visible parser symbols. The use of
+the #parser directive creates this file. Not used in
+C++ mode.
+.IP \fBstdpccts.h\fP
+list of definitions needed by C files, not generated by PCCTS, that
+reference PCCTS objects. This is not generated by default. Not used in
+C++ mode.
+.IP \fBtokens.h\fP
+output \fI#defines\fR for tokens used and function prototypes for
+functions generated for rules.
+.SH "SEE ALSO"
+.LP
+dlg(1), pccts(1)
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.c
new file mode 100644
index 00000000..29a593ca
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.c
@@ -0,0 +1,3574 @@
+/*
+ * A n t l r T r a n s l a t i o n H e a d e r
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ *
+ * ..\bin\antlr -gh antlr.g
+ *
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include "pcctscfg.h"
+#include "set.h"
+#include <ctype.h>
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#define zzcr_attr(attr,tok,t) /*vbox: */ memset((attr), 0, sizeof(*attr))
+#define zzSET_SIZE 20
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "mode.h"
+
+/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */
+
+#ifndef PCCTS_PURIFY
+#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s));
+#endif
+
+ANTLR_INFO
+
+
+/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */
+#if defined(__TURBOC__)
+#pragma warn -aus /* unused assignment of 'xxx' */
+#endif
+
+#ifdef VBOX
+# ifdef _MSC_VER
+# pragma warning(disable : 4068) /* Unguarded '#pragma clang' below */
+# endif
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wunknown-pragmas"
+# endif
+#endif
+
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+
+#ifdef __USE_PROTOS
+static void chkToken(char *, char *, char *, int);
+#else
+static void chkToken();
+#endif
+
+#ifdef __USE_PROTOS
+static int isDLGmaxToken(char *Token); /* MR3 */
+#else
+static int isDLGmaxToken(); /* MR3 */
+#endif
+
+static int class_nest_level = 0;
+
+/* MR20 G. Hobbelt extern definitions moved to antlr.h */
+
+
+
+void
+#ifdef __USE_PROTOS
+grammar(void)
+#else
+grammar()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ Graph g;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ for (;;) {
+ if ( !((setwd1[LA(1)]&0x1))) break;
+ if ( (LA(1)==94) ) {
+ zzmatch(94); zzCONSUME;
+ zzmatch(Action);
+
+ if ( HdrAction==NULL ) {
+ HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(HdrAction!=NULL, "rule grammar: cannot allocate header action");
+ strcpy(HdrAction, LATEXT(1));
+ }
+ else warn("additional #header statement ignored");
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==95) ) {
+ zzmatch(95); zzCONSUME;
+ zzmatch(Action);
+
+ if ( FirstAction==NULL ) {
+ FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(FirstAction!=NULL, "rule grammar: cannot allocate #first action");
+ strcpy(FirstAction, LATEXT(1));
+ } else {
+ warn("additional #first statement ignored");
+ };
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==96) ) {
+ zzmatch(96); zzCONSUME;
+ zzmatch(QuotedTerm);
+
+ if ( GenCC ) {
+ warn("#parser meta-op incompatible with -CC; ignored");
+ }
+ else {
+ if ( strcmp(ParserName,"zzparser")==0 ) {
+ ParserName=StripQuotes(mystrdup(LATEXT(1)));
+ if ( RulePrefix[0]!='\0' )
+ {
+ warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored");
+ RulePrefix[0]='\0';
+ }
+ }
+ else warn("additional #parser statement ignored");
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==97) ) {
+ zzmatch(97); zzCONSUME;
+ zzmatch(QuotedTerm);
+ {
+ char *fname;
+ zzantlr_state st; FILE *f; struct zzdlg_state dst;
+ UserTokenDefsFile = mystrdup(LATEXT(1));
+ zzsave_antlr_state(&st);
+ zzsave_dlg_state(&dst);
+ fname = mystrdup(LATEXT(1));
+ f = fopen(StripQuotes(fname), "r");
+ if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));}
+ else {
+ ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE);
+ UserDefdTokens = 1;
+ }
+ zzrestore_antlr_state(&st);
+ zzrestore_dlg_state(&dst);
+ }
+ zzCONSUME;
+
+ }
+ else break; /* MR6 code for exiting loop "for sure" */
+ }
+ }
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ for (;;) {
+ if ( !((setwd1[LA(1)]&0x2))) break;
+ if ( (LA(1)==Action) ) {
+ zzmatch(Action);
+ {
+ UserAction *ua = newUserAction(LATEXT(1));
+ ua->file = action_file; ua->line = action_line;
+ if ( class_nest_level>0 ) list_add(&class_before_actions, ua);
+ else list_add(&BeforeActions, ua);
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==108) ) {
+ laction();
+ }
+ else {
+ if ( (LA(1)==109) ) {
+ lmember();
+ }
+ else {
+ if ( (LA(1)==110) ) {
+ lprefix();
+ }
+ else {
+ if ( (LA(1)==116) ) {
+ aLexclass();
+ }
+ else {
+ if ( (LA(1)==120) ) {
+ token();
+ }
+ else {
+ if ( (LA(1)==117) ) {
+ error();
+ }
+ else {
+ if ( (LA(1)==118) ) {
+ tclass();
+ }
+ else {
+ if ( (LA(1)==111) ) {
+ aPred();
+ }
+ else {
+ if ( (LA(1)==133) ) {
+ default_exception_handler();
+ }
+ else {
+ if ( (LA(1)==99) ) {
+ class_def();
+ }
+ else {
+ if ( (LA(1)==98) ) {
+ zzmatch(98);
+
+ if ( class_nest_level==0 )
+ warn("missing class definition for trailing '}'");
+ class_nest_level--;
+ zzCONSUME;
+
+ }
+ else break; /* MR6 code for exiting loop "for sure" */
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ rule();
+ g=zzaArg(zztasp1,3); SynDiag = (Junction *) zzaArg(zztasp1,3 ).left;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ for (;;) {
+ if ( !((setwd1[LA(1)]&0x4))) break;
+ if ( (LA(1)==NonTerminal) ) {
+ rule();
+ if ( zzaArg(zztasp2,1 ).left!=NULL ) {
+ g.right = NULL;
+
+/* MR21a */ /* Avoid use of a malformed graph when CannotContinue */
+ /* MR21a */ /* is already set */
+ /* MR21a */
+ /* MR21a */ if (! (CannotContinue && g.left == NULL)) {
+ /* MR21a */ g = Or(g, zzaArg(zztasp2,1));
+ /* MR21a */ }
+ /* MR21a */ }
+ }
+ else {
+ if ( (LA(1)==116) ) {
+ aLexclass();
+ }
+ else {
+ if ( (LA(1)==120) ) {
+ token();
+ }
+ else {
+ if ( (LA(1)==117) ) {
+ error();
+ }
+ else {
+ if ( (LA(1)==118) ) {
+ tclass();
+ }
+ else {
+ if ( (LA(1)==111) ) {
+ aPred();
+ }
+ else {
+ if ( (LA(1)==99) ) {
+ class_def();
+ }
+ else {
+ if ( (LA(1)==98) ) {
+ zzmatch(98);
+
+ if ( class_nest_level==0 )
+ warn("missing class definition for trailing '}'");
+ class_nest_level--;
+ zzCONSUME;
+
+ }
+ else break; /* MR6 code for exiting loop "for sure" */
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ for (;;) {
+ if ( !((setwd1[LA(1)]&0x8))) break;
+ if ( (LA(1)==Action) ) {
+ zzmatch(Action);
+ {
+ UserAction *ua = newUserAction(LATEXT(1));
+ ua->file = action_file; ua->line = action_line;
+ if ( class_nest_level>0 ) list_add(&class_after_actions, ua);
+ else list_add(&AfterActions, ua);
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==108) ) {
+ laction();
+ }
+ else {
+ if ( (LA(1)==109) ) {
+ lmember();
+ }
+ else {
+ if ( (LA(1)==110) ) {
+ lprefix();
+ }
+ else {
+ if ( (LA(1)==117) ) {
+ error();
+ }
+ else {
+ if ( (LA(1)==118) ) {
+ tclass();
+ }
+ else {
+ if ( (LA(1)==99) ) {
+ class_def();
+ }
+ else {
+ if ( (LA(1)==111) ) {
+ aPred();
+ }
+ else {
+ if ( (LA(1)==98) ) {
+ zzmatch(98);
+
+ if ( class_nest_level==0 )
+ warn("missing class definition for trailing '}'");
+ class_nest_level--;
+ zzCONSUME;
+
+ }
+ else break; /* MR6 code for exiting loop "for sure" */
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(Eof); zzCONSUME;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x10);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+class_def(void)
+#else
+class_def()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ int go=1; char name[MaxRuleName+1];
+ zzmatch(99); zzCONSUME;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==NonTerminal) ) {
+ zzmatch(NonTerminal);
+ if(go) strncpy(name,LATEXT(1),MaxRuleName);
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ if(go) strncpy(name,LATEXT(1),MaxRuleName);
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0
+ && GenCC ) {
+ err("only one grammar class allowed in this release");
+ go = 0;
+ }
+ else strcpy(CurrentClassName, name);
+ if ( !GenCC ) { err("class meta-op used without C++ option"); }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (setwd1[LA(1)]&0x20) ) {
+ zzsetmatch(zzerr2, zzerr3);
+ if (ClassDeclStuff == NULL) {
+ /* MR10 */ ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char));
+ /* MR10 */ };
+ /* MR10 */ strncat(ClassDeclStuff," ",MaxClassDeclStuff);
+ /* MR10 */ strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff);
+ /* MR22 */ do {
+ /* MR22 */ if (0 == strcmp(LATEXT(1),"public")) break;
+ /* MR22 */ if (0 == strcmp(LATEXT(1),"private")) break;
+ /* MR22 */ if (0 == strcmp(LATEXT(1),"protected")) break;
+ /* MR22 */ if (0 == strcmp(LATEXT(1),"virtual")) break;
+ /* MR22 */ if (0 == strcmp(LATEXT(1),",")) break;
+ /* MR22 */ if (0 == strcmp(LATEXT(1),":")) break;
+ /* MR22 */ if (BaseClassName != NULL) break;
+ /* MR22 */ BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char));
+ /* MR22 */ require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name");
+ /* MR22 */ strcpy(BaseClassName,LATEXT(1));
+ /* MR22 */ } while (0);
+ /* MR10 */
+ zzCONSUME;
+
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(102);
+
+ no_classes_found = 0;
+ if ( class_nest_level>=1 ) {warn("cannot have nested classes");}
+ else class_nest_level++;
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x40);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+rule(void)
+#else
+rule()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+
+
+ ExceptionGroup *eg;
+ RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e;
+ set toksrefd, rulesrefd;
+ char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL;
+ CurExGroups = NULL;
+ CurElementLabels = NULL;
+ CurAstLabelsInActions = NULL; /* MR27 */
+ /* We want a new element label hash table for each rule */
+ if ( Elabel!=NULL ) killHashTable(Elabel);
+ Elabel = newHashTable();
+ attribsRefdFromAction = empty;
+ zzmatch(NonTerminal);
+ q=NULL;
+ if ( hash_get(Rname, LATEXT(1))!=NULL ) {
+ err(eMsg1("duplicate rule definition: '%s'",LATEXT(1)));
+ CannotContinue=TRUE;
+ }
+ else
+ {
+ q = (RuleEntry *)hash_add(Rname,
+ LATEXT(1),
+ (Entry *)newRuleEntry(LATEXT(1)));
+ CurRule = q->str;
+ }
+ CurRuleNode = q;
+ f = CurFile; l = zzline;
+ NumRules++;
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==103) ) {
+ zzmatch(103);
+ if ( q!=NULL ) q->noAST = TRUE;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd1[LA(1)]&0x80) ) {
+ }
+ else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ ;
+ if ( (setwd2[LA(1)]&0x1) ) {
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==104) ) {
+ zzmatch(104); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==PassAction) ) {
+ }
+ else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ zzmatch(PassAction);
+ pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(pdecl!=NULL, "rule rule: cannot allocate param decl");
+ strcpy(pdecl, LATEXT(1));
+ CurParmDef = pdecl;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd2[LA(1)]&0x2) ) {
+ }
+ else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==105) ) {
+ zzmatch(105); zzCONSUME;
+ zzmatch(PassAction);
+ ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(ret!=NULL, "rule rule: cannot allocate ret type");
+ strcpy(ret, LATEXT(1));
+ CurRetDef = ret;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd2[LA(1)]&0x4) ) {
+ }
+ else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==106) ) {
+ }
+ else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ if ( GenEClasseForRules && q!=NULL ) {
+ e = newECnode;
+ require(e!=NULL, "cannot allocate error class node");
+ if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);}
+ else a = q->egroup;
+ if ( Tnum( a ) == 0 )
+ {
+ e->tok = addTname( a );
+ list_add(&eclasses, (char *)e);
+ if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);
+ /* refers to itself */
+ list_add(&(e->elist), mystrdup(q->str));
+ }
+ else {
+ warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a));
+ if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);
+ free((char *)e);
+ }
+ }
+ BlkLevel++;
+ if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");
+ /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;
+ /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ zzmatch(106);
+ inAlt=1;
+ zzCONSUME;
+
+ block( &toksrefd, &rulesrefd );
+ r = makeBlk(zzaArg(zztasp1,7),0, NULL /* pFirstSetSymbol */ );
+ CurRuleBlk = (Junction *)r.left;
+ CurRuleBlk->blockid = CurBlockID;
+ CurRuleBlk->jtype = RuleBlk;
+ if ( q!=NULL ) CurRuleBlk->rname = q->str;
+ CurRuleBlk->file = f;
+ CurRuleBlk->line = l;
+ CurRuleBlk->pdecl = pdecl;
+ CurRuleBlk->ret = ret;
+ CurRuleBlk->lock = makelocks();
+ CurRuleBlk->pred_lock = makelocks();
+ CurRuleBlk->tokrefs = toksrefd;
+ CurRuleBlk->rulerefs = rulesrefd;
+ p = newJunction(); /* add EndRule Node */
+ ((Junction *)r.right)->p1 = (Node *)p;
+ r.right = (Node *) p;
+ p->jtype = EndRule;
+ p->lock = makelocks();
+ p->pred_lock = makelocks();
+ CurRuleBlk->end = p;
+ if ( q!=NULL ) q->rulenum = NumRules;
+ zzaArg(zztasp1,7) = r;
+
+ /* MR23 */ CurBlockID_array[BlkLevel] = (-1);
+ /* MR23 */ CurAltNum_array[BlkLevel] = (-1);
+ --BlkLevel;
+ altFixup();leFixup();egFixup();
+ zzmatch(107);
+ inAlt=0;
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==Action) ) {
+ zzmatch(Action);
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule rule: cannot allocate error action");
+ strcpy(a, LATEXT(1));
+ CurRuleBlk->erraction = a;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd2[LA(1)]&0x8) ) {
+ }
+ else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==133) ) {
+ eg = exception_group();
+
+ if ( eg!=NULL ) {
+ list_add(&CurExGroups, (void *)eg);
+ if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1;
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ if ( q==NULL ) zzaArg(zztasp1,0 ).left = NULL; else zzaArg(zztasp1,0) = zzaArg(zztasp1,7);
+ CurRuleBlk->exceptions = CurExGroups;
+ CurRuleBlk->el_labels = CurElementLabels;
+ CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions;
+ CurRuleNode = NULL;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x10);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+laction(void)
+#else
+laction()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ char *a;
+ zzmatch(108); zzCONSUME;
+ zzmatch(Action);
+
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule laction: cannot allocate action");
+ strcpy(a, LATEXT(1));
+ list_add(&LexActions, a);
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x20);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+lmember(void)
+#else
+lmember()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ char *a;
+ zzmatch(109); zzCONSUME;
+ zzmatch(Action);
+
+ /* MR1 */ if (! GenCC) {
+ /* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header");
+ /* MR1 */ } else {
+ /* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ /* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action");
+ /* MR1 */ strcpy(a, LATEXT(1));
+ /* MR1 */ list_add(&LexMemberActions, a);
+ /* MR1 */ };
+ /* MR1 */
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x40);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+lprefix(void)
+#else
+lprefix()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ char *a;
+ zzmatch(110); zzCONSUME;
+ zzmatch(Action);
+
+ /* MR1 */ if (! GenCC) {
+ /* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header");
+ /* MR1 */ } else {
+ /* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ /* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action");
+ /* MR1 */ strcpy(a, LATEXT(1));
+ /* MR1 */ list_add(&LexPrefixActions, a);
+ /* MR1 */ };
+ /* MR1 */
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x80);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+aPred(void)
+#else
+aPred()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ PredEntry *predEntry=NULL;
+ char *name=NULL;
+ Predicate *predExpr=NULL;
+ char *predLiteral=NULL;
+ int save_file;
+ int save_line;
+ int predExprPresent=0;
+ zzmatch(111);
+
+ MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */
+ zzCONSUME;
+
+ zzmatch(TokenTerm);
+ name=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+
+ /* don't free - referenced in predicates */
+
+ CurPredName=(char *)calloc(1,strlen(name) + 10);
+ strcat(CurPredName,"#pred ");
+ strcat(CurPredName,name);
+
+ predEntry=(PredEntry *) hash_get(Pname,name);
+ if (predEntry != NULL) {
+ warnFL(eMsg1("#pred %s previously defined - ignored",name),
+ FileStr[action_file],action_line);
+ name=NULL;
+};
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==Pred) ) {
+ zzmatch(Pred);
+ predLiteral=mystrdup(LATEXT(1));
+ save_line=action_line;
+ save_file=action_file;
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (setwd3[LA(1)]&0x1) ) {
+ predExpr = predOrExpr();
+
+ predExprPresent=1;
+ }
+ else {
+ if ( (setwd3[LA(1)]&0x2) ) {
+ }
+ else {zzFAIL(1,zzerr10,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ if (predLiteral != NULL && name != NULL) {
+
+ /*
+ * predExpr may be NULL due to syntax errors
+ * or simply omitted by the user
+ */
+
+ predEntry=newPredEntry(name);
+ predEntry->file=save_file;
+ predEntry->line=save_line;
+ predExpr=MR_predFlatten(predExpr);
+ predEntry->predLiteral=predLiteral;
+ if (! predExprPresent || predExpr == NULL) {
+ predExpr=new_pred();
+ predExpr->expr=predLiteral;
+ predExpr->source=newActionNode();
+ predExpr->source->action=predExpr->expr;
+ predExpr->source->rname=CurPredName;
+ predExpr->source->line=action_line;
+ predExpr->source->file=action_file;
+ predExpr->source->is_predicate=1;
+ predExpr->k=predicateLookaheadDepth(predExpr->source);
+ };
+ predEntry->pred=predExpr;
+ hash_add(Pname,name,(Entry *)predEntry);
+ predExpr=NULL;
+ };
+ predicate_free(predExpr);
+ }
+ else {
+ if ( (setwd3[LA(1)]&0x4) ) {
+ save_line=zzline; save_file=CurFile;
+ predExpr = predOrExpr();
+
+ if (predExpr != NULL && name != NULL) {
+ predEntry=newPredEntry(name);
+ predEntry->file=CurFile;
+ predEntry->line=zzline;
+ predExpr=MR_predFlatten(predExpr);
+ predEntry->pred=predExpr;
+ hash_add(Pname,name,(Entry *)predEntry);
+ predExpr=NULL;
+ };
+ predicate_free(predExpr);
+ }
+ else {zzFAIL(1,zzerr11,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==107) ) {
+ zzmatch(107); zzCONSUME;
+ }
+ else {
+ if ( (setwd3[LA(1)]&0x8) ) {
+ }
+ else {zzFAIL(1,zzerr12,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ predicate_free(predExpr);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x10);
+ }
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+predOrExpr(void)
+#else
+predOrExpr()
+#endif
+{
+ Predicate * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(Predicate * ))
+ zzMake0;
+ {
+ Predicate *ORnode;
+ Predicate *predExpr;
+ Predicate **tail=NULL;
+ predExpr = predAndExpr();
+
+
+ ORnode=new_pred();
+ ORnode->expr=PRED_OR_LIST;
+ if (predExpr != NULL) {
+ ORnode->down=predExpr;
+ tail=&predExpr->right;
+ };
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==112) ) {
+ zzmatch(112); zzCONSUME;
+ predExpr = predAndExpr();
+
+
+ if (predExpr != NULL) {
+ *tail=predExpr;
+ tail=&predExpr->right;
+ };
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ _retv=ORnode;
+ ORnode=NULL;
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+ predicate_free(ORnode);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x20);
+ return _retv;
+ }
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+predAndExpr(void)
+#else
+predAndExpr()
+#endif
+{
+ Predicate * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(Predicate * ))
+ zzMake0;
+ {
+ Predicate *ANDnode;
+ Predicate *predExpr;
+ Predicate **tail=NULL;
+ predExpr = predPrimary();
+
+
+ ANDnode=new_pred();
+ ANDnode->expr=PRED_AND_LIST;
+ if (predExpr != NULL) {
+ ANDnode->down=predExpr;
+ tail=&predExpr->right;
+ };
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==113) ) {
+ zzmatch(113); zzCONSUME;
+ predExpr = predPrimary();
+
+
+ if (predExpr != NULL) {
+ *tail=predExpr;
+ tail=&predExpr->right;
+ };
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ _retv=ANDnode;
+ ANDnode=NULL;
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+ predicate_free(ANDnode);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x40);
+ return _retv;
+ }
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+predPrimary(void)
+#else
+predPrimary()
+#endif
+{
+ Predicate * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(Predicate * ))
+ zzMake0;
+ {
+
+ char *name=NULL;
+ PredEntry *predEntry=NULL;
+ Predicate *predExpr=NULL;
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ name=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+
+ predEntry=(PredEntry *) hash_get(Pname,name);
+ if (predEntry == NULL) {
+ warnFL(eMsg1("no previously defined #pred with name \"%s\"",name),
+ FileStr[CurFile],zzline);
+ name=NULL;
+ _retv=NULL;
+ } else {
+ predExpr=predicate_dup(predEntry->pred);
+ predExpr->predEntry=predEntry;
+ _retv=predExpr;
+ };
+ }
+ else {
+ if ( (LA(1)==114) ) {
+ zzmatch(114); zzCONSUME;
+ predExpr = predOrExpr();
+
+ zzmatch(115);
+
+ _retv=predExpr;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==103) ) {
+ zzmatch(103); zzCONSUME;
+ predExpr = predPrimary();
+
+
+ predExpr->inverted=!predExpr->inverted;
+ _retv=predExpr;
+ }
+ else {zzFAIL(1,zzerr13,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+
+ predicate_free(predExpr);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x80);
+ return _retv;
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+aLexclass(void)
+#else
+aLexclass()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ zzmatch(116); zzCONSUME;
+ zzmatch(TokenTerm);
+ lexclass(mystrdup(LATEXT(1)));
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd4, 0x1);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+error(void)
+#else
+error()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ char *t=NULL; ECnode *e; int go=1; TermEntry *p;
+ zzmatch(117); zzCONSUME;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ ;
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr14,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ e = newECnode;
+ require(e!=NULL, "cannot allocate error class node");
+ e->lexclass = CurrentLexClass;
+ if ( Tnum( (t=StripQuotes(t)) ) == 0 )
+ {
+ if ( hash_get(Texpr, t) != NULL )
+ warn(eMsg1("errclass name conflicts with regular expression '%s'",t));
+ e->tok = addTname( t );
+ set_orel(e->tok, &imag_tokens);
+ require((p=(TermEntry *)hash_get(Tname, t)) != NULL,
+ "hash table mechanism is broken");
+ p->classname = 1; /* entry is errclass name, not token */
+ list_add(&eclasses, (char *)e);
+ }
+ else
+ {
+ warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t));
+ free( (char *)e );
+ go=0;
+}
+ zzmatch(102); zzCONSUME;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==NonTerminal) ) {
+ zzmatch(NonTerminal);
+ if ( go ) t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ if ( go ) t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ if ( go ) t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr15,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ if ( go ) list_add(&(e->elist), t);
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (setwd4[LA(1)]&0x2) ) {
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==NonTerminal) ) {
+ zzmatch(NonTerminal);
+ if ( go ) t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ if ( go ) t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ if ( go ) t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr16,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ if ( go ) list_add(&(e->elist), t);
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(98); zzCONSUME;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd4, 0x4);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+tclass(void)
+#else
+tclass()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p = NULL /* vbox: shut up GCC */, *term, *toterm;
+ char *akaString=NULL; int save_file; int save_line;
+ char *totext=NULL;
+ zzmatch(118); zzCONSUME;
+ zzmatch(TokenTerm);
+ t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ e = newTCnode;
+ require(e!=NULL, "cannot allocate token class node");
+ e->lexclass = CurrentLexClass;
+ if ( Tnum( t ) == 0 )
+ {
+ e->tok = addTname( t );
+ set_orel(e->tok, &imag_tokens);
+ set_orel(e->tok, &tokclasses);
+ require((p=(TermEntry *)hash_get(Tname, t)) != NULL,
+ "hash table mechanism is broken");
+ p->classname = 1; /* entry is class name, not token */
+ p->tclass = e; /* save ptr to this tclass def */
+ list_add(&tclasses, (char *)e);
+ }
+ else
+ {
+ warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t));
+ free( (char *)e );
+ go=0;
+}
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==114) ) {
+ zzmatch(114); zzCONSUME;
+ zzmatch(QuotedTerm);
+ akaString=mystrdup(StripQuotes(LATEXT(1)));
+ /* MR11 */ save_file=CurFile;save_line=zzline;
+ /* MR23 */
+ zzCONSUME;
+
+ zzmatch(115); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==102) ) {
+ }
+ else {zzFAIL(1,zzerr17,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ /* MR23 */ if (p!= NULL && akaString != NULL) {
+ /* MR23 */ if (p->akaString != NULL) {
+ /* MR23 */ if (strcmp(p->akaString,akaString) != 0) {
+ /* MR23 */ warnFL(eMsg2("this #tokclass statement conflicts with a previous #tokclass %s(\"%s\") statement",
+ /* MR23 */ t,p->akaString),
+ /* MR23 */ FileStr[save_file],save_line);
+ /* MR23 */ };
+ /* MR23 */ } else {
+ /* MR23 */ p->akaString=akaString;
+ /* MR23 */ };
+ /* MR23 */ };
+ /* MR23 */
+ zzmatch(102); zzCONSUME;
+ {
+ zzBLOCK(zztasp2);
+ int zzcnt=1;
+ zzMake0;
+ {
+ do {
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ if ( go ) {
+ term = (TermEntry *) hash_get(Tname, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ go = 0;
+ }
+ else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));}
+ }
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (LA(1)==119) ) {
+ zzmatch(119); zzCONSUME;
+ zzmatch(TokenTerm);
+ if ( go ) {
+ toterm = (TermEntry *) hash_get(Tname, LATEXT(1));
+ if ( toterm==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ go = 0;
+ } else {
+ totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1));
+ }
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd4[LA(1)]&0x8) ) {
+ }
+ else {zzFAIL(1,zzerr18,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ if ( go ) {
+ term = (TermEntry *) hash_get(Texpr, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ go = 0;
+ }
+ else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));}
+ }
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr19,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ if ( go ) {
+ if (totext == NULL) {
+ list_add(&(e->tlist), t);
+ } else {
+ list_add(&(e->tlist),"..");
+ list_add(&(e->tlist),t);
+ list_add(&(e->tlist),totext);
+ }
+ totext=NULL;
+ }
+ zzLOOP(zztasp2);
+ } while ( (setwd4[LA(1)]&0x10) );
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(98); zzCONSUME;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd4, 0x20);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+token(void)
+#else
+token()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ char *t=NULL, *e=NULL, *a=NULL; int tnum=0;
+ char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0;
+ zzmatch(120);
+ tokenActionActive=1;
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ t=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==114) ) {
+ zzmatch(114); zzCONSUME;
+ zzmatch(QuotedTerm);
+ akaString=mystrdup(StripQuotes(LATEXT(1)));
+ /* MR11 */ save_file=CurFile;save_line=zzline;
+ /* MR11 */
+ zzCONSUME;
+
+ zzmatch(115); zzCONSUME;
+ }
+ else {
+ if ( (setwd4[LA(1)]&0x40) ) {
+ }
+ else {zzFAIL(1,zzerr20,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==121) ) {
+ zzmatch(121); zzCONSUME;
+ zzmatch(122);
+ tnum = atoi(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd4[LA(1)]&0x80) ) {
+ }
+ else {zzFAIL(1,zzerr21,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ }
+ else {
+ if ( (setwd5[LA(1)]&0x1) ) {
+ }
+ else {zzFAIL(1,zzerr22,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ e=mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd5[LA(1)]&0x2) ) {
+ }
+ else {zzFAIL(1,zzerr23,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==Action) ) {
+ zzmatch(Action);
+
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule token: cannot allocate action");
+ strcpy(a, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd5[LA(1)]&0x4) ) {
+ }
+ else {zzFAIL(1,zzerr24,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==107) ) {
+ zzmatch(107); zzCONSUME;
+ }
+ else {
+ if ( (setwd5[LA(1)]&0x8) ) {
+ }
+ else {zzFAIL(1,zzerr25,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ chkToken(t, e, a, tnum);
+ if (t != NULL) {
+ te=(TermEntry *)hash_get(Tname,t);
+ if (te != NULL && akaString != NULL) {
+ if (te->akaString != NULL) {
+ if (strcmp(te->akaString,akaString) != 0) {
+ warnFL(eMsg2("this #token statement conflicts with a previous #token %s(\"%s\") statement",
+ t,te->akaString),
+ FileStr[save_file],save_line);
+ };
+ } else {
+ te->akaString=akaString;
+ };
+ };
+ };
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd5, 0x10);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+block(set * toksrefd,set * rulesrefd)
+#else
+block(toksrefd,rulesrefd)
+ set *toksrefd;
+set *rulesrefd ;
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+
+ Graph g, b;
+ set saveblah;
+ int saveinalt = inAlt;
+ ExceptionGroup *eg;
+ * toksrefd = empty;
+ * rulesrefd = empty;
+ set_clr(AST_nodes_refd_in_actions);
+ CurBlockID++;
+ /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;
+ CurAltNum = 1;
+ /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ saveblah = attribsRefdFromAction;
+ attribsRefdFromAction = empty;
+ alt( toksrefd,rulesrefd );
+ b = g = zzaArg(zztasp1,1);
+
+ if ( ((Junction *)g.left)->p1->ntype == nAction )
+ {
+ ActionNode *actionNode=(ActionNode *)
+ ( ( (Junction *)g.left) ->p1);
+ if (!actionNode->is_predicate )
+ {
+ actionNode->init_action = TRUE;
+ /* MR12c */ if (actionNode->noHoist) {
+ /* MR12c */ errFL("<<nohoist>> appears as init-action - use <<>> <<nohoist>>",
+ /* MR12c */ FileStr[actionNode->file],actionNode->line);
+ /* MR12c */ };
+ }
+ }
+ ((Junction *)g.left)->blockid = CurBlockID;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==133) ) {
+ eg = exception_group();
+
+
+ if ( eg!=NULL ) {
+ /* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/
+ /* MR7 ***** CurAltStart->exception_label = eg->altID; *****/
+ list_add(&CurExGroups, (void *)eg);
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ CurAltNum++;
+ /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==123) ) {
+ zzmatch(123);
+ inAlt=1;
+ zzCONSUME;
+
+ alt( toksrefd,rulesrefd );
+ g = Or(g, zzaArg(zztasp2,2));
+
+ ((Junction *)g.left)->blockid = CurBlockID;
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ while ( (LA(1)==133) ) {
+ eg = exception_group();
+
+
+ if ( eg!=NULL ) {
+ /* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/
+ /* MR7 ***** CurAltStart->exception_label = eg->altID; *****/
+ list_add(&CurExGroups, (void *)eg);
+ }
+ zzLOOP(zztasp3);
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ CurAltNum++;
+ /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzaArg(zztasp1,0) = b;
+ attribsRefdFromAction = saveblah; inAlt = saveinalt;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd5, 0x20);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+alt(set * toksrefd,set * rulesrefd)
+#else
+alt(toksrefd,rulesrefd)
+ set *toksrefd;
+set *rulesrefd ;
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif;
+ int first_on_line = 1, use_def_MT_handler = 0;
+ g.left=NULL; g.right=NULL;
+
+ CurAltStart = NULL;
+ elems = empty;
+ inAlt = 1;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==88) ) {
+ zzmatch(88);
+ use_def_MT_handler = 1;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd5[LA(1)]&0x40) ) {
+ }
+ else {zzFAIL(1,zzerr26,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ ;
+ while ( (setwd5[LA(1)]&0x80) ) {
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ old_not=0;
+ if ( (LA(1)==124) ) {
+ zzmatch(124);
+ old_not=1;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd6[LA(1)]&0x1) ) {
+ }
+ else {zzFAIL(1,zzerr27,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ node = element( old_not, first_on_line, use_def_MT_handler );
+
+ if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0;
+
+ if ( zzaArg(zztasp2,2 ).left!=NULL ) {
+ g = Cat(g, zzaArg(zztasp2,2));
+ n++;
+ if ( node!=NULL ) {
+ if ( node->ntype!=nAction ) e_num++;
+ /* record record number of all rule and token refs */
+ if ( node->ntype==nToken ) {
+ TokNode *tk = (TokNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1;
+ tk->elnum = e_num;
+ set_orel(e_num, &elems);
+ }
+ else if ( node->ntype==nRuleRef ) {
+ RuleRefNode *rn = (RuleRefNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1;
+ rn->elnum = e_num;
+ set_orel(e_num, rulesrefd);
+ }
+ }
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ if ( n == 0 ) g = emptyAlt();
+ zzaArg(zztasp1,0) = g;
+ /* We want to reduce number of LT(i) calls and the number of
+ * local attribute variables in C++ mode (for moment, later we'll
+ * do for C also). However, if trees are being built, they
+ * require most of the attrib variables to create the tree nodes
+ * with; therefore, we gen a token ptr for each token ref in C++
+ */
+ if ( GenCC && !GenAST )
+ {
+ /* This now free's the temp set -ATG 5/6/95 */
+ set temp;
+ temp = set_and(elems, attribsRefdFromAction);
+ set_orin( toksrefd, temp);
+ set_free(temp);
+}
+else set_orin( toksrefd, elems);
+if ( GenCC ) {
+ dif = set_dif(attribsRefdFromAction, elems);
+ if ( set_deg(dif)>0 )
+ err("one or more $i in action(s) refer to non-token elements");
+ set_free(dif);
+}
+set_free(elems);
+set_free(attribsRefdFromAction);
+inAlt = 0;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd6, 0x2);
+ }
+}
+
+LabelEntry *
+#ifdef __USE_PROTOS
+element_label(void)
+#else
+element_label()
+#endif
+{
+ LabelEntry * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(LabelEntry * ))
+ zzMake0;
+ {
+ TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab;
+ zzmatch(LABEL);
+ lab = mystrdup(LATEXT(1));
+ zzCONSUME;
+
+
+ UsedNewStyleLabel = 1;
+ if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i");
+ t = (TermEntry *) hash_get(Tname, lab);
+ if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab);
+ if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab);
+ if ( t!=NULL ) {
+ err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab));
+ _retv = NULL;
+ }
+ else if ( r!=NULL ) {
+ err(eMsg1("label definition clashes with rule definition: '%s'", lab));
+ _retv = NULL;
+ }
+ else {
+ /* we don't clash with anybody else */
+ l = (LabelEntry *) hash_get(Elabel, lab);
+ if ( l==NULL ) { /* ok to add new element label */
+ l = (LabelEntry *)hash_add(Elabel,
+ lab,
+ (Entry *)newLabelEntry(lab));
+ /* add to list of element labels for this rule */
+ list_add(&CurElementLabels, (void *)lab);
+ /* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */
+ _retv = l;
+ }
+ else {
+ err(eMsg1("label definitions must be unique per rule: '%s'", lab));
+ _retv = NULL;
+}
+}
+ zzmatch(106); zzCONSUME;
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd6, 0x4);
+ return _retv;
+ }
+}
+
+Node *
+#ifdef __USE_PROTOS
+element(int old_not,int first_on_line,int use_def_MT_handler)
+#else
+element(old_not,first_on_line,use_def_MT_handler)
+ int old_not;
+int first_on_line;
+int use_def_MT_handler ;
+#endif
+{
+ Node * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(Node * ))
+ zzMake0;
+ {
+
+ Attrib blk;
+ Predicate *pred = NULL;
+ int local_use_def_MT_handler=0;
+ ActionNode *act;
+ RuleRefNode *rr;
+ set toksrefd, rulesrefd;
+ TermEntry *term;
+ TokNode *p=NULL; RuleRefNode *q; int approx=0;
+ LabelEntry *label=NULL;
+ int predMsgDone=0;
+ int semDepth=0;
+ int ampersandStyle;
+ int height; /* MR11 */
+ int equal_height; /* MR11 */
+
+ char* pFirstSetSymbol = NULL; /* MR21 */
+
+ _retv = NULL;
+ if ( (setwd6[LA(1)]&0x8) ) {
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==LABEL) ) {
+ label = element_label();
+
+ }
+ else {
+ if ( (setwd6[LA(1)]&0x10) ) {
+ }
+ else {zzFAIL(1,zzerr28,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+
+ term = (TermEntry *) hash_get(Tname, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ zzaRet.left = zzaRet.right = NULL;
+ }
+ else {
+ zzaRet = buildToken(LATEXT(1));
+ p=((TokNode *)((Junction *)zzaRet.left)->p1);
+ term = (TermEntry *) hash_get(Tname, LATEXT(1));
+ require( term!= NULL, "hash table mechanism is broken");
+ p->tclass = term->tclass;
+ p->complement = old_not;
+ if ( label!=NULL ) {
+ p->el_label = label->str;
+ label->elem = (Node *)p;
+ }
+ }
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==119) ) {
+ zzmatch(119); zzCONSUME;
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ if ( p!=NULL ) setUpperRange(p, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ if ( p!=NULL ) setUpperRange(p, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr29,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+ }
+ else {
+ if ( (setwd6[LA(1)]&0x20) ) {
+ }
+ else {zzFAIL(1,zzerr30,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+
+ if ( p!=NULL && (p->upper_range!=0 || p->tclass || old_not) )
+ list_add(&MetaTokenNodes, (void *)p);
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==125) ) {
+ zzmatch(125);
+ if ( p!=NULL ) p->astnode=ASTroot;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd6[LA(1)]&0x40) ) {
+ if ( p!=NULL ) p->astnode=ASTchild;
+ }
+ else {
+ if ( (LA(1)==103) ) {
+ zzmatch(103);
+ if ( p!=NULL ) p->astnode=ASTexclude;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr31,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==88) ) {
+ zzmatch(88);
+ local_use_def_MT_handler = 1;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd6[LA(1)]&0x80) ) {
+ }
+ else {zzFAIL(1,zzerr32,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+
+ if ( p!=NULL && first_on_line ) {
+ CurAltStart = (Junction *)zzaRet.left;
+ altAdd(CurAltStart); /* MR7 */
+ p->altstart = CurAltStart;
+ }
+ if ( p!=NULL )
+ p->use_def_MT_handler = use_def_MT_handler || local_use_def_MT_handler;
+ _retv = (Node *)p;
+ }
+ else {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+
+ term = (TermEntry *) hash_get(Texpr, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ zzaRet.left = zzaRet.right = NULL;
+ }
+ else {
+ zzaRet = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1);
+ p->complement = old_not;
+ if ( label!=NULL ) {
+ p->el_label = label->str;
+ label->elem = (Node *)p;
+ }
+ }
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==119) ) {
+ zzmatch(119); zzCONSUME;
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (LA(1)==QuotedTerm) ) {
+ zzmatch(QuotedTerm);
+ if ( p!=NULL ) setUpperRange(p, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+ if ( p!=NULL ) setUpperRange(p, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr33,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x1) ) {
+ }
+ else {zzFAIL(1,zzerr34,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==125) ) {
+ zzmatch(125);
+ if ( p!=NULL ) p->astnode=ASTroot;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x2) ) {
+ if ( p!=NULL ) p->astnode=ASTchild;
+ }
+ else {
+ if ( (LA(1)==103) ) {
+ zzmatch(103);
+ if ( p!=NULL ) p->astnode=ASTexclude;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr35,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==88) ) {
+ zzmatch(88);
+ local_use_def_MT_handler = 1;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x4) ) {
+ }
+ else {zzFAIL(1,zzerr36,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+
+ if ( p!=NULL && (p->upper_range!=0 || p->tclass || old_not) )
+ list_add(&MetaTokenNodes, (void *)p);
+
+ if ( first_on_line ) {
+ CurAltStart = (Junction *)zzaRet.left;
+ altAdd(CurAltStart); /* MR7 */
+ p->altstart = CurAltStart;
+ }
+ if ( p!=NULL )
+ p->use_def_MT_handler = use_def_MT_handler || local_use_def_MT_handler;
+ _retv = (Node *)p;
+ }
+ else {
+ if ( (LA(1)==WildCard) ) {
+ if ( old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')");
+ zzmatch(WildCard);
+ zzaRet = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1);
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==125) ) {
+ zzmatch(125);
+ p->astnode=ASTroot;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x8) ) {
+ p->astnode=ASTchild;
+ }
+ else {
+ if ( (LA(1)==103) ) {
+ zzmatch(103);
+ p->astnode=ASTexclude;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr37,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ list_add(&MetaTokenNodes, (void *)p);
+
+ if ( first_on_line ) {
+ CurAltStart = (Junction *)zzaRet.left;
+ altAdd(CurAltStart); /* MR7 */
+ p->altstart = CurAltStart;
+ if ( label!=NULL ) {
+ p->el_label = label->str;
+ label->elem = (Node *)p;
+ }
+ }
+ _retv = (Node *)p;
+ }
+ else {
+ if ( (LA(1)==NonTerminal) ) {
+ if ( old_not ) warn("~ NONTERMINAL is an undefined operation");
+ zzmatch(NonTerminal);
+ zzaRet = buildRuleRef(LATEXT(1));
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==103) ) {
+ zzmatch(103);
+ q = (RuleRefNode *) ((Junction *)zzaRet.left)->p1;
+ q->astnode=ASTexclude;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x10) ) {
+ }
+ else {zzFAIL(1,zzerr38,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (setwd7[LA(1)]&0x20) ) {
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (LA(1)==104) ) {
+ zzmatch(104); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==PassAction) ) {
+ }
+ else {zzFAIL(1,zzerr39,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+ zzmatch(PassAction);
+ addParm(((Junction *)zzaRet.left)->p1, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x40) ) {
+ }
+ else {zzFAIL(1,zzerr40,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ rr=(RuleRefNode *) ((Junction *)zzaRet.left)->p1;
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ char *a;
+ if ( (LA(1)==105) ) {
+ zzmatch(105); zzCONSUME;
+ zzmatch(PassAction);
+
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule element: cannot allocate assignment");
+ strcpy(a, LATEXT(1));
+ rr->assign = a;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd7[LA(1)]&0x80) ) {
+ }
+ else {zzFAIL(1,zzerr41,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+
+ if ( label!=NULL ) {
+ rr->el_label = label->str;
+ label->elem = (Node *)rr;
+ }
+ if ( first_on_line ) {
+ CurAltStart = (Junction *)zzaRet.left;
+ altAdd(CurAltStart); /* MR7 */
+ ((RuleRefNode *)((Junction *)zzaRet.left)->p1)->altstart = CurAltStart;
+ }
+ _retv = (Node *)rr;
+ }
+ else {zzFAIL(1,zzerr42,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==Action) ) {
+ if ( old_not ) warn("~ ACTION is an undefined operation");
+ zzmatch(Action);
+ zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 0);
+ zzCONSUME;
+
+ if ( first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left; /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };
+ _retv = (Node *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1;
+ }
+ else {
+ if ( (LA(1)==Pred) ) {
+ if ( old_not ) warn("~ SEMANTIC-PREDICATE is an undefined operation");
+ zzmatch(Pred);
+ zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 1);
+ zzCONSUME;
+
+ act = (ActionNode *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1;
+ if (numericActionLabel) { /* MR10 */
+ list_add(&NumericPredLabels,act); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ }; /* MR10 */
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ char *a;
+ if ( (LA(1)==PassAction) ) {
+ zzmatch(PassAction);
+
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule element: cannot allocate predicate fail action");
+ strcpy(a, LATEXT(1));
+ act->pred_fail = a;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x1) ) {
+ }
+ else {zzFAIL(1,zzerr43,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ if ( first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left; /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };
+ _retv = (Node *)act;
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x2) ) {
+ if ( old_not ) warn("~ BLOCK is an undefined operation");
+ BlkLevel++;
+ if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");
+ /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;
+ /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==Pragma) ) {
+ zzmatch(Pragma); zzCONSUME;
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==126) ) {
+ zzmatch(126);
+ approx=LL_k;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==127) ) {
+ zzmatch(127);
+ approx = 1;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==128) ) {
+ zzmatch(128);
+ approx = 2;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr44,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x4) ) {
+ }
+ else {zzFAIL(1,zzerr45,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==FirstSetSymbol) ) {
+ zzmatch(FirstSetSymbol); zzCONSUME;
+ zzmatch(114); zzCONSUME;
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==NonTerminal) ) {
+ zzmatch(NonTerminal);
+
+ /* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,
+ /* MR21 */ sizeof(char));
+ /* MR21 */ require(pFirstSetSymbol!=NULL,
+ /* MR21 */ "cannot allocate first set name");
+ /* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1));
+ /* MR21 */
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+
+ /* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,
+ /* MR21 */ sizeof(char));
+ /* MR21 */ require(pFirstSetSymbol!=NULL,
+ /* MR21 */ "cannot allocate first set name");
+ /* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1));
+ /* MR21 */
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr46,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ zzmatch(115); zzCONSUME;
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x8) ) {
+ }
+ else {zzFAIL(1,zzerr47,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==114) ) {
+ zzmatch(114); zzCONSUME;
+ block( &toksrefd,&rulesrefd );
+ zzmatch(115);
+ blk = zzaRet = zzaArg(zztasp2,2);
+ /* MR23 */ CurBlockID_array[BlkLevel] = (-1);
+ /* MR23 */ CurAltNum_array[BlkLevel] = (-1);
+ --BlkLevel;
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==129) ) {
+ zzmatch(129);
+ zzaRet = makeLoop(zzaRet,approx,pFirstSetSymbol);
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==130) ) {
+ zzmatch(130);
+ zzaRet = makePlus(zzaRet,approx,pFirstSetSymbol);
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==131) ) {
+ zzmatch(131); zzCONSUME;
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (setwd8[LA(1)]&0x10) ) {
+ {
+ zzBLOCK(zztasp5);
+ zzMake0;
+ {
+ if ( (LA(1)==132) ) {
+ zzmatch(132);
+ ampersandStyle=0;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==113) ) {
+ zzmatch(113);
+ ampersandStyle=1;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr48,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp5);
+ }
+ }
+ zzmatch(Pred);
+ zzaRet = buildAction(LATEXT(1),action_file,action_line,1);
+ zzCONSUME;
+
+ act = (ActionNode *) ((Junction *)zzaRet.left)->p1;
+ semDepth=predicateLookaheadDepth(act);
+ if (numericActionLabel) { /* MR10 */
+ list_add(&NumericPredLabels,act); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ }; /* MR10 */
+ {
+ zzBLOCK(zztasp5);
+ zzMake0;
+ {
+ char *a;
+ if ( (LA(1)==PassAction) ) {
+ zzmatch(PassAction);
+
+ a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule element: cannot allocate predicate fail action");
+ strcpy(a, LATEXT(1));
+ act->pred_fail = a;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x20) ) {
+ }
+ else {zzFAIL(1,zzerr49,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp5);
+ }
+ }
+ if ( first_on_line) { /* MR7 */
+ CurAltStart=(Junction *)zzaRet.left; /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };
+ _retv = (Node *)act;
+
+ pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */
+ if ( pred==NULL) { /* MR10 */
+ if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */
+ predMsgDone=1; /* MR10 */
+ } else { /* MR10 */
+ act->guardNodes=(Junction *)blk.left; /* MR11 */
+ pred->expr = act->action;
+ pred->source = act;
+ /* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */
+ /* MR13 */ if (pred->tcontext != NULL) {
+ /* MR13 */ height=MR_max_height_of_tree(pred->tcontext);
+ /* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height);
+ /* MR13 */ if (! equal_height) {
+ /* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height",
+ /* MR13 */ FileStr[act->file],act->line);
+ /* MR13 */ };
+ /* MR13 */ }
+ /* MR10 */ if (ampersandStyle) {
+ /* MR10 */ act->ampersandPred = pred;
+ /* MR11 */ if (! HoistPredicateContext) {
+ /* MR11 */ errFL("without \"-prc on\" (guard)? && <<pred>>? ... doesn't make sense",
+ /* MR11 */ FileStr[act->file],act->line);
+ /* MR11 */ };
+ /* MR10 */ } else {
+ /* MR10 */ act->guardpred = pred;
+ /* MR10 */ };
+ /* MR10 */ if (pred->k != semDepth) {
+ /* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)",
+ /* MR10 */ pred->k,semDepth));
+ /* MR10 */ };
+ }
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x40) ) {
+ zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol);
+ FoundGuessBlk = 1;
+ ((Junction *) ((Junction *)zzaRet.left)->p1)->guess=1;
+ if ( ! first_on_line ) {
+ err("(...)? predicate must be first element of production");
+ }
+ }
+ else {zzFAIL(1,zzerr50,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+ }
+ else {
+ if ( (setwd8[LA(1)]&0x80) ) {
+ zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol);
+ }
+ else {zzFAIL(1,zzerr51,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+
+ if ( pred==NULL && !predMsgDone) { /* MR10 */
+ ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID;
+ ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd;
+ ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd;
+ if ( first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *)((Junction *)((Junction *)zzaRet.left)->p1); /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ }; /* MR7 */
+ _retv = (Node *) ((Junction *)zzaRet.left)->p1;
+ }
+ }
+ else {
+ if ( (LA(1)==102) ) {
+ zzmatch(102); zzCONSUME;
+ block( &toksrefd,&rulesrefd );
+ zzaRet = makeOpt(zzaArg(zztasp2,2),approx,pFirstSetSymbol);
+ /* MR23 */ CurBlockID_array[BlkLevel] = (-1);
+ /* MR23 */ CurAltNum_array[BlkLevel] = (-1);
+ --BlkLevel;
+ zzmatch(98);
+
+ ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID;
+ ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd;
+ ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd;
+ zzCONSUME;
+
+ if ( first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *) ((Junction *)((Junction *)zzaRet.left)->p1); /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };
+ _retv = (Node *) ((Junction *)zzaRet.left)->p1;
+ }
+ else {zzFAIL(1,zzerr52,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==129) ) {
+ zzmatch(129);
+ warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==130) ) {
+ zzmatch(130);
+ warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==105) ) {
+ zzmatch(105);
+ warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==PassAction) ) {
+ zzmatch(PassAction);
+ warn("[...] out of context 'rule > [...]'");
+ CannotContinue=TRUE;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr53,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd9, 0x1);
+ return _retv;
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+default_exception_handler(void)
+#else
+default_exception_handler()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ DefaultExGroup = exception_group();
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd9, 0x2);
+ }
+}
+
+ExceptionGroup *
+#ifdef __USE_PROTOS
+exception_group(void)
+#else
+exception_group()
+#endif
+{
+ ExceptionGroup * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(ExceptionGroup * ))
+ zzMake0;
+ {
+ ExceptionHandler *h; LabelEntry *label=NULL; /* MR6 */
+ FoundException = 1; FoundExceptionGroup = 1;
+ zzmatch(133);
+ _retv = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ char *p;
+ if ( (LA(1)==PassAction) ) {
+ zzmatch(PassAction);
+
+ p = LATEXT(1)+1;
+ p[strlen(p)-1] = '\0'; /* kill trailing space */
+ label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1);
+ if ( label==NULL )
+ {
+ err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1));
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd9[LA(1)]&0x4) ) {
+ }
+ else {zzFAIL(1,zzerr54,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==135) ) {
+ h = exception_handler();
+
+ list_add(&(_retv->handlers), (void *)h);
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==134) ) {
+ zzmatch(134); zzCONSUME;
+ zzmatch(106); zzCONSUME;
+ zzmatch(Action);
+ {
+ ExceptionHandler *eh = (ExceptionHandler *)
+ calloc(1, sizeof(ExceptionHandler));
+ char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(eh!=NULL, "exception: cannot allocate handler");
+ require(a!=NULL, "exception: cannot allocate action");
+ strcpy(a, LATEXT(1));
+ eh->action = a;
+ eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char));
+ require(eh->signalname!=NULL, "exception: cannot allocate sig name");
+ strcpy(eh->signalname, "default");
+ list_add(&(_retv->handlers), (void *)eh);
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd9[LA(1)]&0x8) ) {
+ }
+ else {zzFAIL(1,zzerr55,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ if ( label!=NULL ) {
+ /* Record ex group in sym tab for this label */
+ if ( label->ex_group!=NULL ) {
+ err(eMsg1("duplicate exception handler for label '%s'",label->str));
+ } else {
+ label->ex_group = _retv;
+ /* Label the exception group itself */
+ _retv->label = label->str;
+ /* Make the labelled element pt to the exception also */
+ /* MR6 */ if (label->elem == NULL) {
+ /* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str));
+ /* MR6 */ } else {
+ switch ( label->elem->ntype ) {
+ case nRuleRef :
+ {
+ RuleRefNode *r = (RuleRefNode *)label->elem;
+ r->ex_group = _retv;
+ break;
+ }
+ case nToken :
+ {
+ TokNode *t = (TokNode *)label->elem;
+ t->ex_group = _retv;
+ break;
+ }
+ } /* end switch */
+ /* MR6 */ }; /* end test on label->elem */
+ } /* end test on label->ex_group */
+
+ } /* end test on exception label */
+
+/* MR7 */
+ /* MR7 */ if (BlkLevel == 1 && label == NULL) {
+ /* MR7 */ _retv->forRule=1;
+ /* MR7 */ } else if (label == NULL) {
+ /* MR7 */ _retv->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]);
+ /* MR7 */ egAdd(_retv);
+ /* MR7 */ } else {
+ /* MR7 */ _retv->labelEntry=label;
+ /* MR7 */ };
+ /* MR7 */
+ /* MR7 */ /* You may want to remove this exc from the rule list */
+ /* MR7 */ /* and handle at the labeled element site. */
+ /* MR7 */
+ /* MR7 */ if (label != NULL) {
+ /* MR7 */ _retv = NULL;
+ /* MR7 */ };
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd9, 0x10);
+ return _retv;
+ }
+}
+
+ExceptionHandler *
+#ifdef __USE_PROTOS
+exception_handler(void)
+#else
+exception_handler()
+#endif
+{
+ ExceptionHandler * _retv;
+ zzRULE;
+ zzBLOCK(zztasp1);
+ PCCTS_PURIFY(_retv,sizeof(ExceptionHandler * ))
+ zzMake0;
+ {
+ ;
+ zzmatch(135);
+
+ _retv = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler));
+ require(_retv!=NULL, "exception: cannot allocate handler");
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==NonTerminal) ) {
+ zzmatch(NonTerminal);
+
+ _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(_retv->signalname!=NULL, "exception: cannot allocate sig name");
+ strcpy(_retv->signalname, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TokenTerm) ) {
+ zzmatch(TokenTerm);
+
+ _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(_retv->signalname!=NULL, "exception: cannot allocate sig name");
+ strcpy(_retv->signalname, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr56,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(106); zzCONSUME;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ _retv->action = NULL;
+ if ( (LA(1)==Action) ) {
+ zzmatch(Action);
+
+ _retv->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(_retv->action!=NULL, "exception: cannot allocate action");
+ strcpy(_retv->action, LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd9[LA(1)]&0x20) ) {
+ }
+ else {zzFAIL(1,zzerr57,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return _retv;
+fail:
+ zzEXIT(zztasp1);
+ CannotContinue=TRUE;
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd9, 0x40);
+ return _retv;
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+enum_file(char * fname)
+#else
+enum_file(fname)
+ char *fname ;
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (setwd9[LA(1)]&0x80) ) {
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==143) ) {
+ zzmatch(143); zzCONSUME;
+ zzmatch(ID); zzCONSUME;
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==149) ) {
+ zzmatch(149); zzCONSUME;
+ zzmatch(ID); zzCONSUME;
+ }
+ else {
+ if ( (setwd10[LA(1)]&0x1) ) {
+ }
+ else {zzFAIL(1,zzerr58,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ }
+ else {
+ if ( (setwd10[LA(1)]&0x2) ) {
+ }
+ else {zzFAIL(1,zzerr59,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==151) ) {
+ {
+ zzBLOCK(zztasp3);
+ int zzcnt=1;
+ zzMake0;
+ {
+ do {
+ enum_def( fname );
+ zzLOOP(zztasp3);
+ } while ( (LA(1)==151) );
+ zzEXIT(zztasp3);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==149) ) {
+ defines( fname );
+ }
+ else {zzFAIL(1,zzerr60,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==Eof) ) {
+ }
+ else {zzFAIL(1,zzerr61,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd10, 0x4);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+defines(char * fname)
+#else
+defines(fname)
+ char *fname ;
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ int v; int maxt=(-1); char *t;
+ {
+ zzBLOCK(zztasp2);
+ int zzcnt=1;
+ zzMake0;
+ {
+ do {
+ zzmatch(149); zzCONSUME;
+ zzmatch(ID);
+ t = mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ zzmatch(INT);
+
+ v = atoi(LATEXT(1));
+ /* fprintf(stderr, "#token %s=%d\n", t, v);*/
+
+ /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */
+ /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */
+ /* MR2 Don't let #tokdefs be confused by */
+ /* MR2 DLGminToken and DLGmaxToken */
+
+ if ( ! isDLGmaxToken(t)) { /* MR2 */
+ TokenNum = v;
+ if ( v>maxt ) maxt=v;
+ if ( Tnum( t ) == 0 ) {
+ addForcedTname( t, v );
+ } else {
+ warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline);
+ };
+};
+ zzCONSUME;
+
+ zzLOOP(zztasp2);
+ } while ( (LA(1)==149) );
+ zzEXIT(zztasp2);
+ }
+ }
+ TokenNum = maxt + 1;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd10, 0x8);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+enum_def(char * fname)
+#else
+enum_def(fname)
+ char *fname ;
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ int v= 0; int maxt=(-1); char *t;
+ zzmatch(151); zzCONSUME;
+ zzmatch(ID); zzCONSUME;
+ zzmatch(152); zzCONSUME;
+ zzmatch(ID);
+ t = mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==153) ) {
+ zzmatch(153); zzCONSUME;
+ zzmatch(INT);
+ v=atoi(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd10[LA(1)]&0x10) ) {
+ v++;
+ }
+ else {zzFAIL(1,zzerr62,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+
+ /* fprintf(stderr, "#token %s=%d\n", t, v);*/
+ TokenNum = v;
+ if ( v>maxt ) maxt=v; /* MR3 */
+ if ( Tnum( t ) == 0 ) addForcedTname( t, v );
+ else {
+ warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline);
+ }
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==154) ) {
+ zzmatch(154); zzCONSUME;
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==ID)&&(isDLGmaxToken(LATEXT(1))) ) {
+ if (!(isDLGmaxToken(LATEXT(1))) ) {zzfailed_pred(" isDLGmaxToken(LATEXT(1))",0 /* report */, { ; /* no user action */ } );}
+ zzmatch(ID); zzCONSUME;
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (LA(1)==153) ) {
+ zzmatch(153); zzCONSUME;
+ zzmatch(INT); zzCONSUME;
+ }
+ else {
+ if ( (setwd10[LA(1)]&0x20) ) {
+ }
+ else {zzFAIL(1,zzerr63,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==ID) ) {
+ zzmatch(ID);
+ t = mystrdup(LATEXT(1));
+ zzCONSUME;
+
+ {
+ zzBLOCK(zztasp4);
+ zzMake0;
+ {
+ if ( (LA(1)==153) ) {
+ zzmatch(153); zzCONSUME;
+ zzmatch(INT);
+ v=atoi(LATEXT(1));
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd10[LA(1)]&0x40) ) {
+ v++;
+ }
+ else {zzFAIL(1,zzerr64,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp4);
+ }
+ }
+
+ /* fprintf(stderr, "#token %s=%d\n", t, v);*/
+ TokenNum = v;
+ if ( v>maxt ) maxt=v; /* MR3 */
+ if ( Tnum( t ) == 0 ) addForcedTname( t, v );
+ else {
+ warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline);
+ }
+ }
+ else {
+ if ( (setwd10[LA(1)]&0x80) ) {
+ }
+ else {zzFAIL(1,zzerr65,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(155); zzCONSUME;
+ zzmatch(156);
+ TokenNum = maxt + 1;
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd11, 0x1);
+ }
+}
+
+
+/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */
+/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */
+/* MR2 Don't let #tokdefs be confused by */
+/* MR2 DLGminToken and DLGmaxToken */
+
+/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */
+
+#ifdef __USE_PROTOS
+static int isDLGmaxToken(char *Token)
+#else
+static int isDLGmaxToken(Token)
+char * Token;
+#endif
+{
+static char checkStr1[] = "DLGmaxToken";
+static char checkStr2[] = "DLGminToken";
+
+ if (strcmp(Token, checkStr1) == 0)
+return 1;
+else if (strcmp(Token, checkStr2) == 0)
+return 1;
+else
+return 0;
+}
+
+/* semantics of #token */
+static void
+#ifdef __USE_PROTOS
+chkToken(char *t, char *e, char *a, int tnum)
+#else
+chkToken(t,e,a,tnum)
+char *t, *e, *a;
+int tnum;
+#endif
+{
+TermEntry *p;
+
+ /* check to see that they don't try to redefine a token as a token class */
+if ( t!=NULL ) {
+p = (TermEntry *) hash_get(Tname, t);
+if ( p!=NULL && p->classname ) {
+ err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t));
+ if ( a!=NULL ) free((char *)a);
+ return;
+}
+}
+
+ if ( t==NULL && e==NULL ) { /* none found */
+err("#token requires at least token name or rexpr");
+}
+else if ( t!=NULL && e!=NULL ) { /* both found */
+if ( UserDefdTokens ) { /* if #tokdefs, must not define new */
+ p = (TermEntry *) hash_get(Tname, t);
+ if ( p == NULL) {
+ err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));
+ return;
+ };
+}
+Tklink(t, e);
+if ( a!=NULL ) {
+ if ( hasAction(e) ) {
+ err(eMsg1("redefinition of action for %s; ignored",e));
+ }
+ else setHasAction(e, a);
+}
+}
+else if ( t!=NULL ) { /* only one found */
+if ( UserDefdTokens ) {
+ p = (TermEntry *) hash_get(Tname, t);
+ if (p == NULL) {
+ err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));
+ };
+ return;
+}
+if ( Tnum( t ) == 0 ) addTname( t );
+else {
+ err(eMsg1("redefinition of token %s; ignored",t));
+}
+if ( a!=NULL ) {
+ err(eMsg1("action cannot be attached to a token name (%s); ignored",t));
+ free((char *)a);
+}
+}
+else if ( e!=NULL ) {
+if ( Tnum( e ) == 0 ) addTexpr( e );
+else {
+ if ( hasAction(e) ) {
+ err(eMsg1("redefinition of action for expr %s; ignored",e));
+ }
+ else if ( a==NULL ) {
+ err(eMsg1("redefinition of expr %s; ignored",e));
+ }
+}
+if ( a!=NULL ) setHasAction(e, a);
+}
+
+ /* if a token type number was specified, then add the token ID and 'tnum'
+* pair to the ForcedTokens list. (only applies if an id was given)
+*/
+if ( t!=NULL && tnum>0 )
+{
+if ( set_el(tnum, reserved_positions) )
+{
+ err(eMsgd("a token has already been forced to token number %d; ignored", tnum));
+}
+else
+{
+ list_add(&ForcedTokens, newForcedToken(t,tnum));
+ set_orel(tnum, &reserved_positions);
+}
+}
+}
+
+static int
+#ifdef __USE_PROTOS
+match_token(char *s, char **nxt)
+#else
+match_token(s,nxt)
+char *s;
+char **nxt;
+#endif
+{
+ if ( !(*s>='A' && *s<='Z') ) return 0;
+ s++;
+ while ( (*s>='a' && *s<='z') ||
+ (*s>='A' && *s<='Z') ||
+ (*s>='0' && *s<='9') ||
+ *s=='_' )
+ {
+ s++;
+ }
+ if ( *s!=' ' && *s!='}' ) return 0;
+ *nxt = s;
+ return 1;
+}
+
+static int
+#ifdef __USE_PROTOS
+match_rexpr(char *s, char **nxt)
+#else
+match_rexpr(s,nxt)
+char *s;
+char **nxt;
+#endif
+{
+ if ( *s!='"' ) return 0;
+ s++;
+ while ( *s!='"' )
+ {
+ if ( *s=='\n' || *s=='\r' ) /* MR13 */
+ warn("eoln found in regular expression");
+ if ( *s=='\\' ) s++;
+ s++;
+ }
+ *nxt = s+1;
+ return 1;
+}
+
+/*
+* Walk a string "{ A .. Z }" where A..Z is a space separated list
+* of token references (either labels or reg exprs). Return a
+* string "inlineX_set" for some unique integer X. Basically,
+* we pretend as if we had seen "#tokclass inlineX { A .. Z }"
+* on the input stream outside of an action.
+*/
+char *
+#ifdef __USE_PROTOS
+inline_set(char *s)
+#else
+inline_set(s)
+char *s;
+#endif
+{
+ char *nxt;
+ fprintf(stderr, "found consumeUntil( {...} )\n");
+ while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}
+ if ( *s!='{' )
+ {
+ err("malformed consumeUntil( {...} ); missing '{'");
+ return "bad_set";
+ }
+ s++;
+ while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}
+ while ( *s!='}' )
+ {
+ if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s);
+ else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s);
+ else {
+ err("invalid element in consumeUntil( {...} )");
+ return "bad_set";
+ }
+ s = nxt;
+ while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}
+ }
+ return "inlineX_set";
+}
+
+/* ANTLR-specific syntax error message generator
+* (define USER_ZZSYN when compiling so don't get 2 definitions)
+*/
+void
+#ifdef __USE_PROTOS
+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok,
+int k, char *bad_text)
+#else
+zzsyn(text, tok, egroup, eset, etok, k, bad_text)
+char *text, *egroup, *bad_text;
+int tok;
+int etok;
+int k;
+SetWordType *eset;
+#endif
+{
+fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline);
+fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);
+if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
+if ( k==1 ) fprintf(stderr, " missing");
+else
+{
+fprintf(stderr, "; \"%s\" not", bad_text);
+if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
+}
+if ( zzset_deg(eset)>0 ) zzedecode(eset);
+else fprintf(stderr, " %s", zztokens[etok]);
+if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);
+fprintf(stderr, "\n");
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.g b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.g
new file mode 100644
index 00000000..7df4b319
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.g
@@ -0,0 +1,2587 @@
+/*
+ * antlr.g -- PCCTS Version 1.xx ANTLR
+ *
+ * Parse an antlr input grammar and build a syntax-diagram.
+ *
+ * Written in itself (needs at least 1.06 to work)
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+/* MR1 */
+/* MR1 10-Apr-97 MR1 Replace #if logic with #include "pcctscfg.h" */
+/* MR1 */
+
+#header <<
+ #include "pcctscfg.h"
+ #include "set.h"
+ #include <ctype.h>
+ #include "syn.h"
+ #include "hash.h"
+ #include "generic.h"
+ #define zzcr_attr(attr,tok,t)
+ >>
+
+<<
+
+/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */
+#if defined(__TURBOC__)
+#pragma warn -aus /* unused assignment of 'xxx' */
+#endif
+
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+
+#ifdef __USE_PROTOS
+static void chkToken(char *, char *, char *, int);
+#else
+static void chkToken();
+#endif
+
+#ifdef __USE_PROTOS
+static int isDLGmaxToken(char *Token); /* MR3 */
+#else
+static int isDLGmaxToken(); /* MR3 */
+#endif
+
+static int class_nest_level = 0;
+
+/* MR20 G. Hobbelt extern definitions moved to antlr.h */
+
+>>
+
+#lexaction <<
+/* maintained, but not used for now */
+set AST_nodes_refd_in_actions = set_init;
+int inAlt = 0;
+set attribsRefdFromAction = set_init; /* MR20 */
+int UsedOldStyleAttrib = 0;
+int UsedNewStyleLabel = 0;
+#ifdef __USE_PROTOS
+char *inline_set(char *);
+#else
+char *inline_set();
+#endif
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+/* MR1 in DLG action */
+
+int tokenActionActive=0; /* MR1 */
+
+>>
+
+#lexclass STRINGS
+#token QuotedTerm "\"" << zzmode(START); >>
+#token "\n|\r|\r\n" <<
+ zzline++;
+ warn("eoln found in string");
+ zzskip();
+ >>
+#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >>
+#token "\\~[]" << zzmore(); >>
+#token "~[\n\r\"\\]+" << zzmore(); >>
+
+#lexclass ACTION_STRINGS
+#token "\"" << zzmode(ACTIONS); zzmore(); >>
+#token "\n|\r|\r\n" <<
+ zzline++;
+ warn("eoln found in string (in user action)");
+ zzskip();
+ >>
+#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >>
+#token "\\~[]" << zzmore(); >>
+#token "~[\n\r\"\\]+" << zzmore(); >>
+
+#lexclass ACTION_CHARS
+#token "'" << zzmode(ACTIONS); zzmore(); >>
+#token "\n|\r|\r\n" <<
+ zzline++;
+ warn("eoln found in char literal (in user action)");
+ zzskip();
+ >>
+#token "\\~[]" << zzmore(); >>
+#token "~[\n\r'\\]+" << zzmore(); >>
+
+#lexclass ACTION_COMMENTS
+#token "\*/" << zzmode(ACTIONS); zzmore(); >>
+#token "\*" << zzmore(); >>
+#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >>
+#token "~[\n\r\*]+" << zzmore(); >>
+
+#lexclass TOK_DEF_COMMENTS
+#token "\*/" << zzmode(PARSE_ENUM_FILE);
+ zzmore(); >>
+#token "\*" << zzmore(); >>
+#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >>
+#token "~[\n\r\*]+" << zzmore(); >>
+
+#lexclass TOK_DEF_CPP_COMMENTS
+#token "\n|\r|\r\n" << zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >>
+#token "~[\n\r]+" << zzskip(); >>
+
+#lexclass ACTION_CPP_COMMENTS
+#token "\n|\r|\r\n" << zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >>
+#token "~[\n\r]+" << zzmore(); >>
+
+#lexclass CPP_COMMENTS
+#token "\n|\r|\r\n" << zzline++; zzmode(START); zzskip(); DAWDLE; >>
+#token "~[\n\r]+" << zzskip(); >>
+
+#lexclass COMMENTS
+#token "\*/" << zzmode(START); zzskip(); >>
+#token "\*" << zzskip(); >>
+#token "\n|\r|\r\n" << zzline++; zzskip(); DAWDLE; >>
+#token "~[\n\r\*]+" << zzskip(); >>
+
+/*
+ * This lexical class accepts actions of type [..] and <<..>>
+ *
+ * It translates the following special items for C:
+ *
+ * $j --> "zzaArg(current zztasp, j)"
+ * $i.j --> "zzaArg(zztaspi, j)"
+ * $i.nondigit> "zzaArg(current zztasp, i).nondigit"
+ * $$ --> "zzaRet"
+ * $alnum --> "alnum" (used to ref parameters)
+ * $rule --> "zzaRet"
+ * $retval --> "_retv.retval" if > 1 return values else "_retv"
+ * $[token, text] --> "zzconstr_attr(token, text)"
+ * $[] --> "zzempty_attr()"
+ *
+ * It translates the following special items for C++:
+ * (attributes are now stored with 'Token' and $i's are only
+ * pointers to the Tokens. Rules don't have attributes now.)
+ *
+ * $j --> "_tbj" where b is the block level
+ * $i.j --> "_tij"
+ * $j->nondigit> "_tbj->nondigit"
+ * $$ --> "$$"
+ * $alnum --> "alnum" (used to ref parameters)
+ * $rule --> "$rule"
+ * $retval --> "_retv.retval" if > 1 return values else "_retv"
+ * $[token, text] --> invalid
+ * $[] --> invalid
+ *
+ * And, for trees:
+ *
+ * #0 --> "(*_root)"
+ * #i --> "zzastArg(i)"
+ * #[args] --> "zzmk_ast(zzastnew(), args)"
+ * #[] --> "zzastnew()"
+ * #( root, child1, ..., childn )
+ * --> "zztmake(root, child1, ...., childn, NULL)"
+ * #() --> "NULL"
+ *
+ * For C++, ...
+ *
+ * #0 --> "(*_root)"
+ * #i --> "_astbi" where b is the block level
+ * #alnum --> "alnum_ast" (used to ref #label)
+ * #[args] --> "new AST(args)"
+ * #[] --> "new AST"
+ * #( root, child1, ..., childn )
+ * --> "AST::tmake(root, child1, ...., childn, NULL)"
+ * #() --> "NULL"
+ *
+ * To escape,
+ *
+ * \] --> ]
+ * \) --> )
+ * \$ --> $
+ * \# --> #
+ *
+ * A stack is used to nest action terminators because they can be nested
+ * like crazy: << #[$[..],..] >>
+ */
+#lexclass ACTIONS
+#token Action "\>\>" << /* these do not nest */
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ NLATEXT[1] = ' ';
+ zzbegexpr[0] = ' ';
+ zzbegexpr[1] = ' ';
+ if ( zzbufovf ) {
+ err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));
+ }
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+/* MR1 in DLG action */
+/* MR1 Doesn't matter what kind of action it is - reset*/
+
+ tokenActionActive=0; /* MR1 */
+ >>
+#token Pred "\>\>?" << /* these do not nest */
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ NLATEXT[1] = ' ';
+ zzbegexpr[0] = '\0';
+ if ( zzbufovf ) {
+ err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));
+ };
+#ifdef __cplusplus__
+/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+#ifdef __STDC__
+/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+#ifdef __USE_PROTOS
+/* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+/* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred);
+#endif
+#endif
+#endif
+ >>
+#token PassAction "\]" << if ( topint() == ']' ) {
+ popint();
+ if ( istackempty() ) /* terminate action */
+ {
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ zzbegexpr[0] = ' ';
+ if ( zzbufovf ) {
+ err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));
+ }
+ }
+ else {
+ /* terminate $[..] and #[..] */
+ if ( GenCC ) zzreplstr("))");
+ else zzreplstr(")");
+ zzmore();
+ }
+ }
+ else if ( topint() == '|' ) { /* end of simple [...] */
+ popint();
+ zzmore();
+ }
+ else zzmore();
+ >>
+#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)"
+ <<
+ zzmore();
+ zzreplstr(inline_set(zzbegexpr+
+ strlen("consumeUntil(")));
+ >>
+#token "consumeUntil\( ~[\)]+ \)"
+ << zzmore(); >>
+#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >>
+#token "\>" << zzmore(); >>
+#token "$" << zzmore(); >>
+#token "$$" << if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}
+ else err("$$ use invalid in C++ mode"); >>
+
+#token "$\[\]" << if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}
+ else err("$[] use invalid in C++ mode"); >>
+#token "$\[" <<
+ pushint(']');
+ if ( !GenCC ) zzreplstr("zzconstr_attr(");
+ else err("$[..] use invalid in C++ mode");
+ zzmore();
+ >>
+#token "$[0-9]+" <<{
+ static char buf[100];
+ numericActionLabel=1; /* MR10 */
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("$i attrib ref too big");
+ set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",
+ BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"_t%d%s",
+ BlkLevel-1,zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ >>
+#token "$[0-9]+." <<{
+ static char buf[100];
+ numericActionLabel=1; /* MR10 */
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("$i.field attrib ref too big");
+ zzbegexpr[strlen(zzbegexpr)-1] = ' ';
+ set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",
+ BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"_t%d%s.",
+ BlkLevel-1,zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ >>
+#token "$[0-9]+.[0-9]+" <<{
+ static char buf[100];
+ static char i[20], j[20];
+ char *p,*q;
+ numericActionLabel=1; /* MR10 */
+ if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");
+ for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {
+ if ( q == &i[20] )
+ fatalFL("i of $i.j attrib ref too big",
+ FileStr[CurFile], zzline );
+ *q++ = *p;
+ }
+ *q = '\0';
+ for (p++, q= &j[0]; *p!='\0'; p++) {
+ if ( q == &j[20] )
+ fatalFL("j of $i.j attrib ref too big",
+ FileStr[CurFile], zzline );
+ *q++ = *p;
+ }
+ *q = '\0';
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);
+ else sprintf(buf,"_t%s%s",i,j);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ >>
+#token "$[_a-zA-Z][_a-zA-Z0-9]*"
+ <<{ static char buf[300]; LabelEntry *el;
+ zzbegexpr[0] = ' ';
+ if ( CurRule != NULL &&
+ strcmp(CurRule, &zzbegexpr[1])==0 ) {
+ if ( !GenCC ) zzreplstr("zzaRet");
+ }
+ else if ( CurRetDef != NULL &&
+ strmember(CurRetDef, &zzbegexpr[1])) {
+ if ( hasMultipleOperands( CurRetDef ) ) {
+ require (strlen(zzbegexpr)<=(size_t)285,
+ "$retval attrib ref too big");
+ sprintf(buf,"_retv.%s",&zzbegexpr[1]);
+ zzreplstr(buf);
+ }
+ else zzreplstr("_retv");
+ }
+ else if ( CurParmDef != NULL &&
+ strmember(CurParmDef, &zzbegexpr[1])) {
+ ;
+ }
+ else if ( Elabel==NULL ) {
+ { err("$-variables in actions outside of rules are not allowed"); }
+ } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {
+/* MR10 */
+/* MR10 */ /* element labels might exist without an elem when */
+/* MR10 */ /* it is a forward reference (to a rule) */
+/* MR10 */
+/* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )
+/* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }
+/* MR10 */
+/* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {
+/* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs");
+/* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")");
+/* MR10 */ };
+/* MR10 */
+/* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */
+/* MR10 */ /* element labels contain pointer to the owners node */
+/* MR10 */
+/* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) {
+/* MR10 */ list_add(&CurActionLabels,el);
+/* MR10 */ };
+ }
+ else
+ warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));
+ }
+ zzmore();
+ >>
+#token "#0" << zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >>
+#token "#\[\]" << if ( GenCC ) {
+ if (NewAST) zzreplstr("(newAST)");
+ else zzreplstr("(new AST)");}
+ else {zzreplstr("zzastnew()");} zzmore();
+ chkGTFlag();
+ >>
+#token "#\(\)" << zzreplstr("NULL"); zzmore(); chkGTFlag(); >>
+#token "#[0-9]+" <<{
+ static char buf[100];
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("#i AST ref too big");
+ if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);
+ chkGTFlag();
+ }
+ >>
+
+/* MR14 Arpad Beszedes 26-May-98
+ Add support for #line directives when antlr source is pre-processed
+ #lexclass ACTIONS
+*/
+
+#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)"
+ <<
+ zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();
+ getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);
+ >>
+
+#token "#line ~[\n\r]* (\n|\r|\r\n)"
+ <<
+ zzline++; zzmore();
+ >>
+
+/* MR14 end of a block to support #line in antlr source code */
+
+#token "#[_a-zA-Z][_a-zA-Z0-9]*"
+ <<
+ if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||
+ strcmp(zzbegexpr, "#if")==0 ||
+ strcmp(zzbegexpr, "#else")==0 ||
+ strcmp(zzbegexpr, "#endif")==0 ||
+ strcmp(zzbegexpr, "#ifndef")==0 ||
+ strcmp(zzbegexpr, "#define")==0 ||
+ strcmp(zzbegexpr, "#pragma")==0 ||
+ strcmp(zzbegexpr, "#undef")==0 ||
+ strcmp(zzbegexpr, "#import")==0 ||
+ strcmp(zzbegexpr, "#line")==0 ||
+ strcmp(zzbegexpr, "#include")==0 ||
+ strcmp(zzbegexpr, "#error")==0) )
+ {
+ static char buf[100];
+ sprintf(buf, "%s_ast", zzbegexpr+1);
+/* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));
+ zzreplstr(buf);
+ chkGTFlag();
+ }
+ zzmore();
+ >>
+#token "#\[" <<
+ pushint(']');
+ if ( GenCC ) {
+ if (NewAST) zzreplstr("(newAST(");
+ else zzreplstr("(new AST("); }
+ else zzreplstr("zzmk_ast(zzastnew(),");
+ zzmore();
+ chkGTFlag();
+ >>
+#token "#\(" <<
+ pushint('}');
+ if ( GenCC ) {
+ if (tmakeInParser) {
+ zzreplstr("tmake(");
+ }
+ else {
+ zzreplstr("ASTBase::tmake(");
+ }
+ }
+ else {
+ zzreplstr("zztmake(");
+ }
+ zzmore();
+ chkGTFlag();
+ >>
+#token "#" << zzmore(); >>
+#token "\)" <<
+ if ( istackempty() )
+ zzmore();
+ else if ( topint()==')' ) {
+ popint();
+ }
+ else if ( topint()=='}' ) {
+ popint();
+ /* terminate #(..) */
+ zzreplstr(", NULL)");
+ }
+ zzmore();
+ >>
+#token "\[" <<
+ pushint('|'); /* look for '|' to terminate simple [...] */
+ zzmore();
+ >>
+#token "\(" <<
+ pushint(')');
+ zzmore();
+ >>
+
+#token "\\\]" << zzreplstr("]"); zzmore(); >>
+#token "\\\)" << zzreplstr(")"); zzmore(); >>
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+/* MR1 in DLG action */
+
+#token "\\>" << if (! tokenActionActive) zzreplstr(">"); /* MR1 */
+ zzmore(); /* MR1 */
+ >> /* MR1 */
+
+
+#token "'" << zzmode(ACTION_CHARS); zzmore();>>
+#token "\"" << zzmode(ACTION_STRINGS); zzmore();>>
+#token "\\$" << zzreplstr("$"); zzmore(); >>
+#token "\\#" << zzreplstr("#"); zzmore(); >>
+#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >>
+#token "\\~[\]\)>$#]" << zzmore(); >> /* escaped char, always ignore */
+#token "/" << zzmore(); >>
+#token "/\*" << zzmode(ACTION_COMMENTS); zzmore(); >>
+#token "\*/" << warn("Missing /*; found dangling */ in action"); zzmore(); >>
+#token "//" << zzmode(ACTION_CPP_COMMENTS); zzmore(); >>
+#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >>
+
+#lexclass START
+#token "[\t\ ]+" << zzskip(); >> /* Ignore White */
+#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */
+#token "\[" << zzmode(ACTIONS); zzmore();
+ istackreset();
+ pushint(']'); >>
+#token "\<\<" << action_file=CurFile; action_line=zzline;
+ zzmode(ACTIONS); zzmore();
+ list_free(&CurActionLabels,0); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ istackreset();
+ pushint('>'); >>
+#token "\"" << zzmode(STRINGS); zzmore(); >>
+#token "/\*" << zzmode(COMMENTS); zzskip(); >>
+#token "\*/" << warn("Missing /*; found dangling */"); zzskip(); >>
+#token "//" << zzmode(CPP_COMMENTS); zzskip(); >>
+
+/* MR14 Arpad Beszedes 26-May-98
+ Add support for #line directives when antlr source is pre-processed
+ #lexclass START
+*/
+
+#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)"
+ <<
+ zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();
+ getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);
+ >>
+
+#token "#line ~[\n\r]* (\n|\r|\r\n)"
+ <<
+ zzline++; zzmore();
+ >>
+
+/* MR14 end of a block to support #line in antlr source code */
+
+/* */
+/* 8-Apr-97 Regularize escape sequence for ">>" */
+/* appearing in string literals */
+/* */
+
+#token "\>\>" << warn("Missing <<; found dangling \>\>"); zzskip(); >> /* MR1 */
+#token WildCard "."
+#token "\@" <<FoundException = 1; /* MR6 */
+ FoundAtOperator = 1;>> /* MR6 */
+#token Eof "@"
+ << /* L o o k F o r A n o t h e r F i l e */
+ {
+ FILE *new_input;
+ new_input = NextFile();
+ if ( new_input == NULL ) { NLA=Eof; return; }
+ fclose( input );
+ input = new_input;
+ zzrdstream( input );
+ zzskip(); /* Skip the Eof (@) char i.e continue */
+ }
+ >>
+
+#token LABEL
+
+#errclass "grammar-element" { element }
+#errclass "meta-symbol" { "\}" "!" ";" "\|" "\~" "^" "\)" }
+
+#token Pragma "{\\}#pragma" /* MR21 */
+#token FirstSetSymbol "{\\}#FirstSetSymbol" /* MR21 */
+/*
+ * Get a grammar -- Build a list of rules like:
+ *
+ * o-->Rule1--o
+ * |
+ * o-->Rule2--o
+ * |
+ * ...
+ * |
+ * o-->RuleN--o
+ */
+
+/* rule grammar */
+
+grammar : <<Graph g;>>
+ ( "{\\}#header" Action /* MR13 */
+ <<
+ if ( HdrAction==NULL ) {
+ HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(HdrAction!=NULL, "rule grammar: cannot allocate header action");
+ strcpy(HdrAction, LATEXT(1));
+ }
+ else warn("additional #header statement ignored");
+ >>
+ | "{\\}#first" Action
+ <<
+ if ( FirstAction==NULL ) {
+ FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(FirstAction!=NULL, "rule grammar: cannot allocate #first action");
+ strcpy(FirstAction, LATEXT(1));
+ } else {
+ warn("additional #first statement ignored");
+ };
+ >>
+
+ | "{\\}#parser" QuotedTerm
+ <<
+ if ( GenCC ) {
+ warn("#parser meta-op incompatible with -CC; ignored");
+ }
+ else {
+ if ( strcmp(ParserName,"zzparser")==0 ) {
+ ParserName=StripQuotes(mystrdup(LATEXT(1)));
+ if ( RulePrefix[0]!='\0' )
+ {
+ warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored");
+ RulePrefix[0]='\0';
+ }
+ }
+ else warn("additional #parser statement ignored");
+ }
+ >>
+ | "{\\}#tokdefs" QuotedTerm
+ <<{
+ char *fname;
+ zzantlr_state st; FILE *f; struct zzdlg_state dst;
+ UserTokenDefsFile = mystrdup(LATEXT(1));
+ zzsave_antlr_state(&st);
+ zzsave_dlg_state(&dst);
+ fname = mystrdup(LATEXT(1));
+ f = fopen(StripQuotes(fname), "r");
+ if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));}
+ else {
+ ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE);
+ UserDefdTokens = 1;
+ }
+ zzrestore_antlr_state(&st);
+ zzrestore_dlg_state(&dst);
+ }>>
+ )*
+ ( Action
+ <<{
+ UserAction *ua = newUserAction(LATEXT(1));
+ ua->file = action_file; ua->line = action_line;
+ if ( class_nest_level>0 ) list_add(&class_before_actions, ua);
+ else list_add(&BeforeActions, ua);
+ }>>
+ | laction
+ | lmember /* MR1 */
+ | lprefix /* MR1 */
+ | aLexclass
+ | token
+ | error
+ | tclass
+ | aPred /* MR11 */
+ | default_exception_handler
+ | class_def
+ | "\}"
+ <<
+ if ( class_nest_level==0 )
+ warn("missing class definition for trailing '}'");
+ class_nest_level--;
+ >>
+ )*
+
+ rule <<g=$3; SynDiag = (Junction *) $3.left;>>
+ ( rule
+
+ <<if ( $1.left!=NULL ) {
+ g.right = NULL;
+
+/* MR21a */ /* Avoid use of a malformed graph when CannotContinue */
+/* MR21a */ /* is already set */
+/* MR21a */
+/* MR21a */ if (! (CannotContinue && g.left == NULL)) {
+/* MR21a */ g = Or(g, $1);
+/* MR21a */ }
+/* MR21a */ }
+ >>
+
+ | aLexclass
+ | token
+ | error
+ | tclass
+ | aPred /* MR11 */
+ | class_def
+ | "\}"
+ <<
+ if ( class_nest_level==0 )
+ warn("missing class definition for trailing '}'");
+ class_nest_level--;
+ >>
+ )*
+ ( Action
+ <<{
+ UserAction *ua = newUserAction(LATEXT(1));
+ ua->file = action_file; ua->line = action_line;
+ if ( class_nest_level>0 ) list_add(&class_after_actions, ua);
+ else list_add(&AfterActions, ua);
+ }>>
+ | laction
+ | lmember /* MR1 */
+ | lprefix /* MR1 */
+ | error
+ | tclass
+ | class_def
+ | aPred /* MR11 */
+ | "\}"
+ <<
+ if ( class_nest_level==0 )
+ warn("missing class definition for trailing '}'");
+ class_nest_level--;
+ >>
+ )*
+ Eof
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule class_def */
+
+class_def
+ : <<int go=1; char name[MaxRuleName+1];>>
+ "class"
+ ( NonTerminal <<if(go) strncpy(name,LATEXT(1),MaxRuleName);>>
+ | TokenTerm <<if(go) strncpy(name,LATEXT(1),MaxRuleName);>>
+ )
+ <<
+ if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0
+ && GenCC ) {
+ err("only one grammar class allowed in this release");
+ go = 0;
+ }
+ else strcpy(CurrentClassName, name);
+ >>
+ <<if ( !GenCC ) { err("class meta-op used without C++ option"); }>>
+
+/* MR10 */ (~ "\{"
+/* MR10 */ <<if (ClassDeclStuff == NULL) {
+/* MR10 */ ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char));
+/* MR10 */ };
+/* MR10 */ strncat(ClassDeclStuff," ",MaxClassDeclStuff);
+/* MR10 */ strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff);
+/* MR22 */ do {
+/* MR22 */ if (0 == strcmp(LATEXT(1),"public")) break;
+/* MR22 */ if (0 == strcmp(LATEXT(1),"private")) break;
+/* MR22 */ if (0 == strcmp(LATEXT(1),"protected")) break;
+/* MR22 */ if (0 == strcmp(LATEXT(1),"virtual")) break;
+/* MR22 */ if (0 == strcmp(LATEXT(1),",")) break;
+/* MR22 */ if (0 == strcmp(LATEXT(1),":")) break;
+/* MR22 */ if (BaseClassName != NULL) break;
+/* MR22 */ BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char));
+/* MR22 */ require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name");
+/* MR22 */ strcpy(BaseClassName,LATEXT(1));
+/* MR22 */ } while (0);
+/* MR10 */ >>
+/* MR10 */ )*
+
+ "\{"
+ <<
+ no_classes_found = 0;
+ if ( class_nest_level>=1 ) {warn("cannot have nested classes");}
+ else class_nest_level++;
+ >>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/*
+ * Build -o-->o-R-o-->o- where -o-R-o- is the block from rule 'block'.
+ * Construct the RuleBlk front and EndRule node on the end of the
+ * block. This is used to add FOLLOW pointers to the rule end. Add the
+ * new rule name to the Rname hash table and sets its rulenum.
+ * Store the parameter definitions if any are found.
+ *
+ * Note that locks are required on the RuleBlk and EndRule nodes to thwart
+ * infinite recursion.
+ *
+ * Return the left graph pointer == NULL to indicate error/dupl rule def.
+ */
+
+/* rule rule */
+
+rule : <<
+
+ ExceptionGroup *eg;
+ RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e;
+ set toksrefd, rulesrefd;
+ char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL;
+ CurExGroups = NULL;
+ CurElementLabels = NULL;
+ CurAstLabelsInActions = NULL; /* MR27 */
+ /* We want a new element label hash table for each rule */
+ if ( Elabel!=NULL ) killHashTable(Elabel);
+ Elabel = newHashTable();
+ attribsRefdFromAction = empty;
+ >>
+ NonTerminal
+ <<q=NULL;
+ if ( hash_get(Rname, LATEXT(1))!=NULL ) {
+ err(eMsg1("duplicate rule definition: '%s'",LATEXT(1)));
+ CannotContinue=TRUE;
+ }
+ else
+ {
+ q = (RuleEntry *)hash_add(Rname,
+ LATEXT(1),
+ (Entry *)newRuleEntry(LATEXT(1)));
+ CurRule = q->str;
+ }
+ CurRuleNode = q;
+ f = CurFile; l = zzline;
+ NumRules++;
+ >>
+ { "!" <<if ( q!=NULL ) q->noAST = TRUE;>> }
+ { <<;>>
+ {"\<"}
+ PassAction
+ << pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(pdecl!=NULL, "rule rule: cannot allocate param decl");
+ strcpy(pdecl, LATEXT(1));
+ CurParmDef = pdecl;
+ >>
+ }
+ { "\>"
+ PassAction
+ << ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(ret!=NULL, "rule rule: cannot allocate ret type");
+ strcpy(ret, LATEXT(1));
+ CurRetDef = ret;
+ >>
+ }
+ { QuotedTerm <<if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1));>> }
+ <<
+ if ( GenEClasseForRules && q!=NULL ) {
+ e = newECnode;
+ require(e!=NULL, "cannot allocate error class node");
+ if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);}
+ else a = q->egroup;
+ if ( Tnum( a ) == 0 )
+ {
+ e->tok = addTname( a );
+ list_add(&eclasses, (char *)e);
+ if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);
+ /* refers to itself */
+ list_add(&(e->elist), mystrdup(q->str));
+ }
+ else {
+ warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a));
+ if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);
+ free((char *)e);
+ }
+ }
+ >>
+ <<BlkLevel++;
+ if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");
+/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;
+/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ >>
+
+ ":" <<inAlt=1;>>
+ block[&toksrefd, &rulesrefd]
+ <<r = makeBlk($7,0, NULL /* pFirstSetSymbol */ );
+ CurRuleBlk = (Junction *)r.left;
+ CurRuleBlk->blockid = CurBlockID;
+ CurRuleBlk->jtype = RuleBlk;
+ if ( q!=NULL ) CurRuleBlk->rname = q->str;
+ CurRuleBlk->file = f;
+ CurRuleBlk->line = l;
+ CurRuleBlk->pdecl = pdecl;
+ CurRuleBlk->ret = ret;
+ CurRuleBlk->lock = makelocks();
+ CurRuleBlk->pred_lock = makelocks();
+ CurRuleBlk->tokrefs = toksrefd;
+ CurRuleBlk->rulerefs = rulesrefd;
+ p = newJunction(); /* add EndRule Node */
+ ((Junction *)r.right)->p1 = (Node *)p;
+ r.right = (Node *) p;
+ p->jtype = EndRule;
+ p->lock = makelocks();
+ p->pred_lock = makelocks();
+ CurRuleBlk->end = p;
+ if ( q!=NULL ) q->rulenum = NumRules;
+ $7 = r;
+ >>
+ <<
+ /* MR23 */ CurBlockID_array[BlkLevel] = (-1);
+ /* MR23 */ CurAltNum_array[BlkLevel] = (-1);
+ --BlkLevel;
+ >>
+ <<altFixup();leFixup();egFixup();>> /* MR7 */
+ ";" <<inAlt=0;>>
+ { Action
+ << a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule rule: cannot allocate error action");
+ strcpy(a, LATEXT(1));
+ CurRuleBlk->erraction = a;
+ >>
+ }
+ ( exception_group > [eg]
+ <<if ( eg!=NULL ) {
+ list_add(&CurExGroups, (void *)eg);
+ if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1;
+ }
+ >>
+ )*
+ <<if ( q==NULL ) $0.left = NULL; else $0 = $7;>>
+ <<CurRuleBlk->exceptions = CurExGroups;>>
+ <<CurRuleBlk->el_labels = CurElementLabels;>>
+ <<CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions;>> /* MR27 */
+ <<CurRuleNode = NULL;>> /* MR27 Moved */
+ ;
+ <<CannotContinue=TRUE;>>
+
+/*
+ * pragma : "{\\}#pragma" "dup\-labeled\-tokens"
+ * <<Pragma_DupLabeledTokens=1;>>
+ * ;
+ */
+
+/* rule laction */
+
+laction : <<char *a;>>
+
+ "{\\}#lexaction"
+ Action
+ <<
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule laction: cannot allocate action");
+ strcpy(a, LATEXT(1));
+ list_add(&LexActions, a);
+ >>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */
+/* MR1 */
+
+/* rule lmember */
+
+lmember: <<char *a;>> /* MR1 */
+
+/* MR1 */ "{\\}#lexmember"
+/* MR1 */ Action
+/* MR1 */ <<
+/* MR1 */ if (! GenCC) {
+/* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header");
+/* MR1 */ } else {
+/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+/* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action");
+/* MR1 */ strcpy(a, LATEXT(1));
+/* MR1 */ list_add(&LexMemberActions, a);
+/* MR1 */ };
+/* MR1 */ >>
+/* MR1 */ ;
+/* MR1 */ <<CannotContinue=TRUE;>>
+
+/* rule lprefix */
+
+lprefix: <<char *a;>> /* MR1 */
+
+/* MR1 */ "{\\}#lexprefix"
+/* MR1 */ Action
+/* MR1 */ <<
+/* MR1 */ if (! GenCC) {
+/* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header");
+/* MR1 */ } else {
+/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+/* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action");
+/* MR1 */ strcpy(a, LATEXT(1));
+/* MR1 */ list_add(&LexPrefixActions, a);
+/* MR1 */ };
+/* MR1 */ >>
+/* MR1 */ ;
+/* MR1 */ <<CannotContinue=TRUE;>>
+
+/*
+ * #pred upper <<isupper()>>? predicate literal
+ * #pred lower <<islower()>>? predicate literal
+ * #pred up_or_low upper || lower predicate expression
+ * concealed interdependence
+ * #pred up_or_low_2 <<isletter()>>? A || B predicate literal equals predicate expr
+ * analyze using lower||upper
+ * generate using isLetter()
+ */
+
+/* rule aPref */
+
+aPred: <<PredEntry *predEntry=NULL;
+ char *name=NULL;
+ Predicate *predExpr=NULL;
+ char *predLiteral=NULL;
+ int save_file;
+ int save_line;
+ int predExprPresent=0;
+ >>
+
+ "{\\}#pred"
+
+ <<
+ MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */
+ >>
+
+ /* used to allow NonTerminal but it caused problems
+ when a rule name immediately followed a #pred statement */
+
+ TokenTerm <<name=mystrdup(LATEXT(1));>>
+
+ <<
+ /* don't free - referenced in predicates */
+
+ CurPredName=(char *)calloc(1,strlen(name) + 10);
+ strcat(CurPredName,"#pred ");
+ strcat(CurPredName,name);
+
+ predEntry=(PredEntry *) hash_get(Pname,name);
+ if (predEntry != NULL) {
+ warnFL(eMsg1("#pred %s previously defined - ignored",name),
+ FileStr[action_file],action_line);
+ name=NULL;
+ };
+ >>
+
+ (
+
+ Pred <<predLiteral=mystrdup(LATEXT(1));
+ save_line=action_line;
+ save_file=action_file;
+ >>
+
+ {
+ predOrExpr>[predExpr] <<predExprPresent=1;>>
+ }
+
+ <<if (predLiteral != NULL && name != NULL) {
+
+ /*
+ * predExpr may be NULL due to syntax errors
+ * or simply omitted by the user
+ */
+
+ predEntry=newPredEntry(name);
+ predEntry->file=save_file;
+ predEntry->line=save_line;
+ predExpr=MR_predFlatten(predExpr);
+ predEntry->predLiteral=predLiteral;
+ if (! predExprPresent || predExpr == NULL) {
+ predExpr=new_pred();
+ predExpr->expr=predLiteral;
+ predExpr->source=newActionNode();
+ predExpr->source->action=predExpr->expr;
+ predExpr->source->rname=CurPredName;
+ predExpr->source->line=action_line;
+ predExpr->source->file=action_file;
+ predExpr->source->is_predicate=1;
+ predExpr->k=predicateLookaheadDepth(predExpr->source);
+ };
+ predEntry->pred=predExpr;
+ hash_add(Pname,name,(Entry *)predEntry);
+ predExpr=NULL;
+ };
+ predicate_free(predExpr);
+ >>
+
+ |
+ <<save_line=zzline; save_file=CurFile;>>
+
+ predOrExpr>[predExpr]
+
+ <<if (predExpr != NULL && name != NULL) {
+ predEntry=newPredEntry(name);
+ predEntry->file=CurFile;
+ predEntry->line=zzline;
+ predExpr=MR_predFlatten(predExpr);
+ predEntry->pred=predExpr;
+ hash_add(Pname,name,(Entry *)predEntry);
+ predExpr=NULL;
+ };
+ predicate_free(predExpr);
+ >>
+ )
+ {";"}
+;
+
+/* fail */
+
+<<predicate_free(predExpr);
+>>
+
+/* rule predOrExpr */
+
+predOrExpr>[Predicate *result] :
+ <<Predicate *ORnode;
+ Predicate *predExpr;
+ Predicate **tail=NULL;
+ >>
+ predAndExpr>[predExpr]
+ <<
+ ORnode=new_pred();
+ ORnode->expr=PRED_OR_LIST;
+ if (predExpr != NULL) {
+ ORnode->down=predExpr;
+ tail=&predExpr->right;
+ };
+ >>
+ ( "\|\|" predAndExpr>[predExpr]
+ <<
+ if (predExpr != NULL) {
+ *tail=predExpr;
+ tail=&predExpr->right;
+ };
+ >>
+ )*
+ <<
+ $result=ORnode;
+ ORnode=NULL;
+ >>
+;
+
+/* fail */
+
+<<predicate_free(ORnode);>>
+
+/* rule predAndExpr */
+
+predAndExpr>[Predicate *result] :
+ <<Predicate *ANDnode;
+ Predicate *predExpr;
+ Predicate **tail=NULL;
+ >>
+ predPrimary>[predExpr]
+ <<
+ ANDnode=new_pred();
+ ANDnode->expr=PRED_AND_LIST;
+ if (predExpr != NULL) {
+ ANDnode->down=predExpr;
+ tail=&predExpr->right;
+ };
+ >>
+ ( "&&" predPrimary>[predExpr]
+ <<
+ if (predExpr != NULL) {
+ *tail=predExpr;
+ tail=&predExpr->right;
+ };
+ >>
+ )*
+ <<
+ $result=ANDnode;
+ ANDnode=NULL;
+ >>
+;
+
+/* fail */
+
+<<predicate_free(ANDnode);>>
+
+
+/* rule predPrimary */
+
+predPrimary>[Predicate *result] :
+ <<
+ char *name=NULL;
+ PredEntry *predEntry=NULL;
+ Predicate *predExpr=NULL;
+ >>
+
+ TokenTerm <<name=mystrdup(LATEXT(1));>>
+
+ <<
+ predEntry=(PredEntry *) hash_get(Pname,name);
+ if (predEntry == NULL) {
+ warnFL(eMsg1("no previously defined #pred with name \"%s\"",name),
+ FileStr[CurFile],zzline);
+ name=NULL;
+ $result=NULL;
+ } else {
+ predExpr=predicate_dup(predEntry->pred);
+ predExpr->predEntry=predEntry;
+ $result=predExpr;
+ };
+ >>
+
+ | "\(" predOrExpr>[predExpr] "\)"
+ <<
+ $result=predExpr;
+ >>
+
+ | "!" predPrimary>[predExpr]
+ <<
+ predExpr->inverted=!predExpr->inverted;
+ $result=predExpr;
+ >>
+;
+
+/* fail */ <<
+ predicate_free(predExpr);
+ >>
+
+/* rule aLexclass */
+
+aLexclass: "{\\}#lexclass" TokenTerm <<lexclass(mystrdup(LATEXT(1)));>>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule error */
+
+error : <<char *t=NULL; ECnode *e; int go=1; TermEntry *p;>>
+ "{\\}#errclass"
+ (<<;>> TokenTerm <<t=mystrdup(LATEXT(1));>>
+ | QuotedTerm <<t=mystrdup(LATEXT(1));>>
+ )
+ <<e = newECnode;
+ require(e!=NULL, "cannot allocate error class node");
+ e->lexclass = CurrentLexClass;
+ if ( Tnum( (t=StripQuotes(t)) ) == 0 )
+ {
+ if ( hash_get(Texpr, t) != NULL )
+ warn(eMsg1("errclass name conflicts with regular expression '%s'",t));
+ e->tok = addTname( t );
+ set_orel(e->tok, &imag_tokens);
+ require((p=(TermEntry *)hash_get(Tname, t)) != NULL,
+ "hash table mechanism is broken");
+ p->classname = 1; /* entry is errclass name, not token */
+ list_add(&eclasses, (char *)e);
+ }
+ else
+ {
+ warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t));
+ free( (char *)e );
+ go=0;
+ }
+ >>
+ "\{"
+ ( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>>
+ | TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>>
+ | QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>>
+ )
+ <<if ( go ) list_add(&(e->elist), t);>>
+ (
+ ( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>>
+ | TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>>
+ | QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>>
+ )
+ <<if ( go ) list_add(&(e->elist), t);>>
+ )*
+ "\}"
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule tclass */
+
+tclass : <<char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm;>>
+ <<char *akaString=NULL; int save_file; int save_line;>>
+ <<char *totext=NULL; >>
+ "{\\}#tokclass" TokenTerm <<t=mystrdup(LATEXT(1));>>
+ <<e = newTCnode;
+ require(e!=NULL, "cannot allocate token class node");
+ e->lexclass = CurrentLexClass;
+ if ( Tnum( t ) == 0 )
+ {
+ e->tok = addTname( t );
+ set_orel(e->tok, &imag_tokens);
+ set_orel(e->tok, &tokclasses);
+ require((p=(TermEntry *)hash_get(Tname, t)) != NULL,
+ "hash table mechanism is broken");
+ p->classname = 1; /* entry is class name, not token */
+ p->tclass = e; /* save ptr to this tclass def */
+ list_add(&tclasses, (char *)e);
+ }
+ else
+ {
+ warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t));
+ free( (char *)e );
+ go=0;
+ }
+ >>
+/* MR23 */ {
+/* MR23 */ "\("
+/* MR23 */ QuotedTerm
+/* MR23 */ <<akaString=mystrdup(StripQuotes(LATEXT(1)));
+/* MR11 */ save_file=CurFile;save_line=zzline;
+/* MR23 */ >>
+/* MR23 */ "\)"
+/* MR23 */ }
+/* MR23 */
+/* MR23 */
+/* MR23 */ <<
+/* MR23 */ if (p!= NULL && akaString != NULL) {
+/* MR23 */ if (p->akaString != NULL) {
+/* MR23 */ if (strcmp(p->akaString,akaString) != 0) {
+/* MR23 */ warnFL(eMsg2("this #tokclass statement conflicts with a previous #tokclass %s(\"%s\") statement",
+/* MR23 */ t,p->akaString),
+/* MR23 */ FileStr[save_file],save_line);
+/* MR23 */ };
+/* MR23 */ } else {
+/* MR23 */ p->akaString=akaString;
+/* MR23 */ };
+/* MR23 */ };
+/* MR23 */ >>
+
+ "\{"
+ (
+ ( TokenTerm
+ <<if ( go ) {
+ term = (TermEntry *) hash_get(Tname, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ go = 0;
+ }
+ else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));}
+ }>>
+
+ {
+ ".."
+ TokenTerm
+
+ <<if ( go ) {
+ toterm = (TermEntry *) hash_get(Tname, LATEXT(1));
+ if ( toterm==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ go = 0;
+ } else {
+ totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1));
+ }
+ }
+ >>
+ }
+
+ | QuotedTerm
+ <<if ( go ) {
+ term = (TermEntry *) hash_get(Texpr, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ go = 0;
+ }
+ else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));}
+ }>>
+ )
+ <<if ( go ) {
+ if (totext == NULL) {
+ list_add(&(e->tlist), t);
+ } else {
+ list_add(&(e->tlist),"..");
+ list_add(&(e->tlist),t);
+ list_add(&(e->tlist),totext);
+ }
+ totext=NULL;
+ }
+ >>
+ )+ // MR15 Manfred Kogler - forbid empty #tokclass sets (was "+")
+ "\}"
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule token */
+
+token : <<char *t=NULL, *e=NULL, *a=NULL; int tnum=0;>>
+ <<char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0;>> /* MR11 */
+ "{\\}#token"
+
+/* MR1 10-Apr-97 MR1 Allow shift right operator in DLG actions */
+/* MR1 Danger when parser feedback to lexer */
+/* MR1 */
+
+ <<tokenActionActive=1;>> /* MR1 */
+ { TokenTerm <<t=mystrdup(LATEXT(1));>>
+
+/* MR11 */ {
+/* MR11 */ "\("
+/* MR11 */ QuotedTerm
+/* MR11 */ <<akaString=mystrdup(StripQuotes(LATEXT(1)));
+/* MR11 */ save_file=CurFile;save_line=zzline;
+/* MR11 */ >>
+/* MR11 */ "\)"
+/* MR11 */ }
+
+ { "=" "[0-9]+" /* define the token type number */
+ <<tnum = atoi(LATEXT(1));>>
+ }
+ }
+ { QuotedTerm <<e=mystrdup(LATEXT(1));>> }
+ { Action
+ <<
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule token: cannot allocate action");
+ strcpy(a, LATEXT(1));
+ >>
+ }
+
+ { ";" } /* MR11 */
+
+ <<chkToken(t, e, a, tnum);>>
+
+ <<if (t != NULL) {
+ te=(TermEntry *)hash_get(Tname,t);
+ if (te != NULL && akaString != NULL) {
+ if (te->akaString != NULL) {
+ if (strcmp(te->akaString,akaString) != 0) {
+ warnFL(eMsg2("this #token statement conflicts with a previous #token %s(\"%s\") statement",
+ t,te->akaString),
+ FileStr[save_file],save_line);
+ };
+ } else {
+ te->akaString=akaString;
+ };
+ };
+ };
+ >>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule block */
+
+block[set *toksrefd, set *rulesrefd]
+ : <<
+ Graph g, b;
+ set saveblah;
+ int saveinalt = inAlt;
+ ExceptionGroup *eg;
+ *$toksrefd = empty;
+ *$rulesrefd = empty;
+ set_clr(AST_nodes_refd_in_actions);
+ CurBlockID++;
+/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;
+ CurAltNum = 1;
+/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ saveblah = attribsRefdFromAction;
+ attribsRefdFromAction = empty;
+ >>
+
+ alt[toksrefd,rulesrefd] <<b = g = $1;>>
+
+ <<
+ if ( ((Junction *)g.left)->p1->ntype == nAction )
+ {
+ ActionNode *actionNode=(ActionNode *)
+ ( ( (Junction *)g.left) ->p1);
+ if (!actionNode->is_predicate )
+ {
+ actionNode->init_action = TRUE;
+/* MR12c */ if (actionNode->noHoist) {
+/* MR12c */ errFL("<<nohoist>> appears as init-action - use <<>> <<nohoist>>",
+/* MR12c */ FileStr[actionNode->file],actionNode->line);
+/* MR12c */ };
+ }
+ }
+ ((Junction *)g.left)->blockid = CurBlockID;
+ >>
+
+ ( exception_group > [eg]
+ <<
+ if ( eg!=NULL ) {
+/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/
+/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/
+ list_add(&CurExGroups, (void *)eg);
+ }
+ >>
+ )*
+ <<CurAltNum++;
+/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ >>
+
+ ( "\|" <<inAlt=1;>>
+ alt[toksrefd,rulesrefd] <<g = Or(g, $2);>>
+ <<
+ ((Junction *)g.left)->blockid = CurBlockID;
+ >>
+
+ ( exception_group > [eg]
+ <<
+ if ( eg!=NULL ) {
+/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/
+/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/
+ list_add(&CurExGroups, (void *)eg);
+ }
+ >>
+ )*
+
+ <<CurAltNum++;
+/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ >>
+
+ )*
+ <<$0 = b;>>
+ <<attribsRefdFromAction = saveblah; inAlt = saveinalt;>>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule alt */
+
+alt[set *toksrefd, set *rulesrefd]
+ : <<int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif;
+ int first_on_line = 1, use_def_MT_handler = 0;
+ g.left=NULL; g.right=NULL;
+
+ CurAltStart = NULL;
+ elems = empty;
+ inAlt = 1;
+ >>
+ { "\@" /* handle MismatchedToken signals with default handler */
+ <<use_def_MT_handler = 1;>>
+ }
+
+ ( <<;>> /* MR9 Removed unreferenced variable "tok" */
+ { <<old_not=0;>> "\~" <<old_not=1;>> }
+ element[old_not, first_on_line, use_def_MT_handler] > [node]
+ <<if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0;>>
+ <<
+ if ( $2.left!=NULL ) {
+ g = Cat(g, $2);
+ n++;
+ if ( node!=NULL ) {
+ if ( node->ntype!=nAction ) e_num++;
+ /* record record number of all rule and token refs */
+ if ( node->ntype==nToken ) {
+ TokNode *tk = (TokNode *)((Junction *)$2.left)->p1;
+ tk->elnum = e_num;
+ set_orel(e_num, &elems);
+ }
+ else if ( node->ntype==nRuleRef ) {
+ RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1;
+ rn->elnum = e_num;
+ set_orel(e_num, $rulesrefd);
+ }
+ }
+ }
+ >>
+ )*
+ <<if ( n == 0 ) g = emptyAlt();
+ $0 = g;
+ /* We want to reduce number of LT(i) calls and the number of
+ * local attribute variables in C++ mode (for moment, later we'll
+ * do for C also). However, if trees are being built, they
+ * require most of the attrib variables to create the tree nodes
+ * with; therefore, we gen a token ptr for each token ref in C++
+ */
+ if ( GenCC && !GenAST )
+ {
+ /* This now free's the temp set -ATG 5/6/95 */
+ set temp;
+ temp = set_and(elems, attribsRefdFromAction);
+ set_orin($toksrefd, temp);
+ set_free(temp);
+ }
+ else set_orin($toksrefd, elems);
+ if ( GenCC ) {
+ dif = set_dif(attribsRefdFromAction, elems);
+ if ( set_deg(dif)>0 )
+ err("one or more $i in action(s) refer to non-token elements");
+ set_free(dif);
+ }
+ set_free(elems);
+ set_free(attribsRefdFromAction);
+ inAlt = 0;
+ >>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule element_label */
+
+element_label > [LabelEntry *label]
+ : <<TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab;>>
+ LABEL <<lab = mystrdup(LATEXT(1));>>
+ <<
+ UsedNewStyleLabel = 1;
+ if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i");
+ t = (TermEntry *) hash_get(Tname, lab);
+ if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab);
+ if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab);
+ if ( t!=NULL ) {
+ err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab));
+ $label = NULL;
+ }
+ else if ( r!=NULL ) {
+ err(eMsg1("label definition clashes with rule definition: '%s'", lab));
+ $label = NULL;
+ }
+ else {
+ /* we don't clash with anybody else */
+ l = (LabelEntry *) hash_get(Elabel, lab);
+ if ( l==NULL ) { /* ok to add new element label */
+ l = (LabelEntry *)hash_add(Elabel,
+ lab,
+ (Entry *)newLabelEntry(lab));
+ /* add to list of element labels for this rule */
+ list_add(&CurElementLabels, (void *)lab);
+/* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */
+ $label = l;
+ }
+ else {
+ err(eMsg1("label definitions must be unique per rule: '%s'", lab));
+ $label = NULL;
+ }
+ }
+ >>
+ ":"
+ ;
+
+/* rule element */
+
+element[int old_not, int first_on_line, int use_def_MT_handler] > [Node *node]
+ : <<
+ Attrib blk;
+ Predicate *pred = NULL;
+ int local_use_def_MT_handler=0;
+ ActionNode *act;
+ RuleRefNode *rr;
+ set toksrefd, rulesrefd;
+ TermEntry *term;
+ TokNode *p=NULL; RuleRefNode *q; int approx=0;
+ LabelEntry *label=NULL;
+ int predMsgDone=0;
+ int semDepth=0;
+ int ampersandStyle;
+ int height; /* MR11 */
+ int equal_height; /* MR11 */
+
+ char* pFirstSetSymbol = NULL; /* MR21 */
+
+ $node = NULL;
+ >>
+ {element_label>[label]}
+ ( TokenTerm
+ <<
+ term = (TermEntry *) hash_get(Tname, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ $$.left = $$.right = NULL;
+ }
+ else {
+ $$ = buildToken(LATEXT(1));
+ p=((TokNode *)((Junction *)$$.left)->p1);
+ term = (TermEntry *) hash_get(Tname, LATEXT(1));
+ require( term!= NULL, "hash table mechanism is broken");
+ p->tclass = term->tclass;
+ p->complement = $old_not;
+ if ( label!=NULL ) {
+ p->el_label = label->str;
+ label->elem = (Node *)p;
+ }
+ }
+ >>
+ { ".."
+ ( QuotedTerm
+ <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>
+ | TokenTerm
+ <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>
+ )
+ }
+ <<
+ if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) )
+ list_add(&MetaTokenNodes, (void *)p);
+ >>
+ ( "^" <<if ( p!=NULL ) p->astnode=ASTroot;>>
+ | <<if ( p!=NULL ) p->astnode=ASTchild;>>
+ | "!" <<if ( p!=NULL ) p->astnode=ASTexclude;>>
+ )
+ { "\@" <<local_use_def_MT_handler = 1;>> }
+ <<
+ if ( p!=NULL && $first_on_line ) {
+ CurAltStart = (Junction *)$$.left;
+ altAdd(CurAltStart); /* MR7 */
+ p->altstart = CurAltStart;
+ }
+ if ( p!=NULL )
+ p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler;
+ $node = (Node *)p;
+ >>
+ | QuotedTerm
+ <<
+ term = (TermEntry *) hash_get(Texpr, LATEXT(1));
+ if ( term==NULL && UserDefdTokens ) {
+ err("implicit token definition not allowed with #tokdefs");
+ $$.left = $$.right = NULL;
+ }
+ else {
+ $$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);
+ p->complement = $old_not;
+ if ( label!=NULL ) {
+ p->el_label = label->str;
+ label->elem = (Node *)p;
+ }
+ }
+ >>
+ { ".."
+ ( QuotedTerm
+ <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>
+ | TokenTerm
+ <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>
+ )
+ }
+ ( "^" <<if ( p!=NULL ) p->astnode=ASTroot;>>
+ | <<if ( p!=NULL ) p->astnode=ASTchild;>>
+ | "!" <<if ( p!=NULL ) p->astnode=ASTexclude;>>
+ )
+ { "\@" <<local_use_def_MT_handler = 1;>> }
+ <<
+ if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) )
+ list_add(&MetaTokenNodes, (void *)p);
+ >>
+ <<
+ if ( $first_on_line ) {
+ CurAltStart = (Junction *)$$.left;
+ altAdd(CurAltStart); /* MR7 */
+ p->altstart = CurAltStart;
+ }
+ if ( p!=NULL )
+ p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler;
+ $node = (Node *)p;
+ >>
+
+ | <<if ( $old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')");>>
+ "."
+ <<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>>
+ ( "^" <<p->astnode=ASTroot;>>
+ | <<p->astnode=ASTchild;>>
+ | "!" <<p->astnode=ASTexclude;>>
+ )
+ <<list_add(&MetaTokenNodes, (void *)p);>>
+ <<
+ if ( $first_on_line ) {
+ CurAltStart = (Junction *)$$.left;
+ altAdd(CurAltStart); /* MR7 */
+ p->altstart = CurAltStart;
+ if ( label!=NULL ) {
+ p->el_label = label->str;
+ label->elem = (Node *)p;
+ }
+ }
+ $node = (Node *)p;
+ >>
+
+ | <<if ( $old_not ) warn("~ NONTERMINAL is an undefined operation");>>
+ NonTerminal
+ <<$$ = buildRuleRef(LATEXT(1));>>
+ { "!" <<q = (RuleRefNode *) ((Junction *)$$.left)->p1;
+ q->astnode=ASTexclude;>>
+ }
+ { {"\<"}
+ PassAction <<addParm(((Junction *)$$.left)->p1, LATEXT(1));>>
+ }
+ <<rr=(RuleRefNode *) ((Junction *)$$.left)->p1;>>
+ { <<char *a;>>
+ "\>"
+ PassAction
+ <<
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule element: cannot allocate assignment");
+ strcpy(a, LATEXT(1));
+ rr->assign = a;
+ >>
+ }
+ <<
+ if ( label!=NULL ) {
+ rr->el_label = label->str;
+ label->elem = (Node *)rr;
+ }
+ if ( $first_on_line ) {
+ CurAltStart = (Junction *)$$.left;
+ altAdd(CurAltStart); /* MR7 */
+ ((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart;
+ }
+ $node = (Node *)rr;
+ >>
+ )
+
+ | <<if ( $old_not ) warn("~ ACTION is an undefined operation");>>
+ Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>>
+ <<if ( $first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *)$0.left; /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };>> /* MR7 */
+ <<$node = (Node *) ((Junction *)$0.left)->p1;>>
+
+ | <<if ( $old_not ) warn("~ SEMANTIC-PREDICATE is an undefined operation");>>
+ Pred <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>>
+ <<act = (ActionNode *) ((Junction *)$0.left)->p1;>>
+ <<if (numericActionLabel) { /* MR10 */
+ list_add(&NumericPredLabels,act); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ }; /* MR10 */
+ >>
+ { <<char *a;>>
+ PassAction
+ <<
+ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule element: cannot allocate predicate fail action");
+ strcpy(a, LATEXT(1));
+ act->pred_fail = a;
+ >>
+ }
+ <<if ( $first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *)$0.left; /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };>> /* MR7 */
+ <<$node = (Node *)act;>>
+
+ | <<if ( $old_not ) warn("~ BLOCK is an undefined operation");>>
+ <<BlkLevel++;
+ if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");
+/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;
+/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;
+ >>
+ { Pragma
+ ( "approx" <<approx=LL_k;>>
+ | "LL\(1\)" <<approx = 1;>> /* MR20 */
+ | "LL\(2\)" <<approx = 2;>> /* MR20 */
+ )
+ }
+
+/* MR21 */ { FirstSetSymbol
+/* MR21 */ "\("
+/* MR21 */ ( NonTerminal
+/* MR21 */ <<
+/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,
+/* MR21 */ sizeof(char));
+/* MR21 */ require(pFirstSetSymbol!=NULL,
+/* MR21 */ "cannot allocate first set name");
+/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1));
+/* MR21 */ >>
+/* MR21 */ | TokenTerm
+/* MR21 */ <<
+/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,
+/* MR21 */ sizeof(char));
+/* MR21 */ require(pFirstSetSymbol!=NULL,
+/* MR21 */ "cannot allocate first set name");
+/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1));
+/* MR21 */ >>
+/* MR21 */ )
+/* MR21 */ "\)"
+/* MR21 */ }
+
+ (
+
+ "\(" block[&toksrefd,&rulesrefd] "\)"
+ <<blk = $$ = $2;
+ /* MR23 */ CurBlockID_array[BlkLevel] = (-1);
+ /* MR23 */ CurAltNum_array[BlkLevel] = (-1);
+ --BlkLevel;
+ >>
+
+ ( "\*" <<$$ = makeLoop($$,approx,pFirstSetSymbol);>>
+ | "\+" <<$$ = makePlus($$,approx,pFirstSetSymbol);>>
+ | "?"
+ (
+ ( "=>" <<ampersandStyle=0;>>
+ | "&&" <<ampersandStyle=1;>> /* MR10 (g)? && <<p>>? */
+ )
+ Pred /* generalized predicate */
+ /* first make into a predicate */
+ <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>>
+ <<act = (ActionNode *) ((Junction *)$$.left)->p1;>>
+ <<semDepth=predicateLookaheadDepth(act);>> /* MR10 */
+ <<if (numericActionLabel) { /* MR10 */
+ list_add(&NumericPredLabels,act); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ }; /* MR10 */
+ >>
+ { <<char *a;>>
+ PassAction
+ <<
+ a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(a!=NULL, "rule element: cannot allocate predicate fail action");
+ strcpy(a, LATEXT(1));
+ act->pred_fail = a;
+ >>
+ }
+ <<if ($first_on_line) { /* MR7 */
+ CurAltStart=(Junction *)$$.left; /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };>>
+ <<$node = (Node *)act;>>
+
+ /* for now, just snag context */
+ <<
+ pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */
+ if ( pred==NULL) { /* MR10 */
+ if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */
+ predMsgDone=1; /* MR10 */
+ } else { /* MR10 */
+ act->guardNodes=(Junction *)blk.left; /* MR11 */
+ pred->expr = act->action;
+ pred->source = act;
+/* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */
+/* MR13 */ if (pred->tcontext != NULL) {
+/* MR13 */ height=MR_max_height_of_tree(pred->tcontext);
+/* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height);
+/* MR13 */ if (! equal_height) {
+/* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height",
+/* MR13 */ FileStr[act->file],act->line);
+/* MR13 */ };
+/* MR13 */ }
+/* MR10 */ if (ampersandStyle) {
+/* MR10 */ act->ampersandPred = pred;
+/* MR11 */ if (! HoistPredicateContext) {
+/* MR11 */ errFL("without \"-prc on\" (guard)? && <<pred>>? ... doesn't make sense",
+/* MR11 */ FileStr[act->file],act->line);
+/* MR11 */ };
+/* MR10 */ } else {
+/* MR10 */ act->guardpred = pred;
+/* MR10 */ };
+/* MR10 */ if (pred->k != semDepth) {
+/* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)",
+/* MR10 */ pred->k,semDepth));
+/* MR10 */ };
+ }
+ >>
+ | <<$$ = makeBlk($$,approx,pFirstSetSymbol);
+ FoundGuessBlk = 1;
+ ((Junction *) ((Junction *)$$.left)->p1)->guess=1;
+ if ( !$first_on_line ) {
+ err("(...)? predicate must be first element of production");
+ }
+ >>
+ )
+ | <<$$ = makeBlk($$,approx,pFirstSetSymbol);>>
+ )
+ <<
+ if ( pred==NULL && !predMsgDone) { /* MR10 */
+ ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID;
+ ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd;
+ ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd;
+ if ( $first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1); /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ }; /* MR7 */
+ $node = (Node *) ((Junction *)$$.left)->p1;
+ }
+ >>
+
+ | "\{" block[&toksrefd,&rulesrefd]
+ <<$$ = makeOpt($2,approx,pFirstSetSymbol);
+ /* MR23 */ CurBlockID_array[BlkLevel] = (-1);
+ /* MR23 */ CurAltNum_array[BlkLevel] = (-1);
+ --BlkLevel;
+ >>
+ "\}"
+ <<
+ ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID;
+ ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd;
+ ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd;
+ >>
+ <<if ( $first_on_line ) { /* MR7 */
+ CurAltStart = (Junction *) ((Junction *)((Junction *)$$.left)->p1); /* MR7 */
+ altAdd(CurAltStart); /* MR7 */
+ };
+ >>
+ <<$node = (Node *) ((Junction *)$$.left)->p1;>>
+
+ )
+
+/* Error catching alternatives */
+ | "\*" <<warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE;>>
+ | "\+" <<warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE;>>
+ | "\>" <<warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE;>>
+ | PassAction <<warn("[...] out of context 'rule > [...]'");
+ CannotContinue=TRUE;>>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule default_exception_handler */
+
+default_exception_handler
+ : exception_group > [DefaultExGroup]
+ ;
+
+/* rule exception_group */
+
+exception_group > [ExceptionGroup *eg]
+ : <<ExceptionHandler *h; LabelEntry *label=NULL; /* MR6 */
+ FoundException = 1; FoundExceptionGroup = 1;>> /* MR6 */
+
+ "exception" <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>>
+ { <<char *p;>>
+ PassAction /* did they attach a label? */
+ <<
+ p = LATEXT(1)+1;
+ p[strlen(p)-1] = '\0'; /* kill trailing space */
+ label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1);
+ if ( label==NULL )
+ {
+ err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1));
+ }
+ >>
+ }
+ ( exception_handler > [h]
+ <<list_add(&($eg->handlers), (void *)h);>>
+ )*
+ { "default" ":" Action
+ <<{
+ ExceptionHandler *eh = (ExceptionHandler *)
+ calloc(1, sizeof(ExceptionHandler));
+ char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require(eh!=NULL, "exception: cannot allocate handler");
+ require(a!=NULL, "exception: cannot allocate action");
+ strcpy(a, LATEXT(1));
+ eh->action = a;
+ eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char));
+ require(eh->signalname!=NULL, "exception: cannot allocate sig name");
+ strcpy(eh->signalname, "default");
+ list_add(&($eg->handlers), (void *)eh);
+ }>>
+ }
+
+ <<
+ if ( label!=NULL ) {
+ /* Record ex group in sym tab for this label */
+ if ( label->ex_group!=NULL ) {
+ err(eMsg1("duplicate exception handler for label '%s'",label->str));
+ } else {
+ label->ex_group = $eg;
+ /* Label the exception group itself */
+ $eg->label = label->str;
+ /* Make the labelled element pt to the exception also */
+/* MR6 */ if (label->elem == NULL) {
+/* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str));
+/* MR6 */ } else {
+ switch ( label->elem->ntype ) {
+ case nRuleRef :
+ {
+ RuleRefNode *r = (RuleRefNode *)label->elem;
+ r->ex_group = $eg;
+ break;
+ }
+ case nToken :
+ {
+ TokNode *t = (TokNode *)label->elem;
+ t->ex_group = $eg;
+ break;
+ }
+ } /* end switch */
+/* MR6 */ }; /* end test on label->elem */
+ } /* end test on label->ex_group */
+
+ } /* end test on exception label */
+
+/* MR7 */
+/* MR7 */ if (BlkLevel == 1 && label == NULL) {
+/* MR7 */ $eg->forRule=1;
+/* MR7 */ } else if (label == NULL) {
+/* MR7 */ $eg->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]);
+/* MR7 */ egAdd($eg);
+/* MR7 */ } else {
+/* MR7 */ $eg->labelEntry=label;
+/* MR7 */ };
+/* MR7 */
+/* MR7 */ /* You may want to remove this exc from the rule list */
+/* MR7 */ /* and handle at the labeled element site. */
+/* MR7 */
+/* MR7 */ if (label != NULL) {
+/* MR7 */ $eg = NULL;
+/* MR7 */ };
+
+ >>
+ ;
+ <<CannotContinue=TRUE;>>
+
+/* rule exception_handler */
+
+exception_handler > [ExceptionHandler *eh]
+ : <<;>> /* MR9 Removed unreferenced variable "a" */
+ "catch"
+ <<
+ $eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler));
+ require($eh!=NULL, "exception: cannot allocate handler");
+ >>
+ ( NonTerminal
+ <<
+ $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require($eh->signalname!=NULL, "exception: cannot allocate sig name");
+ strcpy($eh->signalname, LATEXT(1));
+ >>
+ | TokenTerm
+ <<
+ $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require($eh->signalname!=NULL, "exception: cannot allocate sig name");
+ strcpy($eh->signalname, LATEXT(1));
+ >>
+ )
+ ":"
+ { <<$eh->action = NULL;>>
+ Action
+ <<
+ $eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ require($eh->action!=NULL, "exception: cannot allocate action");
+ strcpy($eh->action, LATEXT(1));
+ >>
+ }
+ ;
+ <<CannotContinue=TRUE;>>
+
+#token NonTerminal "[a-z] [A-Za-z0-9_]*"
+ <<
+ while ( zzchar==' ' || zzchar=='\t' ) {
+ zzadvance();
+ }
+ if ( zzchar == ':' && inAlt ) NLA = LABEL;
+ >>
+#token TokenTerm "[A-Z] [A-Za-z0-9_]*"
+ <<
+ while ( zzchar==' ' || zzchar=='\t' ) {
+ zzadvance();
+ }
+ if ( zzchar == ':' && inAlt ) NLA = LABEL;
+ >>
+#token "{\\}#[A-Za-z0-9_]*" <<warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); >>
+
+#lexclass PARSE_ENUM_FILE
+
+#token "[\t\ ]+" << zzskip(); >> /* Ignore White */
+#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */
+#token "//" << zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >>
+#token "/\*" << zzmode(TOK_DEF_COMMENTS); zzskip(); >>
+#token "#ifdef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>
+#token "#if" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>
+#token "#ifndef" << ; >>
+#token "#else" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>
+#token "#endif" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>
+#token "#undef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>
+#token "#import" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>
+#token "@" << ; >>
+
+/* rule enum_file */
+
+enum_file[char *fname]
+ : { "#ifndef" ID
+ { "#define" ID /* ignore if it smells like a gate */
+ /* First #define after the first #ifndef (if any) is ignored */
+ }
+ }
+ ( ( enum_def[$fname] )+
+ | defines[$fname]
+ )
+ |
+ ;
+
+/* rule defines */
+
+defines[char *fname]
+ : <<int v; int maxt=(-1); char *t;>> /* MR3 */
+ (
+ "#define" ID
+ <<t = mystrdup(LATEXT(1));>>
+ INT
+ <<
+ v = atoi(LATEXT(1));
+/* fprintf(stderr, "#token %s=%d\n", t, v);*/
+
+ /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */
+ /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */
+ /* MR2 Don't let #tokdefs be confused by */
+ /* MR2 DLGminToken and DLGmaxToken */
+
+ if ( ! isDLGmaxToken(t)) { /* MR2 */
+ TokenNum = v;
+ if ( v>maxt ) maxt=v;
+ if ( Tnum( t ) == 0 ) {
+ addForcedTname( t, v );
+ } else {
+ warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);
+ };
+ };
+ >>
+ )+
+ <<TokenNum = maxt + 1;>>
+ ;
+
+/* rule enum_def */
+
+enum_def[char *fname]
+ : <<int v= 0; int maxt=(-1); char *t;>> /* MR3 */
+ "enum" ID
+ "\{"
+ ID
+ <<t = mystrdup(LATEXT(1));>>
+ ( "=" INT <<v=atoi(LATEXT(1));>>
+ | <<v++;>>
+ )
+ <<
+/* fprintf(stderr, "#token %s=%d\n", t, v);*/
+ TokenNum = v;
+ if ( v>maxt ) maxt=v; /* MR3 */
+ if ( Tnum( t ) == 0 ) addForcedTname( t, v );
+ else {
+ warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);
+ }
+ >>
+ ( ","
+
+ /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */
+ /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */
+ /* MR2 Don't let #tokdefs be confused by */
+ /* MR2 DLGminToken and DLGmaxToken */
+
+ {
+ <<isDLGmaxToken(LATEXT(1))>>? ID { "=" INT } /* MR2 */
+ | ID /* MR2 */
+ <<t = mystrdup(LATEXT(1));>>
+ ( "=" INT <<v=atoi(LATEXT(1));>>
+ | <<v++;>>
+ )
+ <<
+/* fprintf(stderr, "#token %s=%d\n", t, v);*/
+ TokenNum = v;
+ if ( v>maxt ) maxt=v; /* MR3 */
+ if ( Tnum( t ) == 0 ) addForcedTname( t, v );
+ else {
+ warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);
+ }
+ >>
+ }
+ )*
+ "\}"
+ ";"
+ <<TokenNum = maxt + 1;>> /* MR3 */
+ ;
+
+#token INT "[0-9]+"
+#token ID "[a-zA-Z_][_a-zA-Z0-9]*"
+
+#lexclass START
+
+/* MR14 Arpad Beszedes 26-May-98
+ Add support for #line directives when antlr source is pre-processed
+*/
+
+#lexaction
+<<
+
+static char *
+#ifdef __USE_PROTOS
+getFileNameFromTheLineInfo(char *toStr, char *fromStr)
+#else
+getFileNameFromTheLineInfo(toStr, fromStr)
+char *toStr, *fromStr;
+#endif
+{
+ int i, j, k;
+
+ if (!fromStr || !toStr) return toStr;
+
+ /* find the first " */
+
+ for (i=0;
+ (i<MaxFileName) &&
+ (fromStr[i] != '\n') &&
+ (fromStr[i] != '\r') &&
+ (fromStr[i] != '\"');
+ i++) /* nothing */ ;
+
+ if ( (i == MaxFileName) ||
+ (fromStr[i] == '\n') ||
+ (fromStr[i] == '\r') ) {
+ return toStr;
+ }
+
+ /* find the second " */
+
+ for (j=i+1;
+ (j<MaxFileName) &&
+ (fromStr[j] != '\n') &&
+ (fromStr[j] != '\r') &&
+ (fromStr[j] != '\"');
+ j++) /* nothing */ ;
+
+ if ((j == MaxFileName) ||
+ (fromStr[j] == '\n') ||
+ (fromStr[j] == '\r') ) {
+ return toStr;
+ }
+
+ /* go back until the last / or \ */
+
+ for (k=j-1;
+ (fromStr[k] != '\"') &&
+ (fromStr[k] != '/') &&
+ (fromStr[k] != '\\');
+ k--) /* nothing */ ;
+
+ /* copy the string after " / or \ into toStr */
+
+ for (i=k+1; fromStr[i] != '\"'; i++) {
+ toStr[i-k-1] = fromStr[i];
+ }
+
+ toStr[i-k-1] = '\0';
+
+ return toStr;
+}
+
+/* MR14 end of a block to support #line in antlr source code */
+
+>>
+
+<<
+
+/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */
+/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */
+/* MR2 Don't let #tokdefs be confused by */
+/* MR2 DLGminToken and DLGmaxToken */
+
+/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */
+
+#ifdef __USE_PROTOS
+static int isDLGmaxToken(char *Token)
+#else
+static int isDLGmaxToken(Token)
+ char * Token;
+#endif
+{
+ static char checkStr1[] = "DLGmaxToken";
+ static char checkStr2[] = "DLGminToken";
+
+ if (strcmp(Token, checkStr1) == 0)
+ return 1;
+ else if (strcmp(Token, checkStr2) == 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* semantics of #token */
+static void
+#ifdef __USE_PROTOS
+chkToken(char *t, char *e, char *a, int tnum)
+#else
+chkToken(t,e,a,tnum)
+char *t, *e, *a;
+int tnum;
+#endif
+{
+ TermEntry *p;
+
+ /* check to see that they don't try to redefine a token as a token class */
+ if ( t!=NULL ) {
+ p = (TermEntry *) hash_get(Tname, t);
+ if ( p!=NULL && p->classname ) {
+ err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t));
+ if ( a!=NULL ) free((char *)a);
+ return;
+ }
+ }
+
+ if ( t==NULL && e==NULL ) { /* none found */
+ err("#token requires at least token name or rexpr");
+ }
+ else if ( t!=NULL && e!=NULL ) { /* both found */
+ if ( UserDefdTokens ) { /* if #tokdefs, must not define new */
+ p = (TermEntry *) hash_get(Tname, t);
+ if ( p == NULL) {
+err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));
+ return;
+ };
+ }
+ Tklink(t, e);
+ if ( a!=NULL ) {
+ if ( hasAction(e) ) {
+ err(eMsg1("redefinition of action for %s; ignored",e));
+ }
+ else setHasAction(e, a);
+ }
+ }
+ else if ( t!=NULL ) { /* only one found */
+ if ( UserDefdTokens ) {
+ p = (TermEntry *) hash_get(Tname, t);
+ if (p == NULL) {
+err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));
+ };
+ return;
+ }
+ if ( Tnum( t ) == 0 ) addTname( t );
+ else {
+ err(eMsg1("redefinition of token %s; ignored",t));
+ }
+ if ( a!=NULL ) {
+ err(eMsg1("action cannot be attached to a token name (%s); ignored",t));
+ free((char *)a);
+ }
+ }
+ else if ( e!=NULL ) {
+ if ( Tnum( e ) == 0 ) addTexpr( e );
+ else {
+ if ( hasAction(e) ) {
+ err(eMsg1("redefinition of action for expr %s; ignored",e));
+ }
+ else if ( a==NULL ) {
+ err(eMsg1("redefinition of expr %s; ignored",e));
+ }
+ }
+ if ( a!=NULL ) setHasAction(e, a);
+ }
+
+ /* if a token type number was specified, then add the token ID and 'tnum'
+ * pair to the ForcedTokens list. (only applies if an id was given)
+ */
+ if ( t!=NULL && tnum>0 )
+ {
+ if ( set_el(tnum, reserved_positions) )
+ {
+ err(eMsgd("a token has already been forced to token number %d; ignored", tnum));
+ }
+ else
+ {
+ list_add(&ForcedTokens, newForcedToken(t,tnum));
+ set_orel(tnum, &reserved_positions);
+ }
+ }
+}
+>>
+
+<<
+static int
+#ifdef __USE_PROTOS
+match_token(char *s, char **nxt)
+#else
+match_token(s,nxt)
+char *s;
+char **nxt;
+#endif
+{
+ if ( !(*s>='A' && *s<='Z') ) return 0;
+ s++;
+ while ( (*s>='a' && *s<='z') ||
+ (*s>='A' && *s<='Z') ||
+ (*s>='0' && *s<='9') ||
+ *s=='_' )
+ {
+ s++;
+ }
+ if ( *s!=' ' && *s!='}' ) return 0;
+ *nxt = s;
+ return 1;
+}
+
+static int
+#ifdef __USE_PROTOS
+match_rexpr(char *s, char **nxt)
+#else
+match_rexpr(s,nxt)
+char *s;
+char **nxt;
+#endif
+{
+ if ( *s!='"' ) return 0;
+ s++;
+ while ( *s!='"' )
+ {
+ if ( *s=='\n' || *s=='\r' ) /* MR13 */
+ warn("eoln found in regular expression");
+ if ( *s=='\\' ) s++;
+ s++;
+ }
+ *nxt = s+1;
+ return 1;
+}
+
+/*
+ * Walk a string "{ A .. Z }" where A..Z is a space separated list
+ * of token references (either labels or reg exprs). Return a
+ * string "inlineX_set" for some unique integer X. Basically,
+ * we pretend as if we had seen "#tokclass inlineX { A .. Z }"
+ * on the input stream outside of an action.
+ */
+char *
+#ifdef __USE_PROTOS
+inline_set(char *s)
+#else
+inline_set(s)
+char *s;
+#endif
+{
+ char *nxt;
+ fprintf(stderr, "found consumeUntil( {...} )\n");
+ while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}
+ if ( *s!='{' )
+ {
+ err("malformed consumeUntil( {...} ); missing '{'");
+ return "bad_set";
+ }
+ s++;
+ while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}
+ while ( *s!='}' )
+ {
+ if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s);
+ else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s);
+ else {
+ err("invalid element in consumeUntil( {...} )");
+ return "bad_set";
+ }
+ s = nxt;
+ while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}
+ }
+ return "inlineX_set";
+}
+>>
+
+<<
+/* ANTLR-specific syntax error message generator
+ * (define USER_ZZSYN when compiling so don't get 2 definitions)
+ */
+void
+#ifdef __USE_PROTOS
+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok,
+int k, char *bad_text)
+#else
+zzsyn(text, tok, egroup, eset, etok, k, bad_text)
+char *text, *egroup, *bad_text;
+int tok;
+int etok;
+int k;
+SetWordType *eset;
+#endif
+{
+ fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline);
+ fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);
+ if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
+ if ( k==1 ) fprintf(stderr, " missing");
+ else
+ {
+ fprintf(stderr, "; \"%s\" not", bad_text);
+ if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
+ }
+ if ( zzset_deg(eset)>0 ) zzedecode(eset);
+ else fprintf(stderr, " %s", zztokens[etok]);
+ if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);
+ fprintf(stderr, "\n");
+}
+>>
+
+#lexaction <<
+#ifdef __USE_PROTOS
+void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */
+#else
+void mark_label_used_in_sem_pred(le) /* MR10 */
+ LabelEntry *le;
+#endif
+{
+ TokNode *tn;
+ require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");
+ tn=(TokNode *)le->elem;
+ require (tn->label != 0,"mark_label_used... TokNode has no label");
+ tn->label_used_in_semantic_pred=1;
+}
+>>
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.r b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.r
new file mode 100644
index 00000000..60d4d9d4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr.r
@@ -0,0 +1,787 @@
+/*
+ File: antlrMPW.r
+ Target: antlr 133MR
+ Created: Monday, June 15, 1998 4:41:11 AM
+ Author: Kenji Tanaka (kentar@osa.att.ne.jp)
+*/
+
+#include "cmdo.r"
+
+resource 'cmdo' (128, "Antlr") {
+ { /* array dialogs: 5 elements */
+ /* [1] */
+ 295,
+ "ANTLR -- Purdue Compiler Construction To"
+ "ol Set (PCCTS) LL(k) parser generator.",
+ { /* array itemArray: 12 elements */
+ /* [1] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {18, 23, 33, 223},
+ "Read grammar from stdin",
+ "-",
+ "Read grammar from stdin."
+ },
+ /* [2] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {38, 23, 53, 310},
+ "Send grammar.c/grammar.cpp to stdout",
+ "-stdout",
+ "Send grammar.c/grammar.cpp to stdout."
+ },
+ /* [3] */
+ NotDependent {
+
+ },
+ MultiFiles {
+ "Grammar File(s)É",
+ "Choose the grammar specification files y"
+ "ou wish to have ANTLR process.",
+ {79, 22, 98, 152},
+ "Grammar specification:",
+ "",
+ MultiInputFiles {
+ { /* array MultiTypesArray: 1 elements */
+ /* [1] */
+ text
+ },
+ ".g",
+ "Files ending in .g",
+ "All text files"
+ }
+ },
+ /* [4] */
+ NotDependent {
+
+ },
+ Files {
+ DirOnly,
+ OptionalFile {
+ {58, 168, 74, 298},
+ {79, 169, 98, 299},
+ "Output Directory",
+ ":",
+ "-o",
+ "",
+ "Choose the directory where ANTLR will pu"
+ "t its output.",
+ dim,
+ "Output DirectoryÉ",
+ "",
+ ""
+ },
+ NoMore {
+
+ }
+ },
+ /* [5] */
+ NotDependent {
+
+ },
+ Redirection {
+ StandardOutput,
+ {126, 27}
+ },
+ /* [6] */
+ NotDependent {
+
+ },
+ Redirection {
+ DiagnosticOutput,
+ {126, 178}
+ },
+ /* [7] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {117, 20, 167, 300},
+ "Redirection"
+ },
+ /* [8] */
+ NotDependent {
+
+ },
+ NestedDialog {
+ 5,
+ {20, 324, 40, 460},
+ "Parse OptionsÉ",
+ "Parse control options may be set with th"
+ "is button."
+ },
+ /* [9] */
+ NotDependent {
+
+ },
+ NestedDialog {
+ 2,
+ {50, 324, 70, 460},
+ "Generate OptionsÉ",
+ "Various command line options may be set "
+ "with this button."
+ },
+ /* [10] */
+ NotDependent {
+
+ },
+ NestedDialog {
+ 3,
+ {78, 324, 98, 460},
+ "More OptionsÉ",
+ "Antlr has ALOT of options. There are eve"
+ "n more to be found with this button."
+ },
+ /* [11] */
+ NotDependent {
+
+ },
+ NestedDialog {
+ 4,
+ {106, 324, 126, 460},
+ "Rename OptionsÉ",
+ "Options for renaming output files may be"
+ " set with this button."
+ },
+ /* [12] */
+ NotDependent {
+
+ },
+ VersionDialog {
+ VersionString {
+ "1.33MR"
+ },
+ "PCCTS was written by Terence Parr, Russe"
+ "ll Quong, Will Cohen, and Hank Dietz: 19"
+ "89-1998. MPW port by Scott Haney.",
+ noDialog
+ }
+ },
+ /* [2] */
+ 295,
+ "Use this dialog to specify command line "
+ "Generate Options.",
+ { /* array itemArray: 15 elements */
+ /* [1] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {18, 25, 33, 225},
+ "Generate C++ code",
+ "-CC",
+ "Generate C++ output from both ANTLR and "
+ "DLG."
+ },
+ /* [2] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {38, 25, 53, 225},
+ "Generate ASTs",
+ "-gt",
+ "Generate code for Abstract-Syntax-Trees "
+ "(ASTs)."
+ },
+ /* [3] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {58, 25, 73, 225},
+ "Generate line info",
+ "-gl",
+ "If this option is checked, ANTLR will ge"
+ "nerate line info about grammaractions, t"
+ "hereby making debugging easier since com"
+ "pile errors will point to the grammar fi"
+ "le."
+ },
+ /* [4] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {78, 25, 93, 225},
+ "Generate error classes",
+ "-ge",
+ "If this option is checked, ANTLR will ge"
+ "nerate an error class foreach non-termin"
+ "al."
+ },
+ /* [5] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {98, 25, 113, 225},
+ "Don't generate Code",
+ "-gc",
+ "If this option is checked, ANTLR will ge"
+ "nerate no code, i.e. it will only perfor"
+ "m analysis on the grammar."
+ },
+ /* [6] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {118, 25, 133, 225},
+ "Delay lookahead fetches",
+ "-gk",
+ "If this option is checked, ANTLR will ge"
+ "nerate a parser that delays lookahead fe"
+ "tches until needed."
+ },
+ /* [7] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {138, 25, 153, 225},
+ "Use newAST(...)",
+ "-newAST",
+ "In C++ mode use \"newAST(...)\" rather tha"
+ "n \"new AST(...)\""
+ },
+ /* [8] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {18, 235, 33, 435},
+ "Support parse traces",
+ "-gd",
+ "If this option is checked, ANTLR inserts"
+ " code in each parsing function to provid"
+ "e for user-defined handling of a detaile"
+ "d parse trace. The code consists of call"
+ "s to zzTRACEIN and zzTRACEOUT."
+ },
+ /* [9] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {38, 235, 53, 435},
+ "Generate cross-references",
+ "-cr",
+ "If this option is checked, ANTLR will ge"
+ "nerate a cross reference for all rules. "
+ "For each rule it will print a list of al"
+ "l other rules that reference it."
+ },
+ /* [10] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {58, 235, 73, 435},
+ "Don't create Lexer files",
+ "-gx",
+ "If this option is checked, ANTLR will no"
+ "t generate DLG-related output files. Thi"
+ "s option should be used if one wants a c"
+ "ustom lexical analyzer or if one has mad"
+ "e changes to the grammar not affecting t"
+ "he lexical structure."
+ },
+ /* [11] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {78, 235, 93, 460},
+ "Don't generate token expr sets",
+ "-gs",
+ "If this option is checked, ANTLR will no"
+ "t generate sets for token expression set"
+ "s; instead, it will generate a || separa"
+ "ted sequence of LA(1)==token #. "
+ },
+ /* [12] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {98, 235, 113, 460},
+ "Generate ANSI-compatible",
+ "-ga",
+ "Generate ANSI-compatible code (default=F"
+ "ALSE)"
+ },
+ /* [13] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {118, 235, 133, 460},
+ "Don't generate tokens.h",
+ "-gxt",
+ "Do not generate tokens.h (default=FALSE)"
+ },
+ /* [13] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {138, 235, 153, 460},
+ "Provide \"(alpha)? beta\" info",
+ "-alpha",
+ "Provide additional information for \"(alpha)? beta\" error messages"
+ },
+ /* [14] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Tabs(1 to 8):",
+ {162, 23, 177, 117},
+ {163, 125, 179, 196},
+ "",
+ keepCase,
+ "-tab",
+ "Width of tabs (1 to 8) for grammar.c/gra"
+ "mmar.cpp files."
+ },
+ /* [15] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Function Prefix:",
+ {161, 236, 177, 342},
+ {162, 345, 177, 454},
+ "",
+ keepCase,
+ "-gp",
+ "Prefix all generated rule functions with"
+ " a string."
+ }
+ },
+ /* [3] */
+ 295,
+ "Use this dialog to specify still more co"
+ "mmand line options.",
+ { /* array itemArray: 12 elements */
+ /* [1] */
+ NotDependent {
+
+ },
+ RadioButtons {
+ { /* array radioArray: 3 elements */
+ /* [1] */
+ {38, 25, 53, 85}, "None", "", Set, "When this option is selected, ANTLR will"
+ " not print the grammar to stdout.",
+ /* [2] */
+ {38, 100, 53, 160}, "Yes", "-p", NotSet, "When this option is selected, ANTLR will"
+ " print the grammar, stripped of all acti"
+ "ons and comments, to stdout.",
+ /* [3] */
+ {38, 175, 53, 235}, "More", "-pa", NotSet, "When this option is selected, ANTLR will"
+ " print the grammar, stripped of all acti"
+ "ons and comments, to stdout. It will als"
+ "o annotate the output with the first set"
+ "s determined from grammar analysis."
+ }
+ },
+ /* [2] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {28, 15, 60, 250},
+ "Grammar Printing"
+ },
+ /* [3] */
+ NotDependent {
+
+ },
+ RadioButtons {
+ { /* array radioArray: 3 elements */
+ /* [1] */
+ {88, 25, 103, 85}, "Low", "", Set, "When this option is selected, ANTLR will"
+ " show ambiguities/errors in low detail.",
+ /* [2] */
+ {88, 100, 103, 160}, "Medium", "-e2", NotSet, "When this option is selected, ANTLR will"
+ " show ambiguities/errors in more detail.",
+ /* [3] */
+ {88, 175, 103, 235}, "High", "-e3", NotSet, "When this option is selected, ANTLR will"
+ " show ambiguities/errors in excruciating"
+ " detail."
+ }
+ },
+ /* [4] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {78, 15, 110, 250},
+ "Error reporting"
+ },
+ /* [5] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {130, 22, 145, 222},
+ "More warnings",
+ "-w2",
+ "If this option is checked, ANTLR will wa"
+ "rn if semantic predicates and/or (É)? bl"
+ "ocks are assumed to cover ambiguous alte"
+ "rnatives."
+ },
+ /* [6] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Report when tnode usage exceeds:",
+ {162, 23, 180, 253},
+ {162, 255, 178, 326},
+ "",
+ keepCase,
+ "-treport",
+ "Report when tnode usage exceeds value du"
+ "ring ambiguity resolution."
+ },
+ /* [7] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {40, 292, 55, 431},
+ "Predicate",
+ "-info p",
+ "With the antlr \"-info p\" switch the user"
+ " will receive information about the pred"
+ "icate suppression in the generated file."
+ },
+ /* [8] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {60, 292, 75, 430},
+ "Tree Nodes",
+ "-info t",
+ "Using \"-info t\" gives information about "
+ "the total number of tnodes created and t"
+ "he peak number of tnodes."
+ },
+ /* [9] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {80, 292, 95, 425},
+ "First/follow",
+ "-info f",
+ "first/follow set information."
+ },
+ /* [10] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {100, 292, 115, 425},
+ "Monitor progress",
+ "-info m",
+ "prints name of each rule as it is starte"
+ "d and flushes output at start of each rule."
+ },
+ /* [11] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {120, 292, 135, 416},
+ "Orphan rules",
+ "-info o",
+ "If there is more than one rule which is "
+ "not referenced by any other rule then al"
+ "l such rules are listed."
+ },
+ /* [12] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {28, 279, 147, 451},
+ "Extra info"
+ }
+ },
+ /* [4] */
+ 295,
+ "Use this dialog to specify command line "
+ "options relating to renaming output file"
+ "s.",
+ { /* array itemArray: 7 elements */
+ /* [1] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Errors file name:",
+ {35, 25, 50, 205},
+ {35, 205, 51, 300},
+ "err.c",
+ keepCase,
+ "-fe",
+ "This entry specifies the name ANTLR uses"
+ " for the errors file."
+ },
+ /* [2] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Lexical output name:",
+ {60, 25, 75, 205},
+ {60, 205, 76, 300},
+ "parser.dlg",
+ keepCase,
+ "-fl",
+ "This entry specifies the name ANTLR uses"
+ " for the lexical output file."
+ },
+ /* [3] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Lexical modes name:",
+ {85, 25, 100, 205},
+ {85, 205, 101, 300},
+ "mode.h",
+ keepCase,
+ "-fm",
+ "This entry specifies the name ANTLR uses"
+ " for the lexical mode definitions file."
+ },
+ /* [4] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Remap file name:",
+ {110, 25, 125, 205},
+ {110, 205, 126, 300},
+ "remap.h",
+ keepCase,
+ "-fr",
+ "This entry specifies the name ANTLR uses"
+ " for the file that remaps globally visib"
+ "le symbols."
+ },
+ /* [5] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Tokens file name:",
+ {135, 25, 150, 205},
+ {135, 205, 151, 300},
+ "tokens.h",
+ keepCase,
+ "-ft",
+ "This entry specifies the name ANTLR uses"
+ " for the tokens file."
+ },
+ /* [6] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {160, 25, 175, 175},
+ "Create std header",
+ "-gh",
+ "If this option is checked, ANTLR will cr"
+ "eate a standard header file named, by de"
+ "fault 'stdpccts.h'. This name can be alt"
+ "ered using the entry right next door."
+ },
+ /* [7] */
+ Or {
+ { /* array OrArray: 1 elements */
+ /* [1] */
+ 6
+ }
+ },
+ RegularEntry {
+ "Std header file name:",
+ {160, 175, 175, 355},
+ {160, 355, 176, 450},
+ "stdpccts.h",
+ keepCase,
+ "-fh",
+ "This entry specifies the name ANTLR uses"
+ " for the standard header file."
+ }
+ },
+ /* [5] */
+ 295,
+ "Use this dialog to specify parse options"
+ ".",
+ { /* array itemArray: 9 elements */
+ /* [1] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Lookahead:",
+ {23, 27, 38, 152},
+ {46, 29, 62, 154},
+ "1",
+ keepCase,
+ "-k",
+ "This entry specifies the number of token"
+ "s of lookahead."
+ },
+ /* [2] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Compr lookahead:",
+ {22, 167, 37, 292},
+ {46, 172, 62, 297},
+ "",
+ keepCase,
+ "-ck",
+ "This entry specifies the number of token"
+ "s of lookahead when using compressed (li"
+ "near approximation) lookahead. In genera"
+ "l, the compressed lookahead is much deep"
+ "er than the full lookahead."
+ },
+ /* [3] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Max tree nodes:",
+ {22, 312, 37, 437},
+ {46, 315, 62, 445},
+ "",
+ keepCase,
+ "-rl",
+ "This entry specifies the maximum number "
+ "of tokens of tree nodes used by the gram"
+ "mar analysis."
+ },
+ /* [4] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {76, 25, 91, 350},
+ "Maintenance Release style hoisting",
+ "-mrhoist",
+ "Turn on/off k=1 Maintenance Release styl"
+ "e hoisting."
+ },
+ /* [5] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {96, 25, 111, 431},
+ "EXPERIMENTAL Maintenance Release style h"
+ "oisting",
+ "-mrhoistk",
+ "Turn on/off k>1 EXPERIMENTAL Maintenance"
+ " Release style hoisting."
+ },
+ /* [6] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {116, 25, 131, 363},
+ "Compute context for hoisted predicates",
+ "-prc on",
+ "Turn on/off computation of context for h"
+ "oisted predicates."
+ },
+ /* [7] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Ambiguity aid:",
+ {140, 27, 155, 125},
+ {141, 135, 155, 209},
+ "",
+ keepCase,
+ "-aa",
+ "Ambiguity aid for a rule (rule name or l"
+ "ine number)."
+ },
+ /* [8] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Limits exp growth:",
+ {140, 236, 155, 361},
+ {139, 372, 155, 452},
+ "",
+ keepCase,
+ "-aad",
+ "Limits exp growth of -aa listing - defau"
+ "lt=1 (max=ck value)."
+ },
+ /* [9] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {164, 26, 179, 366},
+ "Lookahead token may appear multiple time"
+ "s",
+ "-aam",
+ "Lookahead token may appear multiple time"
+ "s in -aa listing."
+ }
+ }
+ }
+};
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr1.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr1.txt
new file mode 100644
index 00000000..4545275e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/antlr1.txt
@@ -0,0 +1,264 @@
+
+
+
+ANTLR(1) PCCTS Manual Pages ANTLR(1)
+
+
+
+NAME
+ antlr - ANother Tool for Language Recognition
+
+SYNTAX
+ antlr [_o_p_t_i_o_n_s] _g_r_a_m_m_a_r__f_i_l_e_s
+
+DESCRIPTION
+ _A_n_t_l_r converts an extended form of context-free grammar into
+ a set of C functions which directly implement an efficient
+ form of deterministic recursive-descent LL(k) parser.
+ Context-free grammars may be augmented with predicates to
+ allow semantics to influence parsing; this allows a form of
+ context-sensitive parsing. Selective backtracking is also
+ available to handle non-LL(k) and even non-LALR(k) con-
+ structs. _A_n_t_l_r also produces a definition of a lexer which
+ can be automatically converted into C code for a DFA-based
+ lexer by _d_l_g. Hence, _a_n_t_l_r serves a function much like that
+ of _y_a_c_c, however, it is notably more flexible and is more
+ integrated with a lexer generator (_a_n_t_l_r directly generates
+ _d_l_g code, whereas _y_a_c_c and _l_e_x are given independent
+ descriptions). Unlike _y_a_c_c which accepts LALR(1) grammars,
+ _a_n_t_l_r accepts LL(k) grammars in an extended BNF notation -
+ which eliminates the need for precedence rules.
+
+ Like _y_a_c_c grammars, _a_n_t_l_r grammars can use automatically-
+ maintained symbol attribute values referenced as dollar
+ variables. Further, because _a_n_t_l_r generates top-down
+ parsers, arbitrary values may be inherited from parent rules
+ (passed like function parameters). _A_n_t_l_r also has a mechan-
+ ism for creating and manipulating abstract-syntax-trees.
+
+ There are various other niceties in _a_n_t_l_r, including the
+ ability to spread one grammar over multiple files or even
+ multiple grammars in a single file, the ability to generate
+ a version of the grammar with actions stripped out (for
+ documentation purposes), and lots more.
+
+OPTIONS
+ -ck _n
+ Use up to _n symbols of lookahead when using compressed
+ (linear approximation) lookahead. This type of looka-
+ head is very cheap to compute and is attempted before
+ full LL(k) lookahead, which is of exponential complex-
+ ity in the worst case. In general, the compressed loo-
+ kahead can be much deeper (e.g, -ck 10) _t_h_a_n _t_h_e _f_u_l_l
+ _l_o_o_k_a_h_e_a_d (_w_h_i_c_h _u_s_u_a_l_l_y _m_u_s_t _b_e _l_e_s_s _t_h_a_n _4).
+
+ -CC Generate C++ output from both ANTLR and DLG.
+
+ -cr Generate a cross-reference for all rules. For each
+ rule, print a list of all other rules that reference
+ it.
+
+ -e1 Ambiguities/errors shown in low detail (default).
+
+ -e2 Ambiguities/errors shown in more detail.
+
+ -e3 Ambiguities/errors shown in excruciating detail.
+
+ -fe file
+ Rename err.c to file.
+
+ -fh file
+ Rename stdpccts.h header (turns on -gh) to file.
+
+ -fl file
+ Rename lexical output, parser.dlg, to file.
+
+ -fm file
+ Rename file with lexical mode definitions, mode.h, to
+ file.
+
+ -fr file
+ Rename file which remaps globally visible symbols,
+ remap.h, to file.
+
+ -ft file
+ Rename tokens.h to file.
+
+ -ga Generate ANSI-compatible code (default case). This has
+ not been rigorously tested to be ANSI XJ11 C compliant,
+ but it is close. The normal output of _a_n_t_l_r is
+ currently compilable under both K&R, ANSI C, and C++-
+ this option does nothing because _a_n_t_l_r generates a
+ bunch of #ifdef's to do the right thing depending on
+ the language.
+
+ -gc Indicates that _a_n_t_l_r should generate no C code, i.e.,
+ only perform analysis on the grammar.
+
+ -gd C code is inserted in each of the _a_n_t_l_r generated pars-
+ ing functions to provide for user-defined handling of a
+ detailed parse trace. The inserted code consists of
+ calls to the user-supplied macros or functions called
+ zzTRACEIN and zzTRACEOUT. The only argument is a _c_h_a_r
+ * pointing to a C-style string which is the grammar
+ rule recognized by the current parsing function. If no
+ definition is given for the trace functions, upon rule
+ entry and exit, a message will be printed indicating
+ that a particular rule as been entered or exited.
+
+ -ge Generate an error class for each non-terminal.
+
+ -gh Generate stdpccts.h for non-ANTLR-generated files to
+ include. This file contains all defines needed to
+ describe the type of parser generated by _a_n_t_l_r (e.g.
+ how much lookahead is used and whether or not trees are
+ constructed) and contains the header action specified
+ by the user.
+
+ -gk Generate parsers that delay lookahead fetches until
+ needed. Without this option, _a_n_t_l_r generates parsers
+ which always have _k tokens of lookahead available.
+
+ -gl Generate line info about grammar actions in C parser of
+ the form # _l_i_n_e "_f_i_l_e" which makes error messages from
+ the C/C++ compiler make more sense as they will point
+ into the grammar file not the resulting C file.
+ Debugging is easier as well, because you will step
+ through the grammar not C file.
+
+ -gs Do not generate sets for token expression lists;
+ instead generate a ||-separated sequence of
+ LA(1)==_t_o_k_e_n__n_u_m_b_e_r. The default is to generate sets.
+
+ -gt Generate code for Abstract-Syntax Trees.
+
+ -gx Do not create the lexical analyzer files (dlg-related).
+ This option should be given when the user wishes to
+ provide a customized lexical analyzer. It may also be
+ used in _m_a_k_e scripts to cause only the parser to be
+ rebuilt when a change not affecting the lexical struc-
+ ture is made to the input grammars.
+
+ -k _n Set k of LL(k) to _n; i.e. set tokens of look-ahead
+ (default==1).
+
+ -o dir
+ Directory where output files should go (default=".").
+ This is very nice for keeping the source directory
+ clear of ANTLR and DLG spawn.
+
+ -p The complete grammar, collected from all input grammar
+ files and stripped of all comments and embedded
+ actions, is listed to stdout. This is intended to aid
+ in viewing the entire grammar as a whole and to elim-
+ inate the need to keep actions concisely stated so that
+ the grammar is easier to read. Hence, it is preferable
+ to embed even complex actions directly in the grammar,
+ rather than to call them as subroutines, since the sub-
+ routine call overhead will be saved.
+
+ -pa This option is the same as -p except that the output is
+ annotated with the first sets determined from grammar
+ analysis.
+
+ -prc on
+ Turn on the computation and hoisting of predicate con-
+ text.
+
+ -prc off
+ Turn off the computation and hoisting of predicate con-
+ text. This option makes 1.10 behave like the 1.06
+ release with option -pr on. Context computation is off
+ by default.
+
+ -rl _n
+ Limit the maximum number of tree nodes used by grammar
+ analysis to _n. Occasionally, _a_n_t_l_r is unable to
+ analyze a grammar submitted by the user. This rare
+ situation can only occur when the grammar is large and
+ the amount of lookahead is greater than one. A non-
+ linear analysis algorithm is used by PCCTS to handle
+ the general case of LL(k) parsing. The average com-
+ plexity of analysis, however, is near linear due to
+ some fancy footwork in the implementation which reduces
+ the number of calls to the full LL(k) algorithm. An
+ error message will be displayed, if this limit is
+ reached, which indicates the grammar construct being
+ analyzed when _a_n_t_l_r hit a non-linearity. Use this
+ option if _a_n_t_l_r seems to go out to lunch and your disk
+ start thrashing; try _n=10000 to start. Once the
+ offending construct has been identified, try to remove
+ the ambiguity that _a_n_t_l_r was trying to overcome with
+ large lookahead analysis. The introduction of (...)?
+ backtracking blocks eliminates some of these problems -
+ _a_n_t_l_r does not analyze alternatives that begin with
+ (...)? (it simply backtracks, if necessary, at run
+ time).
+
+ -w1 Set low warning level. Do not warn if semantic
+ predicates and/or (...)? blocks are assumed to cover
+ ambiguous alternatives.
+
+ -w2 Ambiguous parsing decisions yield warnings even if
+ semantic predicates or (...)? blocks are used. Warn if
+ predicate context computed and semantic predicates
+ incompletely disambiguate alternative productions.
+
+ - Read grammar from standard input and generate stdin.c
+ as the parser file.
+
+SPECIAL CONSIDERATIONS
+ _A_n_t_l_r works... we think. There is no implicit guarantee of
+ anything. We reserve no legal rights to the software known
+ as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS
+ is in the public domain. An individual or company may do
+ whatever they wish with source code distributed with PCCTS
+ or the code generated by PCCTS, including the incorporation
+ of PCCTS, or its output, into commercial software. We
+ encourage users to develop software with PCCTS. However, we
+ do ask that credit is given to us for developing PCCTS. By
+ "credit", we mean that if you incorporate our source code
+ into one of your programs (commercial product, research pro-
+ ject, or otherwise) that you acknowledge this fact somewhere
+ in the documentation, research report, etc... If you like
+ PCCTS and have developed a nice tool with the output, please
+ mention that you developed it using PCCTS. As long as these
+ guidelines are followed, we expect to continue enhancing
+ this system and expect to make other tools available as they
+ are completed.
+
+FILES
+ *.c output C parser.
+
+ *.cpp
+ output C++ parser when C++ mode is used.
+
+ parser.dlg
+ output _d_l_g lexical analyzer.
+
+ err.c
+ token string array, error sets and error support rou-
+ tines. Not used in C++ mode.
+
+ remap.h
+ file that redefines all globally visible parser sym-
+ bols. The use of the #parser directive creates this
+ file. Not used in C++ mode.
+
+ stdpccts.h
+ list of definitions needed by C files, not generated by
+ PCCTS, that reference PCCTS objects. This is not gen-
+ erated by default. Not used in C++ mode.
+
+ tokens.h
+ output #_d_e_f_i_n_e_s for tokens used and function prototypes
+ for functions generated for rules.
+
+
+SEE ALSO
+ dlg(1), pccts(1)
+
+
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/bits.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/bits.c
new file mode 100644
index 00000000..3a466fc1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/bits.c
@@ -0,0 +1,1025 @@
+/* bits.c -- manage creation and output of bit sets used by the parser.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <assert.h>
+#include "pcctscfg.h"
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+
+/* char is only thing that is pretty much always known == 8 bits
+ * This allows output of antlr (set stuff, anyway) to be androgynous (portable)
+ */
+typedef unsigned char SetWordType;
+#define BitsPerByte 8
+#define BitsPerWord BitsPerByte*sizeof(SetWordType)
+
+static SetWordType *setwd = NULL;
+int setnum = -1;
+int wordnum = 0;
+
+int esetnum = 0;
+
+/* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets,
+ to bytes that are most portable size-wise.
+ */
+void
+#ifdef __USE_PROTOS
+DumpIntAsChars( FILE *f, char *format, unsigned wd )
+#else
+DumpIntAsChars( f, format, wd )
+FILE *f;
+char *format;
+unsigned wd;
+#endif
+{
+ int i;
+ /* uses max of 32 bit unsigned integer for the moment */
+ static unsigned long byte_mask[sizeof(unsigned long)] =
+ { 0xFF, 0xFF00UL, 0xFF0000UL, 0xFF000000UL }; /* MR20 G. Hobbelt */
+/* 0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/
+
+ /* for each byte in the word */
+ assert(sizeof(unsigned) <= 4); /* M20 G. Hobbelt Sanity check */
+ for (i=0; i<sizeof(unsigned); i++)
+ {
+ /* mask out the ith byte and shift down to the first 8 bits */
+ fprintf(f, format, (wd&byte_mask[i])>>(i*BitsPerByte));
+ if ( i<sizeof(unsigned)-1) fprintf(f, ",");
+ }
+}
+
+/* Create a new setwd (ignoring [Ep] token on end) */
+void
+#ifdef __USE_PROTOS
+NewSetWd( void )
+#else
+NewSetWd( )
+#endif
+{
+ SetWordType *p;
+
+ if ( setwd == NULL )
+ {
+ setwd = (SetWordType *) calloc(TokenNum, sizeof(SetWordType));
+ require(setwd!=NULL, "NewSetWd: cannot alloc set wd\n");
+ }
+ for (p = setwd; p<&(setwd[TokenNum]); p++) {*p=0;}
+ wordnum++;
+}
+
+void
+#ifdef __USE_PROTOS
+DumpSetWd( void )
+#else
+DumpSetWd( )
+#endif
+{
+ if ( GenCC ) DumpSetWdForCC();
+ else DumpSetWdForC();
+}
+
+/* Dump the current setwd to ErrFile. 0..MaxTokenVal */
+void
+#ifdef __USE_PROTOS
+DumpSetWdForC( void )
+#else
+DumpSetWdForC( )
+#endif
+{
+ int i,c=1;
+
+ if ( setwd==NULL ) return;
+ fprintf(DefFile, "extern SetWordType setwd%d[];\n", wordnum);
+ fprintf(ErrFile,
+ "SetWordType setwd%d[%d] = {", wordnum, TokenNum-1);
+ for (i=0; i<TokenNum-1; i++)
+ {
+ DAWDLE;
+ if ( i!=0 ) fprintf(ErrFile, ",");
+ if ( c == 8 ) {fprintf(ErrFile, "\n\t"); c=1;} else c++;
+ fprintf(ErrFile, "0x%x", setwd[i]);
+ }
+ fprintf(ErrFile, "};\n");
+}
+
+/* Dump the current setwd to Parser.C file. 0..MaxTokenVal;
+ * Only used if -CC on.
+ */
+void
+#ifdef __USE_PROTOS
+DumpSetWdForCC( void )
+#else
+DumpSetWdForCC( )
+#endif
+{
+ int i,c=1;
+
+ if ( setwd==NULL ) return;
+ fprintf(Parser_h, "\tstatic SetWordType setwd%d[%d];\n", wordnum, TokenNum-1);
+ fprintf(Parser_c,
+ "SetWordType %s::setwd%d[%d] = {", CurrentClassName, wordnum,
+ TokenNum-1);
+ for (i=0; i<TokenNum-1; i++)
+ {
+ DAWDLE;
+ if ( i!=0 ) fprintf(Parser_c, ",");
+ if ( c == 8 ) {fprintf(Parser_c, "\n\t"); c=1;} else c++;
+ fprintf(Parser_c, "0x%x", setwd[i]);
+ }
+ fprintf(Parser_c, "};\n");
+}
+
+/* Make a new set. Dump old setwd and create new setwd if current setwd is full */
+void
+#ifdef __USE_PROTOS
+NewSet( void )
+#else
+NewSet( )
+#endif
+{
+ setnum++;
+ if ( setnum==BitsPerWord ) /* is current setwd full? */
+ {
+ DumpSetWd(); NewSetWd(); setnum = 0;
+ }
+}
+
+/* s is a set of tokens. Turn on bit at each token position in set 'setnum' */
+void
+#ifdef __USE_PROTOS
+FillSet( set s )
+#else
+FillSet( s )
+set s;
+#endif
+{
+ SetWordType mask=(((unsigned)1)<<setnum);
+ unsigned int e;
+
+ while ( !set_nil(s) )
+ {
+ e = set_int(s);
+ set_rm(e, s);
+ setwd[e] |= mask;
+ }
+}
+
+ /* E r r o r C l a s s S t u f f */
+
+/* compute the FIRST of a rule for the error class stuff */
+static set
+#ifdef __USE_PROTOS
+Efirst( char *rule, ECnode *eclass )
+#else
+Efirst( rule, eclass )
+char *rule;
+ECnode *eclass;
+#endif
+{
+ set rk, a;
+ Junction *r;
+ RuleEntry *q = (RuleEntry *) hash_get(Rname, rule);
+
+ if ( q == NULL )
+ {
+ warnNoFL(eMsg2("undefined rule '%s' referenced in errclass '%s'; ignored",
+ rule, TokenString(eclass->tok)));
+ return empty;
+ }
+ r = RulePtr[q->rulenum];
+ r->end->halt = TRUE; /* don't let reach fall off end of rule here */
+ rk = empty;
+ REACH(r, 1, &rk, a);
+ r->end->halt = FALSE;
+ return a;
+}
+
+/*
+ * scan the list of tokens/eclasses/nonterminals filling the new eclass
+ * with the set described by the list. Note that an eclass can be
+ * quoted to allow spaces etc... However, an eclass must not conflict
+ * with a reg expr found elsewhere. The reg expr will be taken over
+ * the eclass name.
+ */
+static void
+#ifdef __USE_PROTOS
+doEclass( char *eclass )
+#else
+doEclass( eclass )
+char *eclass;
+#endif
+{
+ TermEntry *q;
+ ECnode *p;
+ TCnode *tcnode;
+ ListNode *e;
+ unsigned int t;
+ unsigned deg=0;
+ set a;
+ require(eclass!=NULL, "doEclass: NULL eset");
+
+ p = (ECnode *) eclass;
+ lexmode(p->lexclass); /* switch to lexclass where errclass is defined */
+ p->eset = empty;
+ for (e = (p->elist)->next; e!=NULL; e=e->next)
+ {
+ q = NULL; /* MR23 */
+
+ if ( islower( *((char *)e->elem) ) ) /* is it a rule ref? (alias FIRST request) */
+ {
+ a = Efirst((char *)e->elem, p);
+ set_orin(&p->eset, a);
+ deg += set_deg(a);
+ set_free( a );
+ continue;
+ }
+ else if ( *((char *)e->elem)=='"' )
+ {
+ t = 0;
+ q = (TermEntry *) hash_get(Texpr, (char *) e->elem);
+ if ( q == NULL )
+ {
+ /* if quoted and not an expr look for eclass name */
+ q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem));
+ if ( q != NULL ) t = q->token;
+ }
+ else t = q->token;
+ }
+ else /* labelled token/eclass/tokclass */
+ {
+ q = (TermEntry *) hash_get(Tname, (char *)e->elem);
+ if ( q != NULL )
+ {
+ if ( strcmp((char *)e->elem, TokenString(p->tok))==0 )
+ {
+ warnNoFL(eMsg1("self-referential error class '%s'; ignored",
+ (char *)e->elem));
+ continue;
+ }
+ else
+ t = q->token;
+ }
+ else t=0;
+ }
+ if ( t!=0 )
+ {
+ if (isTermEntryTokClass(q)) { /* MR23 */
+ tcnode = q->tclass; /* MR23 */
+ set_orin(&p->eset, tcnode->tset); /* MR23 */
+ deg = set_deg(p->eset); /* MR23 */
+ } /* MR23 */
+ else {
+ set_orel(t, &p->eset);
+ deg++;
+ }
+ }
+ else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored",
+ (char *)e->elem, TokenString(p->tok)));
+ }
+ p->setdeg = deg;
+}
+
+void
+#ifdef __USE_PROTOS
+ComputeErrorSets( void )
+#else
+ComputeErrorSets( )
+#endif
+{
+#ifdef __cplusplus
+ list_apply(eclasses, (void (*)(void *)) doEclass);
+#else
+#ifdef __USE_PROTOS
+ list_apply(eclasses, (void (*)(void *)) doEclass);
+#else
+ list_apply(eclasses, doEclass);
+#endif
+#endif
+}
+
+void
+#ifdef __USE_PROTOS
+ComputeTokSets( void )
+#else
+ComputeTokSets( )
+#endif
+{
+ ListNode *t, *e = NULL, *e1, *e2;
+ int something_changed;
+ int i;
+ TCnode *p;
+ TermEntry *q, *q1, *q2;
+
+ if ( tclasses == NULL ) return;
+
+ /* turn lists of token/tokclass references into sets */
+ for (t = tclasses->next; t!=NULL; t=t->next)
+ {
+ p = (TCnode *) t->elem;
+
+ /* if wild card, then won't have entries in tclass, assume all_tokens */
+ if ( p->tok == WildCardToken )
+ {
+ p->tset = set_dup(all_tokens);
+ continue;
+ }
+
+ lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */
+ p->tset = empty;
+
+ /* instantiate all tokens/token_classes into the tset */
+ for (e = (p->tlist)->next; e!=NULL; e=e->next)
+ {
+ char *tokstr;
+ tokstr = (char *)e->elem;
+ if ( *tokstr == '"' ) {
+ q = (TermEntry *) hash_get(Texpr, tokstr);
+ require(q!=NULL, "ComputeTokSets: no token def");
+ set_orel(q->token, &p->tset);
+ } else if (tokstr[0] == '.') {
+ e1=e->next;
+ e2=e1->next;
+ e=e2;
+ q1= (TermEntry *) hash_get(Tname, (char *)e1->elem);
+ require(q1!=NULL, "ComputeTokSets: no token def");
+ q2= (TermEntry *) hash_get(Tname, (char *)e2->elem);
+ require(q2!=NULL, "ComputeTokSets: no token def");
+
+ if (set_el(q1->token,imag_tokens)) {
+errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s",
+ TokenString(p->tok),(char *)e1->elem) );
+ }
+ if (set_el(q2->token,imag_tokens)) {
+errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s",
+ TokenString(p->tok),(char *)e2->elem) );
+ }
+ if (q1->token > q2->token) {
+errNoFL(eMsg3("for #tokclass %s %s..%s - first token number > second token number",
+ TokenString(p->tok),(char *)e1->elem,(char *)e2->elem) );
+ for (i=q2->token; i<=q1->token; i++) { set_orel(i, &p->tset); }
+ } else {
+ for (i=q1->token; i<=q2->token; i++) { set_orel(i, &p->tset); }
+ }
+ } else {
+ q = (TermEntry *) hash_get(Tname, tokstr);
+ require(q!=NULL, "ComputeTokSets: no token def");
+ set_orel(q->token, &p->tset);
+ }
+ }
+ }
+
+ /* Go thru list of tokclasses again looking for tokclasses in sets */
+again:
+ something_changed = 0;
+ for (t = tclasses->next; t!=NULL; t=t->next)
+ {
+ set tcl;
+ p = (TCnode *) t->elem;
+ tcl = set_and(p->tset, tokclasses);
+ if ( !set_nil(tcl) )
+ {
+ int tk;
+ /* replace refs to tokclasses with the associated set of tokens */
+ something_changed = 1;
+ while ( !set_nil(tcl) )
+ {
+ tk = set_int(tcl); /* grab one of the tok class refs */
+ set_rm(tk, tcl);
+ if ( p->tok != tk ) /* tokclass ref to yourself? */
+ {
+ q = (TermEntry *) hash_get(Tname, TokenString(tk));
+ require(q!=NULL, "#tokclass not in hash table");
+ set_orin(&p->tset, q->tclass->tset);
+ }
+ set_rm(tk, p->tset); /* remove ref that we replaced */
+ }
+ }
+ set_free(tcl);
+ }
+ if ( something_changed ) goto again;
+}
+
+void
+#ifdef __USE_PROTOS
+DumpRemainingTokSets(void)
+#else
+DumpRemainingTokSets()
+#endif
+{
+ TCnode *p;
+ ListNode *t;
+
+ /* Go thru tclasses (for the last time) and dump the sets not dumped
+ * during code gen; yes, this is a bogus way to do this, but ComputeTokSets()
+ * can't dump the defs as the error file and tok file has not been created
+ * yet etc...
+ */
+ if ( tclasses==NULL ) return;
+ for (t = tclasses->next; t!=NULL; t=t->next)
+ {
+ unsigned e;
+ p = (TCnode *) t->elem;
+ if ( p->dumped ) continue;
+ e = DefErrSet(&(p->tset), 0, TokenString(p->tok));
+ p->dumped = 1;
+ p->setnum = e;
+ }
+}
+
+
+/* replace a subset of an error set with an error class name if a subset is found
+ * repeat process until no replacements made
+ */
+void
+#ifdef __USE_PROTOS
+SubstErrorClass( set *f )
+#else
+SubstErrorClass( f )
+set *f;
+#endif
+{
+ int max, done = 0;
+ ListNode *p;
+ ECnode *ec, *maxclass = NULL;
+ set a;
+ require(f!=NULL, "SubstErrorClass: NULL eset");
+
+ if ( eclasses == NULL ) return;
+ while ( !done )
+ {
+ max = 0;
+ maxclass = NULL;
+ for (p=eclasses->next; p!=NULL; p=p->next) /* chk all error classes */
+ {
+ ec = (ECnode *) p->elem;
+ if ( ec->setdeg > max )
+ {
+ if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) )
+ {maxclass = ec; max=ec->setdeg;}
+ }
+ }
+ if ( maxclass != NULL ) /* if subset found, replace with token */
+ {
+ a = set_dif(*f, maxclass->eset);
+ set_orel((unsigned)maxclass->tok, &a);
+ set_free(*f);
+ *f = a;
+ }
+ else done = 1;
+ }
+}
+
+int
+#ifdef __USE_PROTOS
+DefErrSet1(int nilOK, set *f, int subst, char *name )
+#else
+DefErrSet1(nilOK, f, subst, name )
+int nilOK;
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+#endif
+{
+ if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, "_set");
+ else return DefErrSetForC1(nilOK, f, subst, name, "_set");
+}
+
+int
+#ifdef __USE_PROTOS
+DefErrSet( set *f, int subst, char *name )
+#else
+DefErrSet( f, subst, name )
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+#endif
+{
+ return DefErrSet1(0,f,subst,name);
+}
+
+int
+#ifdef __USE_PROTOS
+DefErrSetWithSuffix(int nilOK, set *f, int subst, char *name, const char* suffix)
+#else
+DefErrSetWithSuffix(nilOK, f, subst, name, suffix )
+int nilOK;
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+char *suffix;
+#endif
+{
+ if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, suffix );
+ else return DefErrSetForC1(nilOK, f, subst, name, suffix);
+}
+
+/* Define a new error set. WARNING...set-implementation dependent.
+ */
+int
+#ifdef __USE_PROTOS
+DefErrSetForC1(int nilOK, set *f, int subst, char * name, const char * suffix)
+#else
+DefErrSetForC1(nilOK, f, subst, name, suffix)
+int nilOK; /* MR13 */
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+const char *suffix;
+#endif
+{
+ unsigned *p, *endp;
+ int e=1;
+
+ if (!nilOK) require(!set_nil(*f), "DefErrSetForC1: nil set to dump?");
+
+ if ( subst ) SubstErrorClass(f);
+ p = f->setword;
+ endp = &(f->setword[f->n]);
+ esetnum++;
+ if ( name!=NULL )
+ fprintf(DefFile, "extern SetWordType %s%s[];\n", name, suffix);
+ else
+ fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum);
+ if ( name!=NULL ) {
+ fprintf(ErrFile, "SetWordType %s%s[%lu] = {",
+ name,
+ suffix,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ }
+ else {
+ fprintf(ErrFile, "SetWordType zzerr%d[%lu] = {",
+ esetnum,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ }
+ while ( p < endp )
+ {
+ if ( e > 1 ) fprintf(ErrFile, ", ");
+ DumpIntAsChars(ErrFile, "0x%x", *p++);
+ if ( e == 3 )
+ {
+ DAWDLE;
+ if ( p < endp ) fprintf(ErrFile, ",");
+ fprintf(ErrFile, "\n\t");
+ e=1;
+ }
+ else e++;
+ }
+ fprintf(ErrFile, "};\n");
+
+ return esetnum;
+}
+
+int
+#ifdef __USE_PROTOS
+DefErrSetForC( set *f, int subst, char *name )
+#else
+DefErrSetForC( f, subst, name )
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+#endif
+{
+ return DefErrSetForC1(0,f,subst,name, "_set");
+}
+
+/* Define a new error set. WARNING...set-implementation dependent;
+ * Only used when -CC on.
+ */
+
+int
+#ifdef __USE_PROTOS
+DefErrSetForCC1(int nilOK, set *f, int subst, char *name, const char *suffix )
+#else
+DefErrSetForCC1(nilOK, f, subst, name, suffix )
+int nilOK; /* MR13 */
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+const char *suffix;
+#endif
+{
+ unsigned *p, *endp;
+ int e=1;
+
+ if (!nilOK) require(!set_nil(*f), "DefErrSetForCC1: nil set to dump?");
+
+ if ( subst ) SubstErrorClass(f);
+ p = f->setword;
+ endp = &(f->setword[f->n]);
+ esetnum++;
+
+ if ( name!=NULL ) {
+ fprintf(Parser_h, "\tstatic SetWordType %s%s[%lu];\n", name, suffix,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ fprintf(Parser_c, "SetWordType %s::%s%s[%lu] = {",
+ CurrentClassName,
+ name,
+ suffix,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ }
+ else {
+ fprintf(Parser_c, "SetWordType %s::err%d[%lu] = {",
+ CurrentClassName,
+ esetnum,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ fprintf(Parser_h, "\tstatic SetWordType err%d[%lu];\n", esetnum,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ }
+
+ while ( p < endp )
+ {
+ if ( e > 1 ) fprintf(Parser_c, ", ");
+ DumpIntAsChars(Parser_c, "0x%x", *p++);
+ if ( e == 3 )
+ {
+ if ( p < endp ) fprintf(Parser_c, ",");
+ fprintf(Parser_c, "\n\t");
+ e=1;
+ }
+ else e++;
+ }
+ fprintf(Parser_c, "};\n");
+
+ return esetnum;
+}
+
+int
+#ifdef __USE_PROTOS
+DefErrSetForCC( set *f, int subst, char *name )
+#else
+DefErrSetForCC( f, subst, name )
+set *f;
+int subst; /* should be substitute error classes? */
+char *name;
+#endif
+{
+ return DefErrSetForCC1(0,f,subst,name, "_set");
+}
+
+void
+#ifdef __USE_PROTOS
+GenParser_c_Hdr(void)
+#else
+GenParser_c_Hdr()
+#endif
+{
+ int i,j;
+ TermEntry *te;
+ char * hasAkaName = NULL; /* MR23 */
+
+ hasAkaName = (char *) malloc(TokenNum+1); /* MR23 */
+ require(hasAkaName!=NULL, "Cannot alloc hasAkaName\n"); /* MR23 */
+ for (i = 0; i < TokenNum; i++) hasAkaName[i]='0'; /* MR23 */
+ hasAkaName[TokenNum] = 0; /* MR23 */
+
+ fprintf(Parser_c, "/*\n");
+ fprintf(Parser_c, " * %s: P a r s e r S u p p o r t\n", CurrentClassName);
+ fprintf(Parser_c, " *\n");
+ fprintf(Parser_c, " * Generated from:");
+ for (i=0; i<NumFiles; i++) fprintf(Parser_c, " %s", FileStr[i]);
+ fprintf(Parser_c, "\n");
+ fprintf(Parser_c, " *\n");
+ fprintf(Parser_c, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(Parser_c, " * Parr Research Corporation\n");
+ fprintf(Parser_c, " * with Purdue University Electrical Engineering\n");
+ fprintf(Parser_c, " * with AHPCRC, University of Minnesota\n");
+ fprintf(Parser_c, " * ANTLR Version %s\n", Version);
+ fprintf(Parser_c, " */\n\n");
+
+ if ( FirstAction != NULL ) dumpAction(FirstAction,Parser_c, 0, -1, 0, 1); /* MR11 MR15b */
+
+ fprintf(Parser_c, "#define ANTLR_VERSION %s\n", VersionDef);
+
+ fprintf(Parser_c, "#include \"pcctscfg.h\"\n");
+ fprintf(Parser_c, "#include \"pccts_stdio.h\"\n");
+ fprintf(Parser_c, "#define ANTLR_SUPPORT_CODE\n");
+ if ( UserTokenDefsFile != NULL )
+ fprintf(Parser_c, "#include %s\n", UserTokenDefsFile);
+ else
+ fprintf(Parser_c, "#include \"%s\"\n", DefFileName);
+
+ fprintf(Parser_c, "#include \"%s.h\"\n\n", CurrentClassName);
+
+ fprintf(Parser_c, "const ANTLRChar *%s::tokenName(int tok) ", /* MR1 */
+ CurrentClassName); /* MR1 */
+ fprintf(Parser_c, " { return _token_tbl[tok]; }\n"); /* MR1 */ /* MR10 */
+ /* Dump a Parser::tokens for each automaton */
+ fprintf(Parser_c, "\nconst ANTLRChar *%s::_token_tbl[]={\n",
+ CurrentClassName); /* MR20 */
+ fprintf(Parser_c, "\t/* 00 */\t\"Invalid\"");
+
+ for (i=1; i<TokenNum-1; i++)
+ {
+ DAWDLE;
+ if ( i == EpToken ) continue;
+ /* remapped to invalid token? */
+ if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )
+ {
+ fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i);
+ continue;
+ }
+ if ( TokenString(i) != NULL ) {
+ te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */
+ if (te == NULL || te->akaString == NULL) { /* MR11 */
+ fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));
+ } else {
+ hasAkaName[i] = '1'; /* MR23 */
+ fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */
+ }
+ }
+ else
+ {
+ /* look in all lexclasses for the reg expr */
+ for (j=0; j<NumLexClasses; j++)
+ {
+ lexmode(j);
+ if ( ExprString(i) != NULL )
+ {
+ fprintf(Parser_c, ",\n\t/* %02d */\t", i);
+ dumpExpr(Parser_c, ExprString(i));
+ break;
+ }
+ }
+ if ( j>=NumLexClasses )
+ {
+ if ( UserDefdTokens )
+ {
+ fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i);
+ }
+ else
+ fatal_internal(eMsgd("No label or expr for token %d",i));
+ }
+ }
+ }
+ fprintf(Parser_c, "\n};\n");
+
+ /* Build constructors */
+ fprintf(Parser_c, "\n%s::", CurrentClassName);
+ fprintf(Parser_c, "%s(ANTLRTokenBuffer *input) : %s(input,%d,%d,%d,%lu)\n",
+ CurrentClassName,
+ (BaseClassName == NULL ? "ANTLRParser" : BaseClassName),
+ OutputLL_k,
+ FoundGuessBlk,
+ DemandLookahead,
+ NumWords(TokenNum-1)*sizeof(unsigned));
+ fprintf(Parser_c, "{\n");
+ fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n");
+ if (TraceGen) {
+ fprintf(Parser_c, "\ttraceOptionValueDefault=1;\t\t// MR10 turn trace ON\n");
+ } else {
+ fprintf(Parser_c, "\ttraceOptionValueDefault=0;\t\t// MR10 turn trace OFF\n");
+ };
+ fprintf(Parser_c, "}\n\n");
+ free ( (void *) hasAkaName);
+}
+
+void
+#ifdef __USE_PROTOS
+GenParser_h_Hdr(void)
+#else
+GenParser_h_Hdr()
+#endif
+{
+ int i;
+
+ fprintf(Parser_h, "/*\n");
+ fprintf(Parser_h, " * %s: P a r s e r H e a d e r \n", CurrentClassName);
+ fprintf(Parser_h, " *\n");
+ fprintf(Parser_h, " * Generated from:");
+ for (i=0; i<NumFiles; i++) fprintf(Parser_h, " %s", FileStr[i]);
+ fprintf(Parser_h, "\n");
+ fprintf(Parser_h, " *\n");
+ fprintf(Parser_h, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(Parser_h, " * Parr Research Corporation\n");
+ fprintf(Parser_h, " * with Purdue University Electrical Engineering\n");
+ fprintf(Parser_h, " * with AHPCRC, University of Minnesota\n");
+ fprintf(Parser_h, " * ANTLR Version %s\n", Version);
+ fprintf(Parser_h, " */\n\n");
+
+ if ( FirstAction != NULL ) dumpAction( FirstAction, Parser_h, 0, -1, 0, 1); /* MR11 MR15b */
+
+ fprintf(Parser_h, "#ifndef %s_h\n", CurrentClassName);
+ fprintf(Parser_h, "#define %s_h\n\n", CurrentClassName);
+
+ fprintf(Parser_h, "#ifndef ANTLR_VERSION\n");
+ fprintf(Parser_h, "#define ANTLR_VERSION %s\n",VersionDef);
+ fprintf(Parser_h, "#endif\n\n");
+
+ if ( GenAST ) fprintf(Parser_h, "class ASTBase;\n");
+ if (TraceGen) {
+ fprintf(Parser_h,"#ifndef zzTRACE_RULES\n"); /* MR20 */
+ fprintf(Parser_h,"#define zzTRACE_RULES\n"); /* MR20 */
+ fprintf(Parser_h,"#endif\n"); /* MR22 */
+ };
+ fprintf(Parser_h, "#include \"%s\"\n\n", APARSER_H);
+
+ if ( HdrAction != NULL ) dumpAction( HdrAction, Parser_h, 0, -1, 0, 1);
+
+/* MR10 */ if (ClassDeclStuff == NULL) {
+/* MR10 */ fprintf(Parser_h, "class %s : public ANTLRParser {\n", CurrentClassName);
+/* MR10 */ } else {
+/* MR10 */ fprintf(Parser_h, "class %s %s {\n",CurrentClassName,ClassDeclStuff);
+/* MR10 */ };
+
+ fprintf(Parser_h, "public:\n"); /* MR1 */
+ fprintf(Parser_h, "\tstatic const ANTLRChar *tokenName(int tk);\n");/* MR1 */
+ fprintf(Parser_h, "\tenum { SET_SIZE = %i };\n",TokenNum-1); /* MR21 */
+ fprintf(Parser_h, "protected:\n");
+ fprintf(Parser_h, "\tstatic const ANTLRChar *_token_tbl[];\n"); /* MR20 */
+ fprintf(Parser_h, "private:\n");
+}
+
+/* Currently, this is only used in !GenCC mode */
+void
+#ifdef __USE_PROTOS
+GenErrHdr( void )
+#else
+GenErrHdr( )
+#endif
+{
+ int i, j;
+ TermEntry *te;
+
+ fprintf(ErrFile, "/*\n");
+ fprintf(ErrFile, " * A n t l r S e t s / E r r o r F i l e H e a d e r\n");
+ fprintf(ErrFile, " *\n");
+ fprintf(ErrFile, " * Generated from:");
+ for (i=0; i<NumFiles; i++) fprintf(ErrFile, " %s", FileStr[i]);
+ fprintf(ErrFile, "\n");
+ fprintf(ErrFile, " *\n");
+ fprintf(ErrFile, " * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(ErrFile, " * Parr Research Corporation\n");
+ fprintf(ErrFile, " * with Purdue University Electrical Engineering\n");
+ fprintf(ErrFile, " * With AHPCRC, University of Minnesota\n");
+ fprintf(ErrFile, " * ANTLR Version %s\n", Version);
+ fprintf(ErrFile, " */\n\n");
+
+ if ( FirstAction != NULL ) dumpAction( FirstAction, ErrFile, 0, -1, 0, 1); /* MR11 MR15b */
+
+ fprintf(ErrFile, "#define ANTLR_VERSION %s\n", VersionDef);
+
+ fprintf(ErrFile, "#include \"pcctscfg.h\"\n");
+ fprintf(ErrFile, "#include \"pccts_stdio.h\"\n");
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ fprintf(ErrFile, "#define %s %s\n", DefaultParserName, ParserName);
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ fprintf(ErrFile, "#include \"%s\"\n", RemapFileName);
+ if ( HdrAction != NULL ) dumpAction( HdrAction, ErrFile, 0, -1, 0, 1 );
+ if ( FoundGuessBlk )
+ {
+ fprintf(ErrFile, "#define ZZCAN_GUESS\n");
+ fprintf(ErrFile, "#include \"pccts_setjmp.h\"\n");
+ }
+ if (TraceGen) {
+ fprintf(ErrFile,"#ifndef zzTRACE_RULES\n"); /* MR20 */
+ fprintf(ErrFile,"#define zzTRACE_RULES\n"); /* MR20 */
+ fprintf(ErrFile,"#endif\n"); /* MR22 */
+ };
+
+ if ( OutputLL_k > 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k);
+#ifdef DUM
+ if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
+#endif
+ fprintf(ErrFile, "#define zzSET_SIZE %lu\n", NumWords(TokenNum-1)*sizeof(unsigned));
+ if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n");
+ fprintf(ErrFile, "#include \"antlr.h\"\n");
+ if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n");
+
+ if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile);
+ /* still need this one as it has the func prototypes */
+ fprintf(ErrFile, "#include \"%s\"\n", DefFileName);
+ fprintf(ErrFile, "#include \"dlgdef.h\"\n");
+ fprintf(ErrFile, "#include \"err.h\"\n\n");
+
+ /* Dump a zztokens for each automaton */
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ {
+ fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1);
+ }
+ else
+ {
+ fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1);
+ }
+ fprintf(ErrFile, "\t/* 00 */\t\"Invalid\"");
+ for (i=1; i<TokenNum-1; i++)
+ {
+ DAWDLE;
+ if ( i == EpToken ) continue;
+ /* remapped to invalid token? */
+ if ( TokenInd!=NULL && TokenInd[i]>=LastTokenCounted )
+ {
+ fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i);
+ continue;
+ }
+ if ( TokenString(i) != NULL ) {
+ te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */
+ if (te == NULL || te->akaString == NULL) { /* MR11 */
+ fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i));
+ } else {
+ fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */
+ }
+ }
+ else
+ {
+ /* look in all lexclasses for the reg expr */
+ for (j=0; j<NumLexClasses; j++)
+ {
+ lexmode(j);
+ if ( ExprString(i) != NULL )
+ {
+ fprintf(ErrFile, ",\n\t/* %02d */\t", i);
+ dumpExpr(ErrFile, ExprString(i));
+ break;
+ }
+ }
+ if ( j>=NumLexClasses )
+ {
+ if ( UserDefdTokens )
+ {
+ fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i);
+ }
+ else
+ fatal_internal(eMsgd("No label or expr for token %d",i));
+ }
+ }
+ }
+ fprintf(ErrFile, "\n};\n");
+}
+
+void
+#ifdef __USE_PROTOS
+dumpExpr( FILE *f, char *e )
+#else
+dumpExpr( f, e )
+FILE *f;
+char *e;
+#endif
+{
+ while ( *e!='\0' )
+ {
+ if ( *e=='\\' && *(e+1)=='\\' )
+ {putc('\\', f); putc('\\', f); e+=2;}
+ else if ( *e=='\\' && *(e+1)=='"' )
+ {putc('\\', f); putc('"', f); e+=2;}
+ else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;}
+ else {putc(*e, f); e++;}
+ }
+}
+
+int
+#ifdef __USE_PROTOS
+isTermEntryTokClass(TermEntry *te)
+#else
+isTermEntryTokClass(te)
+TermEntry *te;
+#endif
+{
+ ListNode *t;
+ TCnode *p;
+ TermEntry *q;
+ char *tokstr;
+
+ if (tclasses == NULL) return 0;
+
+ for (t = tclasses->next; t!=NULL; t=t->next)
+ {
+ p = (TCnode *) t->elem;
+ tokstr = TokenString(p->tok);
+ lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */
+ q = (TermEntry *) hash_get(Tname, tokstr);
+ if (q == te) return 1;
+ }
+ return 0;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/build.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/build.c
new file mode 100644
index 00000000..ec0c1158
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/build.c
@@ -0,0 +1,813 @@
+/*
+ * build.c -- functions associated with building syntax diagrams.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "pcctscfg.h"
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+
+#define SetBlk(g, t, approx, first_set_symbol) { \
+ ((Junction *)g.left)->jtype = t; \
+ ((Junction *)g.left)->approx = approx; \
+ ((Junction *)g.left)->pFirstSetSymbol = first_set_symbol; \
+ ((Junction *)g.left)->end = (Junction *) g.right; \
+ ((Junction *)g.right)->jtype = EndBlk;}
+
+/* Add the parameter string 'parm' to the parms field of a block-type junction
+ * g.left points to the sentinel node on a block. i.e. g.left->p1 points to
+ * the actual junction with its jtype == some block-type.
+ */
+void
+#ifdef __USE_PROTOS
+addParm( Node *p, char *parm )
+#else
+addParm( p, parm )
+Node *p;
+char *parm;
+#endif
+{
+ char *q = (char *) malloc( strlen(parm) + 1 );
+ require(p!=NULL, "addParm: NULL object\n");
+ require(q!=NULL, "addParm: unable to alloc parameter\n");
+
+ strcpy(q, parm);
+ if ( p->ntype == nRuleRef )
+ {
+ ((RuleRefNode *)p)->parms = q;
+ }
+ else if ( p->ntype == nJunction )
+ {
+ ((Junction *)p)->parm = q; /* only one parameter allowed on subrules */
+ }
+ else fatal_internal("addParm: invalid node for adding parm");
+}
+
+/*
+ * Build an action node for the syntax diagram
+ *
+ * buildAction(ACTION) ::= --o-->ACTION-->o--
+ *
+ * Where o is a junction node.
+ */
+Graph
+#ifdef __USE_PROTOS
+buildAction( char *action, int file, int line, int is_predicate )
+#else
+buildAction( action, file, line, is_predicate )
+char *action;
+int file;
+int line;
+int is_predicate;
+#endif
+{
+ Junction *j1, *j2;
+ Graph g;
+ ActionNode *a;
+ require(action!=NULL, "buildAction: invalid action");
+
+ j1 = newJunction();
+ j2 = newJunction();
+ a = newActionNode();
+ a->action = (char *) malloc( strlen(action)+1 );
+ require(a->action!=NULL, "buildAction: cannot alloc space for action\n");
+ strcpy(a->action, action);
+ j1->p1 = (Node *) a;
+ a->next = (Node *) j2;
+ a->is_predicate = is_predicate;
+
+ if (is_predicate) {
+ PredEntry *predEntry;
+ char *t;
+ char *key;
+ char *u;
+ int inverted=0;
+
+ t=key=(char *)calloc(1,strlen(a->action)+1);
+
+ for (u=a->action; *u != '\0' ; u++) {
+ if (*u != ' ') {
+ if (t==key && *u=='!') {
+ inverted=!inverted;
+ } else {
+ *t++=*u;
+ };
+ };
+ };
+
+ *t='\0';
+
+
+ predEntry=(PredEntry *)hash_get(Pname,key);
+ a->predEntry=predEntry;
+ if (predEntry != NULL) a->inverted=inverted;
+ } else {
+/* MR12c */ char *strStart=a->action;
+/* MR12c */ char *strEnd;
+/* MR12c */ strEnd=strStart+strlen(strStart)-1;
+/* MR12c */ for ( ; strEnd >= strStart && isspace(*strEnd); strEnd--) *strEnd=0;
+/* MR12c */ while (*strStart != '\0' && isspace(*strStart)) strStart++;
+/* MR12c */ if (ci_strequ(strStart,"nohoist")) {
+/* MR12c */ a->noHoist=1;
+/* MR12c */ }
+ }
+
+ g.left = (Node *) j1; g.right = (Node *) j2;
+ a->file = file;
+ a->line = line;
+ a->rname = CurRule; /* MR10 */
+ return g;
+}
+
+/*
+ * Build a token node for the syntax diagram
+ *
+ * buildToken(TOKEN) ::= --o-->TOKEN-->o--
+ *
+ * Where o is a junction node.
+ */
+Graph
+#ifdef __USE_PROTOS
+buildToken( char *text )
+#else
+buildToken( text )
+char *text;
+#endif
+{
+ Junction *j1, *j2;
+ Graph g;
+ TokNode *t;
+ require(text!=NULL, "buildToken: invalid token name");
+
+ j1 = newJunction();
+ j2 = newJunction();
+ t = newTokNode();
+ t->altstart = CurAltStart;
+ if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}
+ else {t->label=TRUE; t->token = addTname( text );}
+ j1->p1 = (Node *) t;
+ t->next = (Node *) j2;
+ g.left = (Node *) j1; g.right = (Node *) j2;
+ return g;
+}
+
+/*
+ * Build a wild-card node for the syntax diagram
+ *
+ * buildToken(TOKEN) ::= --o-->'.'-->o--
+ *
+ * Where o is a junction node.
+ */
+Graph
+#ifdef __USE_PROTOS
+buildWildCard( char *text )
+#else
+buildWildCard( text )
+char *text;
+#endif
+{
+ Junction *j1, *j2;
+ Graph g;
+ TokNode *t;
+ TCnode *w;
+ TermEntry *p;
+ require(text!=NULL, "buildWildCard: invalid token name");
+
+ j1 = newJunction();
+ j2 = newJunction();
+ t = newTokNode();
+
+ /* If the ref a wild card, make a token class for it */
+ if ( Tnum(WildCardString) == 0 )
+ {
+ w = newTCnode;
+ w->tok = addTname( WildCardString );
+ set_orel(w->tok, &imag_tokens);
+ set_orel(w->tok, &tokclasses);
+ WildCardToken = w->tok;
+ require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,
+ "hash table mechanism is broken");
+ p->classname = 1; /* entry is class name, not token */
+ p->tclass = w; /* save ptr to this tclass def */
+ list_add(&tclasses, (char *)w);
+ }
+ else {
+ p=(TermEntry *)hash_get(Tname, WildCardString);
+ require( p!= NULL, "hash table mechanism is broken");
+ w = p->tclass;
+ }
+
+ t->token = w->tok;
+ t->wild_card = 1;
+ t->tclass = w;
+
+ t->altstart = CurAltStart;
+ j1->p1 = (Node *) t;
+ t->next = (Node *) j2;
+ g.left = (Node *) j1; g.right = (Node *) j2;
+ return g;
+}
+
+void
+#ifdef __USE_PROTOS
+setUpperRange(TokNode *t, char *text)
+#else
+setUpperRange(t, text)
+TokNode *t;
+char *text;
+#endif
+{
+ require(t!=NULL, "setUpperRange: NULL token node");
+ require(text!=NULL, "setUpperRange: NULL token string");
+
+ if ( *text == '"' ) {t->upper_range = addTexpr( text );}
+ else {t->upper_range = addTname( text );}
+}
+
+/*
+ * Build a rule reference node of the syntax diagram
+ *
+ * buildRuleRef(RULE) ::= --o-->RULE-->o--
+ *
+ * Where o is a junction node.
+ *
+ * If rule 'text' has been defined already, don't alloc new space to store string.
+ * Set r->text to point to old copy in string table.
+ */
+Graph
+#ifdef __USE_PROTOS
+buildRuleRef( char *text )
+#else
+buildRuleRef( text )
+char *text;
+#endif
+{
+ Junction *j1, *j2;
+ Graph g;
+ RuleRefNode *r;
+ RuleEntry *p;
+ require(text!=NULL, "buildRuleRef: invalid rule name");
+
+ j1 = newJunction();
+ j2 = newJunction();
+ r = newRNode();
+ r->altstart = CurAltStart;
+ r->assign = NULL;
+ if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;
+ else r->text = mystrdup( text );
+ j1->p1 = (Node *) r;
+ r->next = (Node *) j2;
+ g.left = (Node *) j1; g.right = (Node *) j2;
+ return g;
+}
+
+/*
+ * Or two subgraphs into one graph via:
+ *
+ * Or(G1, G2) ::= --o-G1-o--
+ * | ^
+ * v |
+ * o-G2-o
+ *
+ * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.
+ * If, however, the G1 altnum is 0, make it 1 and then
+ * make G2 altnum = G1 altnum + 1.
+ */
+Graph
+#ifdef __USE_PROTOS
+Or( Graph g1, Graph g2 )
+#else
+Or( g1, g2 )
+Graph g1;
+Graph g2;
+#endif
+{
+ Graph g;
+ require(g1.left != NULL, "Or: invalid graph");
+ require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");
+
+ ((Junction *)g1.left)->p2 = g2.left;
+ ((Junction *)g2.right)->p1 = g1.right;
+ /* set altnums */
+ if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
+ ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;
+ g.left = g2.left;
+ g.right = g1.right;
+ return g;
+}
+
+/*
+ * Catenate two subgraphs
+ *
+ * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--
+ * Cat(NULL,G2)::= --o-G2-o--
+ * Cat(G1,NULL)::= --o-G1-o--
+ */
+Graph
+#ifdef __USE_PROTOS
+Cat( Graph g1, Graph g2 )
+#else
+Cat( g1, g2 )
+Graph g1;
+Graph g2;
+#endif
+{
+ Graph g;
+
+ if ( g1.left == NULL && g1.right == NULL ) return g2;
+ if ( g2.left == NULL && g2.right == NULL ) return g1;
+ ((Junction *)g1.right)->p1 = g2.left;
+ g.left = g1.left;
+ g.right = g2.right;
+ return g;
+}
+
+/*
+ * Make a subgraph an optional block
+ *
+ * makeOpt(G) ::= --o-->o-G-o-->o--
+ * | ^
+ * v |
+ * o-------o
+ *
+ * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.
+ *
+ * The node on the far right is added so that every block owns its own
+ * EndBlk node.
+ */
+Graph
+#ifdef __USE_PROTOS
+makeOpt( Graph g1, int approx, char * pFirstSetSymbol )
+#else
+makeOpt( g1, approx, pFirstSetSymbol )
+Graph g1;
+int approx;
+char * pFirstSetSymbol;
+#endif
+{
+ Junction *j1,*j2,*p;
+ Graph g;
+ require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");
+
+ j1 = newJunction();
+ j2 = newJunction();
+ ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
+
+ /* MR21
+ *
+ * There is code in genBlk which recognizes the node created
+ * by emptyAlt() as a special case and bypasses it. We don't
+ * want this to happen for the optBlk.
+ */
+
+ g = emptyAlt3(); /* MR21 */
+ if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
+ ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;
+ for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)
+ {;} /* find last alt */
+ p->p2 = g.left; /* add optional alternative */
+ ((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */
+ g1.right = (Node *)j2;
+ SetBlk(g1, aOptBlk, approx, pFirstSetSymbol);
+ j1->p1 = g1.left; /* add generic node in front */
+ g.left = (Node *) j1;
+ g.right = g1.right;
+ return g;
+}
+
+/*
+ * Make a graph into subblock
+ *
+ * makeBlk(G) ::= --o-->o-G-o-->o--
+ *
+ * The node on the far right is added so that every block owns its own
+ * EndBlk node.
+ */
+Graph
+#ifdef __USE_PROTOS
+makeBlk( Graph g1, int approx, char * pFirstSetSymbol )
+#else
+makeBlk( g1, approx, pFirstSetSymbol )
+Graph g1;
+int approx;
+char * pFirstSetSymbol;
+#endif
+{
+ Junction *j,*j2;
+ Graph g;
+ require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");
+
+ j = newJunction();
+ j2 = newJunction();
+ ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
+ g1.right = (Node *)j2;
+ SetBlk(g1, aSubBlk, approx, pFirstSetSymbol);
+ j->p1 = g1.left; /* add node in front */
+ g.left = (Node *) j;
+ g.right = g1.right;
+
+ return g;
+}
+
+/*
+ * Make a subgraph into a loop (closure) block -- (...)*
+ *
+ * makeLoop(G) ::= |---|
+ * v |
+ * --o-->o-->o-G-o-->o--
+ * | ^
+ * v |
+ * o-----------o
+ *
+ * After making loop, always place generic node out front. It becomes
+ * the start of enclosing block. The aLoopBlk is the target of the loop.
+ *
+ * Loop blks have TWO EndBlk nodes--the far right and the node that loops back
+ * to the aLoopBlk node. Node with which we can branch past loop == aLoopBegin and
+ * one which is loop target == aLoopBlk.
+ * The branch-past (initial) aLoopBegin node has end
+ * pointing to the last EndBlk node. The loop-target node has end==NULL.
+ *
+ * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.
+ */
+Graph
+#ifdef __USE_PROTOS
+makeLoop( Graph g1, int approx, char * pFirstSetSymbol )
+#else
+makeLoop( g1, approx, pFirstSetSymbol)
+Graph g1;
+int approx;
+char * pFirstSetSymbol;
+#endif
+{
+ Junction *back, *front, *begin;
+ Graph g;
+ require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");
+
+ back = newJunction();
+ front = newJunction();
+ begin = newJunction();
+ g = emptyAlt3();
+ ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */
+ ((Junction *)g1.right)->p1 = (Node *) back; /* add node to G at end */
+ ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */
+ ((Junction *)g1.left)->jtype = aLoopBlk; /* mark 2nd aLoopBlk node */
+ ((Junction *)g1.left)->end = (Junction *) g1.right;
+ ((Junction *)g1.left)->lock = makelocks();
+ ((Junction *)g1.left)->pred_lock = makelocks();
+ g1.right = (Node *) back;
+ begin->p1 = (Node *) g1.left;
+ g1.left = (Node *) begin;
+ begin->p2 = (Node *) g.left; /* make bypass arc */
+ ((Junction *)g.right)->p1 = (Node *) back;
+ SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol);
+ front->p1 = g1.left; /* add node to front */
+ g1.left = (Node *) front;
+
+ return g1;
+}
+
+/*
+ * Make a subgraph into a plus block -- (...)+ -- 1 or more times
+ *
+ * makePlus(G) ::= |---|
+ * v |
+ * --o-->o-G-o-->o--
+ *
+ * After making loop, always place generic node out front. It becomes
+ * the start of enclosing block. The aPlusBlk is the target of the loop.
+ *
+ * Plus blks have TWO EndBlk nodes--the far right and the node that loops back
+ * to the aPlusBlk node.
+ *
+ * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.
+ */
+Graph
+#ifdef __USE_PROTOS
+makePlus( Graph g1, int approx, char * pFirstSetSymbol)
+#else
+makePlus( g1, approx, pFirstSetSymbol)
+Graph g1;
+int approx;
+char * pFirstSetSymbol;
+#endif
+{
+ int has_empty_alt_already = 0;
+ Graph g;
+ Junction *j2, *j3, *first_alt;
+ Junction *last_alt=NULL, *p;
+ require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");
+
+ first_alt = (Junction *)g1.left;
+ j2 = newJunction();
+ j3 = newJunction();
+ if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
+ ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */
+ ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
+ ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */
+ g1.right = (Node *) j2;
+ SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol);
+ ((Junction *)g1.left)->lock = makelocks();
+ ((Junction *)g1.left)->pred_lock = makelocks();
+ j3->p1 = g1.left; /* add node to front */
+ g1.left = (Node *) j3;
+
+ /* add an optional branch which is the "exit" branch of loop */
+ /* FIRST, check to ensure that there does not already exist
+ * an optional path.
+ */
+ /* find last alt */
+ for(p=first_alt; p!=NULL; p=(Junction *)p->p2)
+ {
+ if ( p->p1->ntype == nJunction &&
+ p->p1!=NULL &&
+ ((Junction *)p->p1)->jtype==Generic &&
+ ((Junction *)p->p1)->p1!=NULL &&
+ ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )
+ {
+ has_empty_alt_already = 1;
+ }
+ last_alt = p;
+ }
+ if ( !has_empty_alt_already )
+ {
+ require(last_alt!=NULL, "last_alt==NULL; bad (..)+");
+ g = emptyAlt();
+ last_alt->p2 = g.left;
+ ((Junction *)g.right)->p1 = (Node *) j2;
+
+ /* make sure lookahead computation ignores this alt for
+ * FIRST("(..)+"); but it's still used for computing the FIRST
+ * of each alternative.
+ */
+ ((Junction *)g.left)->ignore = 1;
+ }
+
+ return g1;
+}
+
+/*
+ * Return an optional path: --o-->o--
+ */
+
+Graph
+#ifdef __USE_PROTOS
+emptyAlt( void )
+#else
+emptyAlt( )
+#endif
+{
+ Junction *j1, *j2;
+ Graph g;
+
+ j1 = newJunction();
+ j2 = newJunction();
+ j1->p1 = (Node *) j2;
+ g.left = (Node *) j1;
+ g.right = (Node *) j2;
+
+ return g;
+}
+
+/* MR21
+ *
+ * There is code in genBlk which recognizes the node created
+ * by emptyAlt() as a special case and bypasses it. We don't
+ * want this to happen for the optBlk.
+ */
+
+Graph
+#ifdef __USE_PROTOS
+emptyAlt3( void )
+#else
+emptyAlt3( )
+#endif
+{
+ Junction *j1, *j2, *j3;
+ Graph g;
+
+ j1 = newJunction();
+ j2 = newJunction();
+ j3 = newJunction();
+ j1->p1 = (Node *) j2;
+ j2->p1 = (Node *) j3;
+ g.left = (Node *) j1;
+ g.right = (Node *) j3;
+
+ return g;
+}
+
+/* N o d e A l l o c a t i o n */
+
+TokNode *
+#ifdef __USE_PROTOS
+newTokNode( void )
+#else
+newTokNode( )
+#endif
+{
+ static TokNode *FreeList = NULL;
+ TokNode *p, *newblk;
+
+ if ( FreeList == NULL )
+ {
+ newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));
+ if ( newblk == NULL )
+ fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
+ for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)
+ {
+ p->next = (Node *)FreeList; /* add all new token nodes to FreeList */
+ FreeList = p;
+ }
+ }
+ p = FreeList;
+ FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */
+ p->next = NULL; /* NULL the ptr we used */
+ memset( (char *) p, 0, sizeof(TokNode)); /* MR10 */
+ p->ntype = nToken;
+ p->rname = CurRule;
+ p->file = CurFile;
+ p->line = zzline;
+ p->altstart = NULL;
+
+ return p;
+}
+
+RuleRefNode *
+#ifdef __USE_PROTOS
+newRNode( void )
+#else
+newRNode( )
+#endif
+{
+ static RuleRefNode *FreeList = NULL;
+ RuleRefNode *p, *newblk;
+
+ if ( FreeList == NULL )
+ {
+ newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));
+ if ( newblk == NULL )
+ fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
+ for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)
+ {
+ p->next = (Node *)FreeList; /* add all new rref nodes to FreeList */
+ FreeList = p;
+ }
+ }
+ p = FreeList;
+ FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */
+ p->next = NULL; /* NULL the ptr we used */
+ memset( (char *) p, 0, sizeof(RuleRefNode)); /* MR10 */
+ p->ntype = nRuleRef;
+ p->rname = CurRule;
+ p->file = CurFile;
+ p->line = zzline;
+ p->astnode = ASTinclude;
+ p->altstart = NULL;
+
+ return p;
+}
+
+static int junctionSeqNumber=0; /* MR10 */
+
+Junction *
+#ifdef __USE_PROTOS
+newJunction( void )
+#else
+newJunction( )
+#endif
+{
+ static Junction *FreeList = NULL;
+ Junction *p, *newblk;
+
+ if ( FreeList == NULL )
+ {
+ newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));
+ if ( newblk == NULL )
+ fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
+ for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)
+ {
+ p->p1 = (Node *)FreeList; /* add all new Junction nodes to FreeList */
+ FreeList = p;
+ }
+ }
+ p = FreeList;
+ FreeList = (Junction *)FreeList->p1;/* remove a Junction node */
+ p->p1 = NULL; /* NULL the ptr we used */
+ memset( (char *) p, 0, sizeof(Junction)); /* MR10 */
+ p->ntype = nJunction;
+ p->visited = 0;
+ p->jtype = Generic;
+ p->rname = CurRule;
+ p->file = CurFile;
+ p->line = zzline;
+ p->exception_label = NULL;
+ p->fset = (set *) calloc(CLL_k+1, sizeof(set));
+ require(p->fset!=NULL, "cannot allocate fset in newJunction");
+ p->seq=++junctionSeqNumber; /* MR10 */
+
+ return p;
+}
+
+ActionNode *
+#ifdef __USE_PROTOS
+newActionNode( void )
+#else
+newActionNode( )
+#endif
+{
+ static ActionNode *FreeList = NULL;
+ ActionNode *p, *newblk;
+
+ if ( FreeList == NULL )
+ {
+ newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));
+ if ( newblk == NULL )
+ fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
+ for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)
+ {
+ p->next = (Node *)FreeList; /* add all new Action nodes to FreeList */
+ FreeList = p;
+ }
+ }
+ p = FreeList;
+ FreeList = (ActionNode *)FreeList->next;/* remove an Action node */
+ memset( (char *) p, 0, sizeof(ActionNode)); /* MR10 */
+ p->ntype = nAction;
+ p->next = NULL; /* NULL the ptr we used */
+ p->done = 0;
+ p->pred_fail = NULL;
+ p->guardpred = NULL;
+ p->ampersandPred = NULL;
+ return p;
+}
+
+/*
+ * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.
+ * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.
+ * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.
+ *
+ * if ( lock[k]==TRUE ) then we have been here before looking for k tokens
+ * of lookahead.
+ */
+char *
+#ifdef __USE_PROTOS
+makelocks( void )
+#else
+makelocks( )
+#endif
+{
+ char *p = (char *) calloc(CLL_k+1, sizeof(char));
+ require(p!=NULL, "cannot allocate lock array");
+
+ return p;
+}
+
+#if 0
+** #ifdef __USE_PROTOS
+** void my_memset(char *p,char value,int count)
+** #else
+** void my_memset(p,value,count)
+** char *p;
+** char value;
+** int count;
+** #endif
+** {
+** int i;
+**
+** for (i=0; i<count; i++) {
+** p[i]=value;
+** };
+** }
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpcycles.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpcycles.c
new file mode 100644
index 00000000..78e39fd6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpcycles.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <ctype.h>
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+void
+#ifdef __USE_PROTOS
+dumpcycles(void)
+#else
+dumpcycles()
+#endif
+{
+ Cycle *c;
+ CacheEntry *f;
+ ListNode *p;
+ int i=0;
+ int k;
+ int degree;
+
+ for (k=1; k <= CLL_k; k++) {
+ if (Cycles[k] == NULL) continue;
+
+ for (p = Cycles[k]->next; p!=NULL; p=p->next) {
+ c = (Cycle *) p->elem;
+ degree=set_deg(c->cyclicDep);
+ fprintf(stderr,"Cycle %d: (degree %d) %s -->\n", i++, degree, RulePtr[c->croot]->rname);
+ fprintf(stderr," *self*\n");
+ MR_dumpRuleSet(c->cyclicDep);
+ fprintf(stderr,"\n");
+ f = (CacheEntry *)
+ hash_get(Fcache,Fkey(RulePtr[c->croot]->rname,'o',k));
+ if (f == NULL) {
+ fprintf(stderr," *** FOLLOW(%s) must be in cache but isn't ***\n",
+ RulePtr[c->croot]->rname);
+ };
+ };
+ };
+}
+
+void
+#ifdef __USE_PROTOS
+dumpfostack(int k)
+#else
+dumpfostack(k)
+int k;
+#endif
+{
+ int i=0;
+ int *pi;
+
+ fprintf(stderr,"\n");
+ if (FoStack[k] == NULL) {
+ fprintf(stderr,"FoStack[%d] is null\n",k);
+ };
+ if (FoTOS[k] == NULL) {
+ fprintf(stderr,"FoTOS[%d] is null\n",k);
+ }
+ if (FoTOS[k] != NULL && FoStack[k] != NULL) {
+ for (pi=FoStack[k]; pi <= FoTOS[k]; pi++) {
+ i++;
+ fprintf(stderr,"#%d rule %d %s\n",i,*pi,RulePtr[*pi]->rname);
+ }
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpnode.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpnode.c
new file mode 100644
index 00000000..7a9c6a7d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/dumpnode.c
@@ -0,0 +1,423 @@
+#include <stdio.h>
+#include <ctype.h>
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+#ifdef __USE_PROTOS
+void dumpset1(set s)
+#else
+void dumpset1(s)
+ set s;
+#endif
+{
+ if (set_nil(s)) {
+ fprintf(stderr,"{}");
+ } else {
+ s_fprT(stderr,s);
+ };
+}
+
+#ifdef __USE_PROTOS
+void dumpset(set s)
+#else
+void dumpset(s)
+ set s;
+#endif
+{
+ dumpset1(s);
+ fprintf(stderr,"\n");
+}
+
+#ifdef __USE_PROTOS
+int isEndRule(Node * p)
+#else
+int isEndRule(p)
+ Node * p;
+#endif
+{
+ int result=0;
+ if ( p->ntype == nJunction &&
+ ( (Junction *) p)->jtype == EndRule) {
+ result=1;
+ };
+ return result;
+}
+
+#ifdef __USE_PROTOS
+void dumppred1(int depth,Predicate *p)
+#else
+void dumppred1(depth,p)
+ int depth;
+ Predicate *p;
+#endif
+{
+ int i;
+ int k;
+
+ for (i=0; i<depth ; i++) {
+ fprintf(stderr," ");
+ };
+ if (p->expr == PRED_AND_LIST ||
+ p->expr == PRED_OR_LIST) {
+ fprintf(stderr," %s", (p->expr == NULL ? "null expr" : p->expr));
+ if (p->inverted) fprintf(stderr," predicate inverted !");
+ if (p->redundant) {
+ fprintf(stderr," Redundant!");
+ };
+ if (p->isConst) fprintf(stderr," const %d !",p->constValue);
+ fprintf(stderr,"\n");
+ } else {
+ fprintf(stderr,"predicate k=%d",p->k);
+ k=set_int(p->completionSet);
+ if (k >= 0) {
+ fprintf(stderr," Incomplete Set=%d !",k);
+ };
+ k=set_int(p->completionTree);
+ if (k >= 0) {
+ fprintf(stderr," Incomplete Tree=%d !",k);
+ };
+ if (p->redundant) {
+ fprintf(stderr," Redundant!");
+ };
+ fprintf(stderr," \"%s\" (%x)", (p->expr == NULL ? "null expr" : p->expr) ,p);
+ if (p->source != NULL) {
+ fprintf(stderr,"line %d",p->source->line);
+ };
+ if (p->inverted) fprintf(stderr," predicate inverted !");
+ fprintf(stderr,"\n");
+ for (i=0; i<depth ; i++) {
+ fprintf(stderr," ");
+ };
+ fprintf(stderr,"scontext: ");
+ dumpset(p->scontext[1]);
+ for (i=0; i<depth ; i++) {
+ fprintf(stderr," ");
+ };
+ fprintf(stderr,"tcontext: ");
+ preorder(p->tcontext);
+ fprintf(stderr,"\n");
+ };
+ fprintf(stderr,"\n");
+ if (p->down != NULL) {
+ dumppred1(depth+1,p->down);
+ };
+ if (p->right != NULL) {
+ dumppred1(depth,p->right);
+ };
+}
+
+#ifdef __USE_PROTOS
+void dumppred(Predicate *p)
+#else
+void dumppred(p)
+ Predicate *p;
+#endif
+{
+ fprintf(stderr,"---------------------------------\n");
+ dumppred1(0,p);
+ fprintf(stderr,"\n");
+}
+
+#ifdef __USE_PROTOS
+void dumppredtree(Predicate *p)
+#else
+void dumppredtree(p)
+ Predicate *p;
+#endif
+{
+ fprintf(stderr,"predicate k=%d \"%s\" line %d\n",p->k,p->expr,p->source->line);
+ dumpset(p->scontext[1]);
+}
+
+#ifdef __USE_PROTOS
+void dumppredexpr(Predicate *p)
+#else
+void dumppredexpr(p)
+ Predicate *p;
+#endif
+{
+ fprintf(stderr," pred expr \"%s\"\n",p->expr);
+}
+
+#ifdef __USE_PROTOS
+void dt(Tree *t)
+#else
+void dt(t)
+ Tree *t;
+#endif
+{
+ MR_dumpTreeF(stderr,0,t,5);
+}
+
+#ifdef __USE_PROTOS
+void d(Node * p)
+#else
+void d(p)
+ Node * p;
+#endif
+{
+
+ Junction *j;
+ RuleRefNode *r;
+ TokNode *t;
+ ActionNode *a;
+
+ if (p==NULL) {
+ fprintf(stderr,"dumpNode: Node is NULL");
+ return;
+ };
+
+ switch (p->ntype) {
+ case nJunction :
+ j = (Junction *) p;
+ fprintf(stderr, "Junction (#%d in rule %s line %d) ",j->seq,j->rname,j->line);
+ if (j->guess) fprintf(stderr,"guess block ");
+ switch (j->jtype ) {
+ case aSubBlk :
+ fprintf(stderr,"aSubBlk");
+ break;
+ case aOptBlk :
+ fprintf(stderr,"aOptBlk");
+ break;
+ case aLoopBegin :
+ fprintf(stderr,"aLoopBeginBlk");
+ break;
+ case aLoopBlk :
+ fprintf(stderr,"aLoopBlk");
+ break;
+ case aPlusBlk :
+ fprintf(stderr,"aPlusBlk");
+ break;
+ case EndBlk :
+ fprintf(stderr,"EndBlk");
+ break;
+ case RuleBlk :
+ fprintf(stderr,"RuleBlk");
+ break;
+ case Generic :
+ fprintf(stderr,"Generic");
+ break;
+ case EndRule :
+ fprintf(stderr,"EndRule");
+ break;
+ };
+ if (j->halt) fprintf(stderr," halt!");
+ if (j->p1) fprintf(stderr," p1 valid");
+ if (j->p2) {
+ if (j->p2->ntype == nJunction) {
+ fprintf(stderr," (p2=#%d)",( (Junction *) j->p2)->seq);
+ } else {
+ fprintf(stderr," (p2 valid)");
+ };
+ };
+ if (j->ignore) fprintf(stderr, " ignore/plus-block-bypass");
+ if (j->fset != NULL && set_deg(*j->fset) != 0) {
+ fprintf(stderr,"\nfset:\n");
+ dumpset(*j->fset);
+ };
+ if (j->ftree != NULL) {
+ fprintf(stderr,"\nftree:\n");
+ preorder(j->ftree);
+ };
+ fprintf(stderr,"\n");
+ break;
+ case nRuleRef :
+ r = (RuleRefNode *) p;
+ fprintf(stderr, "RuleRefNode (in rule %s line %d) to rule %s\n", r->rname,r->line,r->text);
+ break;
+ case nToken :
+ t = (TokNode *) p;
+ fprintf(stderr, "TokNode (in rule %s line %d) token %s\n",t->rname,t->line,TerminalString(t->token));
+ break;
+ case nAction :
+ a =(ActionNode *) p;
+ if (a->is_predicate) {
+ fprintf(stderr, "Predicate (in rule %s line %d) %s",a->rname,a->line,a->action);
+ if (a->inverted) fprintf(stderr," action inverted !");
+ if (a->guardpred != NULL) {
+ fprintf(stderr," guarded");
+ dumppredexpr(a->guardpred);
+ if (a->ampersandPred) {
+ fprintf(stderr," \"&&\" style");
+ } else {
+ fprintf(stderr," \"=>\" style");
+ };
+ };
+ if (a->predEntry != NULL) fprintf(stderr," predEntry \"%s\" ",a->predEntry->str);
+ fprintf(stderr,"\n");
+ } else if (a->init_action) {
+ fprintf(stderr, "Init-Action (in rule %s line %d) %s\n",a->rname,a->line,a->action);
+ } else {
+ fprintf(stderr, "Action (in rule %s line %d) %s\n",a->rname,a->line,a->action);
+ };
+ break;
+ };
+}
+
+#ifdef __USE_PROTOS
+Node * dp1(Node * p)
+#else
+Node * dp1(p)
+ Node * p;
+#endif
+{
+ Node *result=NULL;
+
+ if (p->ntype == nJunction) {
+ result=( (Junction *) p )->p1;
+ d(result);
+ } else {
+ fprintf(stderr,"dp1: Not a Junction node");
+ };
+ return result;
+}
+
+#ifdef __USE_PROTOS
+Node * dp2(Node * p)
+#else
+Node * dp2(p)
+ Node * p;
+#endif
+{
+ Node *result=NULL;
+
+ if (p->ntype == nJunction) {
+ result=( (Junction *) p )->p2;
+ d(result);
+ } else {
+ fprintf(stderr,"dp2: Not a Junction node");
+ };
+ return result;
+}
+
+#ifdef __USE_PROTOS
+Node * dn(Node * p)
+#else
+Node * dn(p)
+ Node * p;
+#endif
+
+{
+ Node *result=NULL;
+
+ if (p->ntype == nRuleRef) {
+ result=( (RuleRefNode *)p )->next;
+ } else if (p->ntype == nAction) {
+ result=( (ActionNode *)p )->next;
+ } else if (p->ntype == nToken) {
+ result=( (TokNode *)p )->next;
+ } else {
+ fprintf(stderr,"No next field: Neither a RuleRefNode, ActionNode, nor TokNode");
+ };
+ if (result != NULL) d(result);
+ return result;
+}
+
+#ifdef __USE_PROTOS
+void df(Node * p)
+#else
+void df(p)
+ Node * p;
+#endif
+{
+ int count=0;
+ Node *next;
+
+ fprintf(stderr,"\n#%d ",++count);
+ d(p);
+
+ for (next=p; next != NULL && !isEndRule(next) ; ) {
+ fprintf(stderr,"#%d ",++count);
+ if (next->ntype == nJunction) {
+ next=dp1(next);
+ } else {
+ next=dn(next);
+ };
+ };
+}
+
+#ifdef __USE_PROTOS
+Node * dfn(Node * p,int target)
+#else
+Node * dfn(p,target)
+ Node * p;
+ int target;
+#endif
+{
+ Node *result=NULL;
+ int count=0;
+ Node *next;
+
+ fprintf(stderr,"#%d ",++count);
+ d(p);
+
+ for (next=p; next != NULL && !isEndRule(next) ; ) {
+ fprintf(stderr,"#%d ",++count);
+ if (next->ntype == nJunction) {
+ next=dp1(next);
+ } else {
+ next=dn(next);
+ };
+ if (count == target) {
+ result=next;
+ break;
+ };
+ };
+ return result;
+}
+
+
+static int findnodeMatch;
+
+#ifdef __USE_PROTOS
+Junction *findnode1(Node *n)
+#else
+Junction *findnode1(n)
+ Node *n;
+#endif
+{
+ Node *next;
+ Junction *j;
+ Junction *match;
+
+ if (n == NULL) return NULL;
+ if (n->ntype == nJunction) {
+ j=(Junction *) n;
+ if (j->seq == findnodeMatch) return j;
+ if (j->jtype == EndRule) return NULL;
+ if (j->jtype != RuleBlk && j->jtype != EndBlk) {
+ if (j->p2 != NULL && !j->ignore) {
+ match=findnode1(j->p2);
+ if (match != NULL) return match;
+ };
+ };
+ };
+ next=MR_advance(n);
+ return findnode1(next);
+}
+
+#ifdef __USE_PROTOS
+Junction *findnode(int match)
+#else
+Junction *findnode(match)
+ int match;
+#endif
+{
+ Junction *j;
+ Junction *result=NULL;
+
+ findnodeMatch=match;
+
+ for (j=SynDiag; j != NULL; j=(Junction *)j->p2) {
+ require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block");
+ result=findnode1( (Node *) j);
+ if (result != NULL) break;
+ };
+ if (result != NULL) {
+ d( (Node *) result);
+ };
+ return result;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/egman.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/egman.c
new file mode 100644
index 00000000..1bbc9283
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/egman.c
@@ -0,0 +1,328 @@
+/*
+ * egman.c
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33MR10
+ * 2001
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "proto.h"
+
+static ExceptionGroup **egArray=NULL; /* ExceptionGroup by BlkLevel */
+static LabelEntry **leArray=NULL; /* LabelEntry by BlkLevel */
+static Junction **altArray=NULL; /* start of alternates */
+static int arraySize=0;
+static int highWater=0;
+static ExceptionGroup *lastEG=NULL; /* used in altFixup() */
+static int lastBlkLevel=0; /* used in altFixup() */
+
+#ifdef __USE_PROTOS
+static void arrayCheck(void);
+#else
+static void arrayCheck();
+#endif
+
+/* Called to add an exception group for an alternative EG */
+
+#ifdef __USE_PROTOS
+void egAdd(ExceptionGroup * eg)
+#else
+void egAdd(eg)
+ExceptionGroup *eg;
+#endif
+{
+ int i;
+
+ ExceptionGroup *nextEG;
+ ExceptionGroup *innerEG;
+
+ LabelEntry *nextLE;
+ LabelEntry *innerLE;
+
+ Junction *nextAlt;
+ Junction *innerAlt;
+
+ lastEG=eg;
+ lastBlkLevel=BlkLevel;
+
+ arrayCheck();
+ eg->pendingLink=egArray[BlkLevel];
+ egArray[BlkLevel]=eg;
+
+ /* EG for alternates already have their altID filled in */
+
+ for (i=BlkLevel+1; i<=highWater ; i++) {
+ for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {
+ nextEG=innerEG->pendingLink;
+ innerEG->pendingLink=NULL;
+ innerEG->outerEG=eg;
+ };
+ egArray[i]=NULL;
+ };
+
+ /*
+ * for patching up the LabelEntry you might use an EG for the
+ * current alternative - unlike patching up an alternative EG
+ * i.e. start the loop at BlkLevel rather than (BlkLevel+1)
+ * fill it in only if the EG and the LE are for the very
+ * same alternative if they're at the same BlkLevel
+ * it's easier to leave the LE on this list (filled in) rather than
+ * trying to selectively remove it. It will eventually be
+ * removed anyway when the BlkLevel gets small enough.
+ */
+
+ for (i=BlkLevel; i<=highWater ; i++) {
+ for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {
+ nextLE=innerLE->pendingLink;
+ if (BlkLevel != i ||
+ innerLE->curAltNum == CurAltNum_array[BlkLevel]) {
+ if (innerLE->outerEG == NULL) {
+ innerLE->outerEG=eg;
+ };
+ };
+ };
+ if (BlkLevel != i) leArray[i]=NULL;
+ };
+
+/*
+ * For the start of alternatives it is necessary to make a
+ * distinction between the exception group for the current
+ * alternative and the "fallback" EG for the block which
+ * contains the alternative
+ *
+ * The fallback outerEG is used to handle the case where
+ * no alternative of a block matches. In that case the
+ * signal is "NoViableAlt" (or "NoSemViableAlt" and the
+ * generator needs the EG of the block CONTAINING the
+ * current one.
+ *
+ * rule: ( ( ( a
+ * | b
+ * )
+ * | c
+ * )
+ * | d
+ * );
+ */
+
+ for (i=BlkLevel; i <= highWater ; i++) {
+ for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {
+ nextAlt=innerAlt->pendingLink;
+
+ /* first fill in the EG for the current alternative */
+ /* but leave it on the list in order to get the fallback EG */
+ /* if the EG is at the same LEVEL as the alternative then */
+ /* fill it in only if in the very same alternative */
+ /* */
+ /* rule: ( a */
+ /* | b */
+ /* | c exception ... */
+ /* ) */
+ /* */
+ /* if the EG is outside the alternative (e.g. BlkLevel < i) */
+ /* then it doesn't matter about the alternative */
+ /* */
+ /* rule: ( a */
+ /* | b */
+ /* | c */
+ /* ) exception ... */
+ /* */
+
+#if 0
+ printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%s\n",
+ BlkLevel,i,innerAlt->curAltNum,CurAltNum_array[BlkLevel],eg->altID);
+#endif
+ if (BlkLevel != i ||
+ innerAlt->curAltNum == CurAltNum_array[BlkLevel]) {
+ if (innerAlt->exception_label == NULL) {
+ innerAlt->exception_label=eg->altID;
+ };
+ };
+
+ /* occurs at a later pass then for the exception_label */
+ /* if an outerEG has been found then fill in the outer EG */
+ /* remove if from the list when the BlkLevel gets smaller */
+
+ if (BlkLevel != i) {
+ if (innerAlt->outerEG == NULL) {
+ innerAlt->outerEG=eg;
+ };
+ };
+ };
+ if (BlkLevel != i) altArray[i]=NULL;
+ };
+}
+
+#ifdef __USE_PROTOS
+void leAdd(LabelEntry * le)
+#else
+void leAdd(le)
+LabelEntry *le;
+#endif
+
+{
+ arrayCheck();
+ le->pendingLink=leArray[BlkLevel];
+ le->curAltNum=CurAltNum_array[BlkLevel];
+ leArray[BlkLevel]=le;
+}
+
+#ifdef __USE_PROTOS
+void altAdd(Junction *alt)
+#else
+void altAdd(alt)
+Junction *alt;
+#endif
+
+{
+ arrayCheck();
+#if 0
+ printf("BlkLevel=%d CurAltNum=%d\n",
+ BlkLevel,CurAltNum_array[BlkLevel]);
+#endif
+ alt->curAltNum=CurAltNum_array[BlkLevel];
+ alt->pendingLink=altArray[BlkLevel];
+ altArray[BlkLevel]=alt;
+}
+
+static void
+#ifdef __USE_PROTOS
+arrayCheck(void)
+#else
+arrayCheck()
+#endif
+{
+ ExceptionGroup **egArrayNew;
+ LabelEntry **leArrayNew;
+ Junction **altArrayNew;
+ int arraySizeNew;
+ int i;
+
+ if (BlkLevel > highWater) highWater=BlkLevel;
+
+ if (BlkLevel >= arraySize) {
+ arraySizeNew=BlkLevel+5; /* MR20 */
+ egArrayNew=(ExceptionGroup **)
+ calloc(arraySizeNew,sizeof(ExceptionGroup *));
+ leArrayNew=(LabelEntry **)
+ calloc(arraySizeNew,sizeof(LabelEntry *));
+ altArrayNew=(Junction **)
+ calloc(arraySizeNew,sizeof(Junction *));
+ for (i=0; i<arraySize ; i++) {
+ egArrayNew[i]=egArray[i];
+ leArrayNew[i]=leArray[i];
+ altArrayNew[i]=altArray[i];
+ };
+ arraySize=arraySizeNew;
+ if (egArray != NULL) free( (char *) egArray);
+ if (leArray != NULL) free( (char *) leArray);
+ if (altArray != NULL) free( (char *) altArray);
+ egArray=egArrayNew;
+ leArray=leArrayNew;
+ altArray=altArrayNew;
+ };
+}
+
+/* always call leFixup() BEFORE egFixup() */
+
+void
+#ifdef __USE_PROTOS
+egFixup(void)
+#else
+egFixup()
+#endif
+{
+ int i;
+ ExceptionGroup *nextEG;
+ ExceptionGroup *innerEG;
+
+ for (i=1; i<=highWater ; i++) {
+ for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {
+ nextEG=innerEG->pendingLink;
+ innerEG->pendingLink=NULL;
+ };
+ egArray[i]=NULL;
+ };
+ lastEG=NULL;
+ lastBlkLevel=0;
+}
+
+/* always call leFixup() BEFORE egFixup() */
+
+#ifdef __USE_PROTOS
+void leFixup(void)
+#else
+void leFixup()
+#endif
+{
+
+ int i;
+ LabelEntry *nextLE;
+ LabelEntry *innerLE;
+
+ for (i=BlkLevel; i<=highWater ; i++) {
+ for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {
+ nextLE=innerLE->pendingLink;
+ innerLE->pendingLink=NULL;
+ };
+ leArray[i]=NULL;
+ };
+}
+
+/* always call altFixup() BEFORE egFixup() */
+
+#ifdef __USE_PROTOS
+void altFixup(void)
+#else
+void altFixup()
+#endif
+{
+
+ int i;
+ Junction *nextAlt;
+ Junction *innerAlt;
+
+ for (i=BlkLevel; i<=highWater ; i++) {
+ for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {
+
+ /* if an outerEG has been found then fill in the outer EG */
+
+ if (lastBlkLevel <= i) {
+ if (innerAlt->outerEG == NULL) {
+ innerAlt->outerEG=lastEG;
+ };
+ };
+ nextAlt=innerAlt->pendingLink;
+ innerAlt->pendingLink=NULL;
+ };
+ altArray[i]=NULL;
+ };
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/err.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/err.c
new file mode 100644
index 00000000..f3777ba6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/err.c
@@ -0,0 +1,538 @@
+/*
+ * A n t l r S e t s / E r r o r F i l e H e a d e r
+ *
+ * Generated from: antlr.g
+ *
+ * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001
+ * Parr Research Corporation
+ * with Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include "pcctscfg.h"
+#include "set.h"
+#include <ctype.h>
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#define zzcr_attr(attr,tok,t) /*vbox: */ memset((attr), 0, sizeof(*attr))
+#define zzSET_SIZE 20
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "err.h"
+
+ANTLRChar *zztokens[157]={
+ /* 00 */ "Invalid",
+ /* 01 */ "Eof",
+ /* 02 */ "QuotedTerm",
+ /* 03 */ "\\n|\\r|\\r\\n",
+ /* 04 */ "\\(\\n|\\r|\\r\\n)",
+ /* 05 */ "\\~[]",
+ /* 06 */ "~[\\n\\r\"\\]+",
+ /* 07 */ "\"",
+ /* 08 */ "\\n|\\r|\\r\\n",
+ /* 09 */ "\\(\\n|\\r|\\r\\n)",
+ /* 10 */ "\\~[]",
+ /* 11 */ "~[\\n\\r\"\\]+",
+ /* 12 */ "'",
+ /* 13 */ "\\n|\\r|\\r\\n",
+ /* 14 */ "\\~[]",
+ /* 15 */ "~[\\n\\r'\\]+",
+ /* 16 */ "\\*/",
+ /* 17 */ "\\*",
+ /* 18 */ "\\n|\\r|\\r\\n",
+ /* 19 */ "~[\\n\\r\\*]+",
+ /* 20 */ "\\*/",
+ /* 21 */ "\\*",
+ /* 22 */ "\\n|\\r|\\r\\n",
+ /* 23 */ "~[\\n\\r\\*]+",
+ /* 24 */ "\\n|\\r|\\r\\n",
+ /* 25 */ "~[\\n\\r]+",
+ /* 26 */ "\\n|\\r|\\r\\n",
+ /* 27 */ "~[\\n\\r]+",
+ /* 28 */ "\\n|\\r|\\r\\n",
+ /* 29 */ "~[\\n\\r]+",
+ /* 30 */ "\\*/",
+ /* 31 */ "\\*",
+ /* 32 */ "\\n|\\r|\\r\\n",
+ /* 33 */ "~[\\n\\r\\*]+",
+ /* 34 */ "Action",
+ /* 35 */ "Pred",
+ /* 36 */ "PassAction",
+ /* 37 */ "consumeUntil\\( [\\ \\t]* \\{~[\\}]+\\} [\\ \\t]* \\)",
+ /* 38 */ "consumeUntil\\( ~[\\)]+ \\)",
+ /* 39 */ "\\n|\\r|\\r\\n",
+ /* 40 */ "\\>",
+ /* 41 */ "$",
+ /* 42 */ "$$",
+ /* 43 */ "$\\[\\]",
+ /* 44 */ "$\\[",
+ /* 45 */ "$[0-9]+",
+ /* 46 */ "$[0-9]+.",
+ /* 47 */ "$[0-9]+.[0-9]+",
+ /* 48 */ "$[_a-zA-Z][_a-zA-Z0-9]*",
+ /* 49 */ "#0",
+ /* 50 */ "#\\[\\]",
+ /* 51 */ "#\\(\\)",
+ /* 52 */ "#[0-9]+",
+ /* 53 */ "#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)",
+ /* 54 */ "#line ~[\\n\\r]* (\\n|\\r|\\r\\n)",
+ /* 55 */ "#[_a-zA-Z][_a-zA-Z0-9]*",
+ /* 56 */ "#\\[",
+ /* 57 */ "#\\(",
+ /* 58 */ "#",
+ /* 59 */ "\\)",
+ /* 60 */ "\\[",
+ /* 61 */ "\\(",
+ /* 62 */ "\\\\]",
+ /* 63 */ "\\\\)",
+ /* 64 */ "\\>",
+ /* 65 */ "'",
+ /* 66 */ "\"",
+ /* 67 */ "\\$",
+ /* 68 */ "\\#",
+ /* 69 */ "\\(\\n|\\r|\\r\\n)",
+ /* 70 */ "\\~[\\]\\)>$#]",
+ /* 71 */ "/",
+ /* 72 */ "/\\*",
+ /* 73 */ "\\*/",
+ /* 74 */ "//",
+ /* 75 */ "~[\\n\\r\\)\\(\\$#\\>\\]\\[\"'/]+",
+ /* 76 */ "[\\t\\ ]+",
+ /* 77 */ "\\n|\\r|\\r\\n",
+ /* 78 */ "\\[",
+ /* 79 */ "\\<\\<",
+ /* 80 */ "\"",
+ /* 81 */ "/\\*",
+ /* 82 */ "\\*/",
+ /* 83 */ "//",
+ /* 84 */ "#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)",
+ /* 85 */ "#line ~[\\n\\r]* (\\n|\\r|\\r\\n)",
+ /* 86 */ "\\>\\>",
+ /* 87 */ "WildCard",
+ /* 88 */ "\\@",
+ /* 89 */ "LABEL",
+ /* 90 */ "grammar-element",
+ /* 91 */ "meta-symbol",
+ /* 92 */ "Pragma",
+ /* 93 */ "FirstSetSymbol",
+ /* 94 */ "{\\}#header",
+ /* 95 */ "{\\}#first",
+ /* 96 */ "{\\}#parser",
+ /* 97 */ "{\\}#tokdefs",
+ /* 98 */ "\\}",
+ /* 99 */ "class",
+ /* 100 */ "NonTerminal",
+ /* 101 */ "TokenTerm",
+ /* 102 */ "\\{",
+ /* 103 */ "!",
+ /* 104 */ "\\<",
+ /* 105 */ "\\>",
+ /* 106 */ ":",
+ /* 107 */ ";",
+ /* 108 */ "{\\}#lexaction",
+ /* 109 */ "{\\}#lexmember",
+ /* 110 */ "{\\}#lexprefix",
+ /* 111 */ "{\\}#pred",
+ /* 112 */ "\\|\\|",
+ /* 113 */ "&&",
+ /* 114 */ "\\(",
+ /* 115 */ "\\)",
+ /* 116 */ "{\\}#lexclass",
+ /* 117 */ "{\\}#errclass",
+ /* 118 */ "{\\}#tokclass",
+ /* 119 */ "..",
+ /* 120 */ "{\\}#token",
+ /* 121 */ "=",
+ /* 122 */ "[0-9]+",
+ /* 123 */ "\\|",
+ /* 124 */ "\\~",
+ /* 125 */ "^",
+ /* 126 */ "approx",
+ /* 127 */ "LL\\(1\\)",
+ /* 128 */ "LL\\(2\\)",
+ /* 129 */ "\\*",
+ /* 130 */ "\\+",
+ /* 131 */ "?",
+ /* 132 */ "=>",
+ /* 133 */ "exception",
+ /* 134 */ "default",
+ /* 135 */ "catch",
+ /* 136 */ "{\\}#[A-Za-z0-9_]*",
+ /* 137 */ "[\\t\\ ]+",
+ /* 138 */ "\\n|\\r|\\r\\n",
+ /* 139 */ "//",
+ /* 140 */ "/\\*",
+ /* 141 */ "#ifdef",
+ /* 142 */ "#if",
+ /* 143 */ "#ifndef",
+ /* 144 */ "#else",
+ /* 145 */ "#endif",
+ /* 146 */ "#undef",
+ /* 147 */ "#import",
+ /* 148 */ "ID",
+ /* 149 */ "#define",
+ /* 150 */ "INT",
+ /* 151 */ "enum",
+ /* 152 */ "\\{",
+ /* 153 */ "=",
+ /* 154 */ ",",
+ /* 155 */ "\\}",
+ /* 156 */ ";"
+};
+SetWordType zzerr1[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr2[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xf3,
+ 0xbf,0xff,0xff,0xff, 0xff,0xff,0xff,0x1f};
+SetWordType zzerr3[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xfb,
+ 0x3b,0xf7,0xf7,0xc7, 0xff,0xff,0xff,0x1f};
+SetWordType zzerr4[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x80,0x7,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType setwd1[157] = {0x0,0x50,0xa0,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x6a,0x20,0xa0,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x0,0x0,0x20,0x20,0x21,
+ 0x21,0x21,0x21,0x6e,0x6e,0x64,0x20,0x0,
+ 0x20,0xa0,0xa0,0xa0,0x20,0x6a,0x6a,0x6a,
+ 0x6e,0x20,0x20,0x20,0x20,0x66,0x6e,0x6e,
+ 0x20,0x66,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20};
+SetWordType zzerr5[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr6[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x7,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr7[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x6,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr8[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x4,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr9[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf0,0x70,0x1, 0x20,0x0,0x0,0x0};
+SetWordType setwd2[157] = {0x0,0xf8,0x6,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xf8,0x0,0x1,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xf8,0xf8,0xf8,0x0,0x0,
+ 0x0,0x1,0x2,0x6,0x0,0xf8,0xf8,0xf8,
+ 0xf8,0x0,0x0,0x0,0x0,0xf8,0xf8,0xf8,
+ 0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0xe8,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr10[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0xbc,0xf8,0x74,0x1, 0x20,0x0,0x0,0x0};
+SetWordType zzerr11[20] = {0x0,0x0,0x0,0x0, 0x8,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr12[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};
+SetWordType zzerr13[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};
+SetWordType setwd3[157] = {0x0,0xfa,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xfa,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xfa,0xfa,0xfa,0x5,0x0,
+ 0x5,0x0,0x0,0x0,0xe2,0xfa,0xfa,0xfa,
+ 0xfa,0xc0,0x80,0x5,0xe0,0xfa,0xfa,0xfa,
+ 0x0,0xfa,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0xfa,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr14[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr15[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr16[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr17[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr18[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x24,0x0,0x80,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr19[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr20[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x74,0x3, 0x20,0x0,0x0,0x0};
+SetWordType zzerr21[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x70,0x3, 0x20,0x0,0x0,0x0};
+SetWordType setwd4[157] = {0x0,0xe5,0xda,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xe5,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xed,0xe5,0xe7,0x1a,0x0,
+ 0x0,0x0,0x0,0x0,0xc0,0xe5,0xe5,0xe5,
+ 0xe5,0x0,0x0,0x0,0x0,0xe5,0xe5,0xe5,
+ 0x0,0xe5,0x40,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0xe5,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr22[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x3c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};
+SetWordType zzerr23[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};
+SetWordType zzerr24[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};
+SetWordType zzerr25[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0};
+SetWordType zzerr26[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5,
+ 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType setwd5[157] = {0x0,0x1f,0xc1,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xdf,0xc0,0xc0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0xc0,0x0,0xc0,0x0,0x0,0xc0,0xc0,0x0,
+ 0x0,0x0,0x0,0x7f,0x1f,0xdf,0xc0,0xc0,
+ 0x0,0x0,0xc0,0x0,0x67,0x1f,0x1f,0x1f,
+ 0x1f,0x0,0x0,0xc0,0x60,0x1f,0x1f,0x1f,
+ 0x0,0x1f,0x0,0x0,0x40,0xc0,0x0,0x0,
+ 0x0,0x0,0xc0,0xc0,0x0,0x0,0x5f,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr27[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x0,0x0,0x0,0x10, 0x0,0x0,0x0,0x0};
+SetWordType zzerr28[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x2,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr29[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr30[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,
+ 0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0};
+SetWordType zzerr31[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,
+ 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0};
+SetWordType zzerr32[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5,
+ 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr33[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType setwd6[157] = {0x0,0x0,0xfd,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0xfd,0x60,0xe9,0x0,0x0,0xe1,0xe1,0x0,
+ 0x0,0x0,0x0,0xe2,0x0,0xfd,0xfd,0xe1,
+ 0x20,0x0,0xe1,0x0,0xe2,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xe1,0xe2,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0xe2,0xe0,0x20,0x0,
+ 0x0,0x0,0xe1,0xe1,0x0,0x0,0xe2,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr34[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,
+ 0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0};
+SetWordType zzerr35[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd,
+ 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0};
+SetWordType zzerr36[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5,
+ 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr37[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xc,
+ 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0};
+SetWordType zzerr38[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x84,0x9,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr39[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr40[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x4,0x9,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr41[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr42[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x0,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType setwd7[157] = {0x0,0x0,0xdf,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xdf,0xdf,0xff,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0xdf,0x3,0xdf,0x0,0x0,0xdf,0xdf,0x0,
+ 0x0,0x0,0x0,0xdf,0x0,0xdf,0xdf,0xdf,
+ 0x1,0x30,0xdf,0x0,0xdf,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xdf,0xdf,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0xdf,0xdf,0x1,0x0,
+ 0x0,0x0,0xdf,0xdf,0x0,0x0,0xdf,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr43[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr44[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xc0, 0x1,0x0,0x0,0x0};
+SetWordType zzerr45[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x30,
+ 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr46[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr47[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x20,
+ 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr48[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x2,0x0, 0x10,0x0,0x0,0x0};
+SetWordType zzerr49[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0};
+SetWordType zzerr50[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x4,0x8,0xa,0x18, 0x30,0x0,0x0,0x0};
+SetWordType zzerr51[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x4,0x8,0x8,0x18, 0x28,0x0,0x0,0x0};
+SetWordType zzerr52[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr53[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType setwd8[157] = {0x0,0x0,0xe1,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0xe1,0x0,0xe1,0x0,0x0,0xe3,0xe7,0x0,
+ 0x0,0x0,0x0,0xe1,0x0,0xe1,0xe1,0xef,
+ 0x0,0x0,0xe1,0x0,0xe1,0x0,0x0,0x0,
+ 0x0,0x0,0x10,0xef,0xe1,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0xe1,0xe1,0x0,0x0,
+ 0x0,0x0,0xe1,0xe1,0x0,0x10,0xe1,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr54[20] = {0x2,0x0,0x0,0x0, 0x14,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0};
+SetWordType zzerr55[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x78,0x9, 0x60,0x0,0x0,0x0};
+SetWordType zzerr56[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr57[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0};
+SetWordType setwd9[157] = {0x0,0x7c,0x1,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x7f,0x1,0x1,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x1,0x0,0x1,0x0,0x0,0x1,0x1,0x0,
+ 0x0,0x0,0x0,0x7f,0x7e,0x7f,0x1,0x1,
+ 0x0,0x0,0x1,0x0,0x7d,0x7e,0x7e,0x7e,
+ 0x7e,0x0,0x0,0x1,0x7d,0x7e,0x7e,0x7e,
+ 0x0,0x7e,0x0,0x0,0x7d,0x1,0x0,0x0,
+ 0x0,0x0,0x1,0x1,0x0,0x0,0x7f,0x64,
+ 0x64,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x0,
+ 0x80,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr58[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0};
+SetWordType zzerr59[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0};
+SetWordType zzerr60[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0};
+SetWordType zzerr61[20] = {0x2,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0};
+SetWordType zzerr62[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe};
+SetWordType zzerr63[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe};
+SetWordType zzerr64[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe};
+SetWordType zzerr65[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0, 0x0,0x0,0x10,0xc};
+SetWordType setwd10[157] = {0x0,0xc,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,
+ 0x3,0x0,0x0,0xf0,0xf0,0x0};
+SetWordType setwd11[157] = {0x0,0x1,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x1,0x0,0x0,0x0,0x0,0x0};
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fcache.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fcache.c
new file mode 100644
index 00000000..9b7653de
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fcache.c
@@ -0,0 +1,123 @@
+/*
+ * fcache.c
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33MR10
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "pcctscfg.h"
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+#ifdef __USE_PROTOS
+CacheEntry *dumpFcache1(char *prev)
+#else
+CacheEntry *dumpFcache1(prev)
+ char *prev;
+#endif
+{
+ Entry **table=Fcache;
+
+ int low=0;
+ int hi=0;
+
+ CacheEntry *least=NULL;
+
+ Entry **p;
+
+ for (p=table; p<&(table[HashTableSize]); p++) {
+
+ CacheEntry *q =(CacheEntry *) *p;
+
+ if ( q != NULL && low==0 ) low = p-table;
+ while ( q != NULL ) {
+ if (strcmp(q->str,prev) > 0) {
+ if (least == NULL) {
+ least=q;
+ } else {
+ if (strcmp(q->str,least->str) < 0) {
+ least=q;
+ };
+ };
+ };
+ q = q->next;
+ };
+
+ if ( *p != NULL ) hi = p-table;
+ }
+ return least;
+}
+
+#ifdef __USE_PROTOS
+void reportFcache(CacheEntry *q)
+#else
+void reportFcache(q)
+ CacheEntry *q;
+#endif
+{
+ char *qstr;
+
+ fprintf(stdout,"\nrule ");
+ for (qstr=q->str; *qstr != '*' ; qstr++) {
+ fprintf(stdout,"%c",*qstr);
+ };
+
+ qstr++;
+ if (*qstr == 'i') fprintf(stdout," First[");
+ if (*qstr == 'o') fprintf(stdout," Follow[");
+ qstr++;
+ fprintf(stdout,"%s]",qstr);
+ if (q->incomplete) fprintf(stdout," *** incomplete ***");
+ fprintf(stdout,"\n");
+ MR_dumpTokenSet(stdout,1,q->fset);
+}
+
+void
+#ifdef __USE_PROTOS
+DumpFcache(void)
+#else
+DumpFcache()
+#endif
+{
+
+ char *prev="";
+ int n=0;
+ CacheEntry *next;
+
+ fprintf(stdout,"\n\nDump of First/Follow Cache\n");
+
+ for(;;) {
+ next=dumpFcache1(prev);
+ if (next == NULL) break;
+ reportFcache(next);
+ ++n;
+ prev=next->str;
+ };
+ fprintf(stdout,"\nEnd dump of First/Follow Cache\n");
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset.c
new file mode 100644
index 00000000..2e013cc1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset.c
@@ -0,0 +1,1555 @@
+/*
+ * fset.c
+ *
+ * Compute FIRST and FOLLOW sets.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcctscfg.h"
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+#include "limits.h"
+
+#ifdef __USE_PROTOS
+static void ensure_predicates_cover_ambiguous_lookahead_sequences
+ (Junction *, Junction *, char *, Tree *);
+#else
+static void ensure_predicates_cover_ambiguous_lookahead_sequences();
+#endif
+
+/*
+ * What tokens are k tokens away from junction q?
+ *
+ * Follow both p1 and p2 paths (unless RuleBlk) to collect the tokens k away from this
+ * node.
+ * We lock the junction according to k--the lookahead. If we have been at this
+ * junction before looking for the same, k, number of lookahead tokens, we will
+ * do it again and again...until we blow up the stack. Locks are only used on aLoopBlk,
+ * RuleBlk, aPlusBlk and EndRule junctions to remove/detect infinite recursion from
+ * FIRST and FOLLOW calcs.
+ *
+ * If p->jtype == EndRule we are going to attempt a FOLLOW. (FOLLOWs are really defined
+ * in terms of FIRST's, however). To proceed with the FOLLOW, p->halt cannot be
+ * set. p->halt is set to indicate that a reference to the current rule is in progress
+ * and the FOLLOW is not desirable.
+ *
+ * If we attempt a FOLLOW and find that there is no FOLLOW or REACHing beyond the EndRule
+ * junction yields an empty set, replace the empty set with EOF. No FOLLOW means that
+ * only EOF can follow the current rule. This normally occurs only on the start symbol
+ * since all other rules are referenced by another rule somewhere.
+ *
+ * Normally, both p1 and p2 are followed. However, checking p2 on a RuleBlk node is
+ * the same as checking the next rule which is clearly incorrect.
+ *
+ * Cycles in the FOLLOW sense are possible. e.g. Fo(c) requires Fo(b) which requires
+ * Fo(c). Both Fo(b) and Fo(c) are defined to be Fo(b) union Fo(c). Let's say
+ * Fo(c) is attempted first. It finds all of the FOLLOW symbols and then attempts
+ * to do Fo(b) which finds of its FOLLOW symbols. So, we have:
+ *
+ * Fo(c)
+ * / \
+ * a set Fo(b)
+ * / \
+ * a set Fo(c) .....Hmmmm..... Infinite recursion!
+ *
+ * The 2nd Fo(c) is not attempted and Fo(b) is left deficient, but Fo(c) is now
+ * correctly Fo(c) union Fo(b). We wish to pick up where we left off, so the fact
+ * that Fo(b) terminated early means that we lack Fo(c) in the Fo(b) set already
+ * laying around. SOOOOoooo, we track FOLLOW cycles. All FOLLOW computations are
+ * cached in a hash table. After the sequence of FOLLOWs finish, we reconcile all
+ * cycles --> correct all Fo(rule) sets in the cache.
+ *
+ * Confused? Good! Read my MS thesis [Purdue Technical Report TR90-30].
+ * TJP 8/93 -- can now read PhD thesis from Purdue.
+ *
+ * Also, FIRST sets are cached in the hash table. Keys are (rulename,Fi/Fo,k).
+ * Only FIRST sets, for which the FOLLOW is not included, are stored.
+ *
+ * SPECIAL CASE of (...)+ blocks:
+ * I added an optional alt so that the alts could see what
+ * was behind the (...)+ block--thus using enough lookahead
+ * to branch out rather than just enough to distinguish
+ * between alts in the (...)+. However, when the FIRST("(...)+") is
+ * is needed, must not use this last "optional" alt. This routine
+ * turns off this path by setting a new 'ignore' flag for
+ * the alt and then resetting it afterwards.
+ */
+
+set
+#ifdef __USE_PROTOS
+rJunc( Junction *p, int k, set *rk )
+#else
+rJunc( p, k, rk )
+Junction *p;
+int k;
+set *rk;
+#endif
+{
+ set a, b;
+
+ require(p!=NULL, "rJunc: NULL node");
+ require(p->ntype==nJunction, "rJunc: not junction");
+
+#ifdef DBG_LL1
+ if ( p->jtype == RuleBlk ) fprintf(stderr, "FIRST(%s,%d) \n",((Junction *)p)->rname,k);
+ else fprintf(stderr, "rJunc: %s in rule %s\n",
+ decodeJType[p->jtype], ((Junction *)p)->rname);
+#endif
+ /* if this is one of the added optional alts for (...)+ then return */
+
+ /* no need to pop backtrace - hasn't been pushed */
+
+ if ( p->ignore ) return empty;
+
+ if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);
+
+/* MR14 */ if (AlphaBetaTrace && p->alpha_beta_guess_end) {
+/* MR14 */ warnFL(
+/* MR14 */ "not possible to compute follow set for alpha in an \"(alpha)? beta\" block. ",
+/* MR14 */ FileStr[p->file],p->line);
+/* MR14 */ MR_alphaBetaTraceReport();
+/* MR14 */ };
+
+/* MR14 */ if (p->alpha_beta_guess_end) {
+/* MR14 */ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+/* MR14 */ return empty;
+/* MR14 */ }
+
+ /* locks are valid for aLoopBlk,aPlusBlk,RuleBlk,EndRule junctions only */
+ if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
+ p->jtype==aPlusBlk || p->jtype==EndRule )
+ {
+ require(p->lock!=NULL, "rJunc: lock array is NULL");
+ if ( p->lock[k] )
+ {
+ if ( p->jtype == EndRule ) /* FOLLOW cycle? */
+ {
+#ifdef DBG_LL1
+ fprintf(stderr, "FOLLOW cycle to %s: panic!\n", p->rname);
+#endif
+ if (! MR_AmbSourceSearch) RegisterCycle(p->rname, k);
+ }
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return empty;
+ }
+ if ( p->jtype == RuleBlk &&
+ p->end->halt &&
+ ! MR_AmbSourceSearch) /* check for FIRST cache */
+ {
+ CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'i',k));
+ if ( q != NULL )
+ {
+ set_orin(rk, q->rk);
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return set_dup( q->fset );
+ }
+ }
+ if ( p->jtype == EndRule &&
+ !p->halt && /* MR11 was using cache even when halt set */
+ ! MR_AmbSourceSearch) /* FOLLOW set cached already? */
+ {
+ CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k));
+ if ( q != NULL )
+ {
+#ifdef DBG_LL1
+ fprintf(stderr, "cache for FOLLOW(%s,%d):", p->rname,k);
+ s_fprT(stderr, q->fset);
+ if ( q->incomplete ) fprintf(stderr, " (incomplete)");
+ fprintf(stderr, "\n");
+#endif
+ if ( !q->incomplete )
+ {
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return set_dup( q->fset );
+ }
+ }
+ }
+ p->lock[k] = TRUE; /* This rule is busy */
+ }
+
+ a = b = empty;
+
+ if ( p->jtype == EndRule )
+ {
+ if (p->halt ) /* don't want FOLLOW here? */ /* unless MR10 hoisting */
+ {
+ p->lock[k] = FALSE;
+ set_orel(k, rk); /* indicate this k value needed */
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return empty;
+ }
+ if (! MR_AmbSourceSearch) FoPush(p->rname, k); /* Attempting FOLLOW */
+ if ( p->p1 == NULL ) set_orel((TokenInd!=NULL?TokenInd[EofToken]:EofToken), &a);/* if no FOLLOW assume EOF */
+#ifdef DBG_LL1
+ fprintf(stderr, "-->FOLLOW(%s,%d)\n", p->rname,k);
+#endif
+ }
+
+ if ( p->p1 != NULL ) {
+/* MR14 */ if (p->guess) {
+/* MR14 */ if (p->guess_analysis_point == NULL) {
+/* MR14 */ Node * guess_point;
+/* MR14 */ guess_point=(Node *)analysis_point(p);
+/* MR14 */ if (guess_point == (Node *)p) {
+/* MR14 */ guess_point=p->p1;
+/* MR14 */ }
+/* MR14 */ p->guess_analysis_point=guess_point;
+/* MR14 */ }
+/* MR14 */ REACH(p->guess_analysis_point, k, rk, a);
+ } else {
+ REACH(p->p1, k, rk, a);
+ }
+ }
+
+ /* C a c h e R e s u l t s */
+
+ if ( p->jtype == RuleBlk && p->end->halt && ! MR_AmbSourceSearch) /* can save FIRST set? */
+ {
+ CacheEntry *q = newCacheEntry( Fkey(p->rname,'i',k) );
+ /*fprintf(stderr, "Caching %s FIRST %d\n", p->rname, k);*/
+ hash_add(Fcache, Fkey(p->rname,'i',k), (Entry *)q);
+ q->fset = set_dup( a );
+ q->rk = set_dup( *rk );
+ }
+
+ if ( p->jtype == EndRule &&
+ !p->halt && /* MR11 was using cache even with halt set */
+ ! MR_AmbSourceSearch) /* just completed FOLLOW? */
+ {
+ /* Cache Follow set */
+ CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k));
+ if ( q==NULL )
+ {
+ q = newCacheEntry( Fkey(p->rname,'o',k) );
+ hash_add(Fcache, Fkey(p->rname,'o',k), (Entry *)q);
+ }
+ /*fprintf(stderr, "Caching %s FOLLOW %d\n", p->rname, k);*/
+ if ( set_nil(a) && !q->incomplete )
+ {
+ /* Don't ever save a nil set as complete.
+ * Turn it into an eof set.
+ */
+ set_orel(EofToken, &a);
+ }
+ set_orin(&(q->fset), a);
+ FoPop( k );
+ if ( FoTOS[k] == NULL && Cycles[k] != NULL ) ResolveFoCycles(k);
+#ifdef DBG_LL1
+ fprintf(stderr, "saving FOLLOW(%s,%d):", p->rname, k);
+ s_fprT(stderr, q->fset);
+ if ( q->incomplete ) fprintf(stderr, " (incomplete)");
+ fprintf(stderr, "\n");
+#endif
+ }
+
+ if (p->jtype != RuleBlk && p->p2 != NULL && /* MR14 */ ! p->guess) {
+ REACH(p->p2, k, rk, b);
+ }
+
+ if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
+ p->jtype==aPlusBlk || p->jtype==EndRule )
+ p->lock[k] = FALSE; /* unlock node */
+
+ set_orin(&a, b);
+ set_free(b);
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return a;
+}
+
+set
+#ifdef __USE_PROTOS
+rRuleRef( RuleRefNode *p, int k, set *rk_out )
+#else
+rRuleRef( p, k, rk_out )
+RuleRefNode *p;
+int k;
+set *rk_out;
+#endif
+{
+ set rk;
+ Junction *r;
+ int k2;
+ set a, rk2, b;
+ int save_halt;
+ RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
+ require(p!=NULL, "rRuleRef: NULL node");
+ require(p->ntype==nRuleRef, "rRuleRef: not rule ref");
+
+#ifdef DBG_LL1
+ fprintf(stderr, "rRuleRef: %s\n", p->text);
+#endif
+
+ if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);
+
+ if ( q == NULL )
+ {
+ warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );
+ REACH(p->next, k, rk_out, a);
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return a;
+ }
+ rk2 = empty;
+
+/* MR9 Problems with rule references in guarded predicates */
+/* MR9 Perhaps can use hash table to find rule ? */
+
+/* MR9 */ if (RulePtr == NULL) {
+/* MR9 */ fatalFL(eMsg2("Rule %s uses rule %s via RulePtr before it has been initialized",
+/* MR9 */ p->rname,q->str),FileStr[p->file],p->line);
+/* MR9 */ };
+
+ r = RulePtr[q->rulenum];
+ if ( r->lock[k] )
+ {
+ errNoFL( eMsg2("infinite left-recursion to rule %s from rule %s",
+ r->rname, p->rname) );
+
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+
+ return empty;
+ }
+
+ save_halt = r->end->halt;
+ r->end->halt = TRUE; /* don't let reach fall off end of rule here */
+ rk = empty;
+ REACH(r, k, &rk, a);
+ r->end->halt = save_halt;
+ while ( !set_nil(rk) ) {
+ k2 = set_int(rk); /* MR11 this messes up the ambiguity search routine */
+ set_rm(k2, rk);
+ REACH(p->next, k2, &rk2, b); /* MR11 by changing the value of k */
+ set_orin(&a, b);
+ set_free(b);
+ }
+ set_free(rk); /* this has no members, but free its memory */
+ set_orin(rk_out, rk2); /* remember what we couldn't do */
+ set_free(rk2);
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return a;
+}
+
+/*
+ * Return FIRST sub k ( token_node )
+ *
+ * TJP 10/11/93 modified this so that token nodes that are actually
+ * ranges (T1..T2) work.
+ */
+set
+#ifdef __USE_PROTOS
+rToken( TokNode *p, int k, set *rk )
+#else
+rToken( p, k, rk )
+TokNode *p;
+int k;
+set *rk;
+#endif
+{
+ set a;
+
+ require(p!=NULL, "rToken: NULL node");
+ require(p->ntype==nToken, "rToken: not token node");
+
+#ifdef DBG_LL1
+ fprintf(stderr, "rToken: %s\n", (TokenString(p->token)!=NULL)?TokenString(p->token):
+ ExprString(p->token));
+#endif
+
+
+ if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);
+
+ if (MR_AmbSourceSearch && (k-1) == 0) {
+
+ set localConstrain;
+ set intersection;
+
+ localConstrain=fset[maxk-k+1];
+
+ if (! set_nil(p->tset)) {
+ intersection=set_and(localConstrain,p->tset);
+ if (! set_nil(intersection)) {
+ MR_backTraceReport();
+ };
+ set_free(intersection);
+ } else {
+ if (set_el( (unsigned) p->token,localConstrain)) {
+ MR_backTraceReport();
+ }
+ };
+ };
+
+ if ( k-1 == 0 ) {
+
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+
+ if ( !set_nil(p->tset) ) {
+ return set_dup(p->tset);
+ } else {
+ return set_of(p->token);
+ };
+ }
+
+ REACH(p->next, k-1, rk, a);
+
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+
+ return a;
+}
+
+set
+#ifdef __USE_PROTOS
+rAction( ActionNode *p, int k, set *rk )
+#else
+rAction( p, k, rk )
+ActionNode *p;
+int k;
+set *rk;
+#endif
+{
+ set a;
+
+ require(p!=NULL, "rJunc: NULL node");
+ require(p->ntype==nAction, "rJunc: not action");
+
+/* MR11 */ if (p->is_predicate && p->ampersandPred != NULL) {
+/* MR11 */ Predicate *pred=p->ampersandPred;
+/* MR11 */ if (k <= pred->k) {
+/* MR11 */ REACH(p->guardNodes,k,rk,a);
+/* MR11 */ return a;
+/* MR11 */ };
+/* MR11 */ };
+
+ /* it might be a good idea when doing an MR_AmbSourceSearch
+ to *not* look behind predicates under some circumstances
+ we'll look into that later
+ */
+
+ REACH(p->next, k, rk, a); /* ignore actions */
+ return a;
+}
+
+ /* A m b i g u i t y R e s o l u t i o n */
+
+
+void
+#ifdef __USE_PROTOS
+dumpAmbigMsg( set *fset, FILE *f, int want_nls )
+#else
+dumpAmbigMsg( fset, f, want_nls )
+set *fset;
+FILE *f;
+int want_nls;
+#endif
+{
+ int i;
+
+ set copy; /* MR11 */
+
+ if ( want_nls ) fprintf(f, "\n\t");
+ else fprintf(f, " ");
+
+ for (i=1; i<=CLL_k; i++)
+ {
+ copy=set_dup(fset[i]); /* MR11 */
+
+ if ( i>1 )
+ {
+ if ( !want_nls ) fprintf(f, ", ");
+ }
+ if ( set_deg(copy) > 3 && elevel == 1 )
+ {
+ int e,m;
+ fprintf(f, "{");
+ for (m=1; m<=3; m++)
+ {
+ e=set_int(copy);
+ fprintf(f, " %s", TerminalString(e));
+ set_rm(e, copy);
+ }
+ fprintf(f, " ... }");
+ }
+ else s_fprT(f, copy);
+ if ( want_nls ) fprintf(f, "\n\t");
+ set_free(copy);
+ }
+ fprintf(f, "\n");
+
+}
+
+static void
+#ifdef __USE_PROTOS
+verify_context(Predicate *predicate)
+#else
+verify_context(predicate)
+Predicate *predicate;
+#endif
+{
+ if ( predicate == NULL ) return;
+
+ if ( predicate->expr == PRED_OR_LIST ||
+ predicate->expr == PRED_AND_LIST )
+ {
+ verify_context(predicate->down);
+ verify_context(predicate->right); /* MR10 */
+ return;
+ }
+
+ if ( !predicate->source->ctxwarned && predicate->source->guardpred==NULL &&
+ ((predicate->k > 1 &&
+ !is_single_tuple(predicate->tcontext)) ||
+ ( predicate->k == 1 &&
+ set_deg(predicate->scontext[1])>1 )) )
+ {
+
+/* MR9 Suppress annoying messages caused by our own clever(?) fix */
+
+ fprintf(stderr, ErrHdr, FileStr[predicate->source->file],
+ predicate->source->line);
+ fprintf(stderr, " warning: predicate applied for >1 lookahead %d-sequences\n", predicate->k);
+ fprintf(stderr, ErrHdr, FileStr[predicate->source->file],
+ predicate->source->line);
+ fprintf(stderr, " predicate text: \"%s\"\n",
+ (predicate->expr == NULL ? "(null)" : predicate->expr) );
+ fprintf(stderr, ErrHdr, FileStr[predicate->source->file],
+ predicate->source->line);
+ fprintf(stderr, " You may only want one lookahead %d-sequence to apply\n", predicate->k);
+ fprintf(stderr, ErrHdr, FileStr[predicate->source->file],
+ predicate->source->line);
+ fprintf(stderr, " Try using a context guard '(...)? =>'\n");
+ predicate->source->ctxwarned = 1;
+ }
+ verify_context(predicate->right); /* MR10 */
+}
+
+/*
+ * If delta is the set of ambiguous lookahead sequences, then make sure that
+ * the predicate(s) for productions alt1,alt2 cover the sequences in delta.
+ *
+ * For example,
+ * a : <<PRED1>>? (A B|A C)
+ * | b
+ * ;
+ * b : <<PRED2>>? A B
+ * | A C
+ * ;
+ *
+ * This should give a warning that (A C) predicts both productions and alt2
+ * does not have a predicate in the production that generates (A C).
+ *
+ * The warning detection is simple. Let delta = LOOK(alt1) intersection LOOK(alt2).
+ * Now, if ( delta set-difference context(predicates-for-alt1) != empty then
+ * alt1 does not "cover" all ambiguous sequences.
+ *
+ * If ambig is nonempty, then ambig in LL(k) sense -> use tree info; else use fset
+ * info. Actually, sets are used only if k=1 for this grammar.
+ */
+static void
+#ifdef __USE_PROTOS
+ensure_predicates_cover_ambiguous_lookahead_sequences
+ ( Junction *alt1, Junction *alt2, char *sub, Tree *ambig )
+#else
+ensure_predicates_cover_ambiguous_lookahead_sequences( alt1, alt2, sub, ambig )
+Junction *alt1;
+Junction *alt2;
+char *sub;
+Tree *ambig;
+#endif
+{
+ if ( !ParseWithPredicates ) return;
+
+ if ( ambig!=NULL )
+ {
+ Tree *non_covered = NULL;
+ if ( alt1->predicate!=NULL )
+ non_covered = tdif(ambig, alt1->predicate, alt1->fset, alt2->fset);
+ if ( (non_covered!=NULL || alt1->predicate==NULL) && WarningLevel>1 )
+ {
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",
+ alt1->altnum, sub);
+ if ( alt1->predicate!=NULL && non_covered!=NULL )
+ {
+ fprintf(stderr, " upon");
+ preorder(non_covered);
+ }
+ else if ( alt1->predicate==NULL )
+ {
+ fprintf(stderr, " upon");
+ preorder(ambig->down);
+ }
+ fprintf(stderr, "\n");
+ }
+ Tfree(non_covered);
+ non_covered = NULL;
+ if ( alt2->predicate!=NULL )
+ non_covered = tdif(ambig, alt2->predicate, alt1->fset, alt2->fset);
+ if ( (non_covered!=NULL || alt2->predicate==NULL) && WarningLevel>1 )
+ {
+ fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line);
+ fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",
+ alt2->altnum, sub);
+ if ( alt2->predicate!=NULL && non_covered!=NULL )
+ {
+ fprintf(stderr, " upon");
+ preorder(non_covered);
+ }
+ else if ( alt2->predicate==NULL )
+ {
+ fprintf(stderr, " upon");
+ preorder(ambig->down);
+ }
+ fprintf(stderr, "\n");
+ }
+ Tfree(non_covered);
+ }
+ else if ( !set_nil(alt1->fset[1]) )
+ {
+ set delta, non_covered;
+ delta = set_and(alt1->fset[1], alt2->fset[1]);
+ non_covered = set_dif(delta, covered_set(alt1->predicate));
+ if ( set_deg(non_covered)>0 && WarningLevel>1 )
+ {
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",
+ alt1->altnum, sub);
+ if ( alt1->predicate!=NULL )
+ {
+ fprintf(stderr, " upon ");
+ s_fprT(stderr, non_covered);
+ }
+ fprintf(stderr, "\n");
+ }
+ set_free( non_covered );
+ non_covered = set_dif(delta, covered_set(alt2->predicate));
+ if ( set_deg(non_covered)>0 && WarningLevel>1 )
+ {
+ fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line);
+ fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity",
+ alt2->altnum, sub);
+ if ( alt2->predicate!=NULL )
+ {
+ fprintf(stderr, " upon ");
+ s_fprT(stderr, non_covered);
+ }
+ fprintf(stderr, "\n");
+ }
+ set_free( non_covered );
+ set_free( delta );
+ }
+ else fatal_internal("productions have no lookahead in predicate checking routine");
+}
+
+#ifdef __USE_PROTOS
+void MR_doPredicatesHelp(int inGuessBlock,Junction *alt1,Junction *alt2,int jtype,char *sub)
+#else
+void MR_doPredicatesHelp(inGuessBlock,alt1,alt2,jtype,sub)
+ int inGuessBlock;
+ Junction *alt1;
+ Junction *alt2;
+ int jtype;
+ char *sub;
+#endif
+{
+ Predicate *p1;
+ Predicate *p2;
+
+ Junction *parentRule=MR_nameToRuleBlk(alt1->rname);
+
+ if (inGuessBlock && WarningLevel <= 1) return;
+
+ /* let antlr give the usual error message */
+
+ if (alt1->predicate == NULL && alt2->predicate == NULL) return;
+
+ if ( (jtype == RuleBlk || jtype == aSubBlk)
+ && (alt1->predicate == NULL && alt2->predicate != NULL)) {
+ fprintf(stderr, ErrHdr, FileStr[parentRule->file],parentRule->line);
+ fprintf(stderr," warning: alt %d line %d and alt %d line %d of %s\n%s%s%s",
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ sub,
+ " These alts have ambig lookahead sequences resolved by a predicate for\n",
+ " the second choice. The second choice may not be reachable.\n",
+ " You may want to use a complementary predicate or rearrange the alts\n"
+ );
+ return;
+ };
+
+ /* first do the easy comparison. then do the hard one */
+
+ if (MR_comparePredicates(alt1->predicate,alt2->predicate)) {
+
+ if (jtype == aLoopBegin || jtype == aPlusBlk ) {
+
+ /* I'm not sure this code is reachable.
+ Predicates following a (...)+ or (...)* block are probably
+ considered validation predicates and therefore not
+ participate in the predication expression
+ */
+
+ fprintf(stderr, ErrHdr,FileStr[parentRule->file],parentRule->line);
+ fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s",
+ "the predicates used to disambiguate optional/exit paths of ",
+ sub,
+ CurRule,
+ FileStr[alt1->file],
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ " are identical and have no resolving power\n");
+ } else {
+ fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
+ fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s",
+ "the predicates used to disambiguate",
+ CurRule,
+ FileStr[alt1->file],
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ " are identical and have no resolving power\n");
+ };
+ } else {
+ p1=predicate_dup_without_context(alt1->predicate);
+ p1=MR_unfold(p1);
+ MR_clearPredEntry(p1);
+ MR_simplifyInverted(p1,0);
+ p1=MR_predSimplifyALL(p1);
+ p2=predicate_dup_without_context(alt2->predicate);
+ p2=MR_unfold(p2);
+ MR_clearPredEntry(p2);
+ MR_simplifyInverted(p2,0);
+ p2=MR_predSimplifyALL(p2);
+ if (MR_comparePredicates(p1,p2)) {
+ if (jtype == aLoopBegin || jtype == aPlusBlk ) {
+ fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
+ fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s",
+ "the predicates used to disambiguate optional/exit paths of ",
+ sub,
+ CurRule,
+ FileStr[alt1->file],
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ " are identical when compared without context and may have no\n",
+ " resolving power for some lookahead sequences.\n");
+ } else {
+ fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
+ fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s",
+ "the predicates used to disambiguate",
+ CurRule,
+ FileStr[alt1->file],
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ " are identical when compared without context and may have no\n",
+ " resolving power for some lookahead sequences.\n");
+ };
+ if (InfoP) {
+ fprintf(output,"\n#if 0\n\n");
+ fprintf(output,"The following predicates are identical when compared without\n");
+ fprintf(output," lookahead context information. For some ambiguous lookahead\n");
+ fprintf(output," sequences they may not have any power to resolve the ambiguity.\n");
+ fprintf(output,"\n");
+
+ fprintf(output,"Choice 1: %s alt %d line %d file %s\n\n",
+ MR_ruleNamePlusOffset( (Node *) alt1),
+ alt1->altnum,
+ alt1->line,
+ FileStr[alt1->file]);
+ fprintf(output," The original predicate for choice 1 with available context information:\n\n");
+ MR_dumpPred1(2,alt1->predicate,1);
+ fprintf(output," The predicate for choice 1 after expansion (but without context information):\n\n");
+ MR_dumpPred1(2,p1,0);
+ if (p1 == NULL) {
+ Predicate *phelp;
+ fprintf(output," The predicate for choice 1 after expansion (but before simplification)\n\n");
+ phelp=predicate_dup_without_context(alt1->predicate);
+ phelp=MR_unfold(phelp);
+ MR_clearPredEntry(phelp);
+ MR_simplifyInverted(phelp,0);
+ phelp=MR_predSimplifyALLX(phelp,1);
+ MR_dumpPred1(2,phelp,0);
+ predicate_free(phelp);
+ };
+ fprintf(output,"\n");
+
+ fprintf(output,"Choice 2: %s alt %d line %d file %s\n\n",
+ MR_ruleNamePlusOffset( (Node *) alt2),
+ alt2->altnum,
+ alt2->line,
+ FileStr[alt2->file]);
+ fprintf(output," The original predicate for choice 2 with available context information:\n\n");
+ MR_dumpPred1(1,alt2->predicate,1);
+ fprintf(output," The predicate for choice 2 after expansion (but without context information):\n\n");
+ MR_dumpPred1(1,p2,0);
+ if (p2 == NULL) {
+ Predicate *phelp;
+ fprintf(output," The predicate for choice 2 after expansion (but before simplification)\n\n");
+ phelp=predicate_dup_without_context(alt2->predicate);
+ phelp=MR_unfold(phelp);
+ MR_clearPredEntry(phelp);
+ MR_simplifyInverted(phelp,0);
+ phelp=MR_predSimplifyALLX(phelp,1);
+ MR_dumpPred1(2,phelp,0);
+ predicate_free(phelp);
+ };
+ fprintf(output,"\n#endif\n");
+ };
+ } else if (MR_secondPredicateUnreachable(p1,p2)) {
+ if (jtype == aLoopBegin || jtype == aPlusBlk ) {
+ fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
+ fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s",
+ "the predicate used to disambiguate the first choice of the optional/exit paths of ",
+ sub,
+ CurRule,
+ FileStr[alt1->file],
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ " appears to \"cover\" the second predicate when compared without context.\n",
+ " The second predicate may have no resolving power for some lookahead sequences.\n");
+ } else {
+ fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
+ fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s",
+ "the predicate used to disambiguate the first choice of",
+ CurRule,
+ FileStr[alt1->file],
+ alt1->altnum,
+ alt1->line,
+ alt2->altnum,
+ alt2->line,
+ " appears to \"cover\" the second predicate when compared without context.\n",
+ " The second predicate may have no resolving power for some lookahead sequences.\n");
+ };
+ if (InfoP) {
+ fprintf(output,"\n#if 0\n\n");
+ fprintf(output,"The first predicate appears to \"cover\" the second predicate when they\n");
+ fprintf(output," are compared without lookahead context information. For some ambiguous\n");
+ fprintf(output," lookahead sequences the second predicate may not have any power to\n");
+ fprintf(output," resolve the ambiguity.\n");
+ fprintf(output,"\n");
+ fprintf(output,"Choice 1: %s alt %d line %d file %s\n\n",
+ MR_ruleNamePlusOffset( (Node *) alt1),
+ alt1->altnum,
+ alt1->line,
+ FileStr[alt1->file]);
+ fprintf(output," The original predicate for choice 1 with available context information:\n\n");
+ MR_dumpPred1(2,alt1->predicate,1);
+ fprintf(output," The predicate for choice 1 after expansion (but without context information):\n\n");
+ MR_dumpPred1(2,p1,0);
+ if (p1 == NULL) {
+ Predicate *phelp;
+ fprintf(output," The predicate for choice 1 after expansion (but before simplification)\n\n");
+ phelp=predicate_dup_without_context(alt1->predicate);
+ phelp=MR_unfold(phelp);
+ MR_clearPredEntry(phelp);
+ MR_simplifyInverted(phelp,0);
+ phelp=MR_predSimplifyALLX(phelp,1);
+ MR_dumpPred1(2,phelp,0);
+ predicate_free(phelp);
+ };
+ fprintf(output,"\n");
+
+ fprintf(output,"Choice 2: %s alt %d line %d file %s\n\n",
+ MR_ruleNamePlusOffset( (Node *) alt2),
+ alt2->altnum,
+ alt2->line,
+ FileStr[alt2->file]);
+ fprintf(output," The original predicate for choice 2 with available context information:\n\n");
+ MR_dumpPred1(1,alt2->predicate,1);
+ fprintf(output," The predicate for choice 2 after expansion (but without context information):\n\n");
+ MR_dumpPred1(1,p2,0);
+ if (p2 == NULL) {
+ Predicate *phelp;
+ fprintf(output," The predicate for choice 2 after expansion (but before simplification)\n\n");
+ phelp=predicate_dup_without_context(alt2->predicate);
+ phelp=MR_unfold(phelp);
+ MR_clearPredEntry(phelp);
+ MR_simplifyInverted(phelp,0);
+ phelp=MR_predSimplifyALLX(phelp,1);
+ MR_dumpPred1(2,phelp,0);
+ predicate_free(phelp);
+ };
+ fprintf(output,"\n#endif\n");
+ };
+ };
+ predicate_free(p1);
+ predicate_free(p2);
+ };
+}
+
+static int totalOverflow=0; /* MR9 */
+
+void
+#ifdef __USE_PROTOS
+HandleAmbiguity( Junction *block, Junction *alt1, Junction *alt2, int jtype )
+#else
+HandleAmbiguity( block, alt1, alt2, jtype )
+Junction *block;
+Junction *alt1;
+Junction *alt2;
+int jtype;
+#endif
+{
+ unsigned **ftbl;
+ set *fset, b;
+ int i, numAmbig,n2;
+ Tree *ambig=NULL, *t, *u;
+ char *sub = "";
+ long n;
+ int thisOverflow=0; /* MR9 */
+ long set_deg_value; /* MR10 */
+ long threshold; /* MR10 */
+
+ require(block!=NULL, "NULL block");
+ require(block->ntype==nJunction, "invalid block");
+
+ /* These sets are used to constrain LL_k set, but are made CLL_k long anyway */
+ fset = (set *) calloc(CLL_k+1, sizeof(set));
+ require(fset!=NULL, "cannot allocate fset");
+ ftbl = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));
+ require(ftbl!=NULL, "cannot allocate ftbl");
+
+ /* create constraint table and count number of possible ambiguities (use<=LL_k) */
+ for (n=1,i=1; i<=CLL_k; i++)
+ {
+ b = set_and(alt1->fset[i], alt2->fset[i]);
+/* MR9 */ set_deg_value = set_deg(b);
+/* MR10 */ if (n > 0) {
+/* MR10 */ threshold = LONG_MAX / n;
+/* MR10 */ if (set_deg_value <= threshold) {
+/* MR10 */ n *= set_deg_value;
+/* MR10 */ } else {
+/* MR10 */ n=LONG_MAX;
+/* MR9 */ if (totalOverflow == 0) {
+#if 0
+ /* MR10 comment this out because it just makes users worry */
+
+/* MR9 */ warnNoFL("Overflow in computing number of possible ambiguities in HandleAmbiguity\n");
+#endif
+/* MR9 */ };
+/* MR9 */ thisOverflow++;
+/* MR9 */ totalOverflow++;
+/* MR9 */ };
+/* MR10 */ } else {
+/* MR10 */ n *= set_deg_value;
+/* MR9 */ };
+ fset[i] = set_dup(b);
+ ftbl[i] = set_pdq(b);
+ set_free(b);
+ }
+
+ switch ( jtype )
+ {
+ case aSubBlk: sub = "of (..) "; break;
+ case aOptBlk: sub = "of {..} "; break;
+ case aLoopBegin: sub = "of (..)* "; break;
+ case aLoopBlk: sub = "of (..)* "; break;
+ case aPlusBlk: sub = "of (..)+ "; break;
+ case RuleBlk: sub = "of the rule itself "; break;
+ default : sub = ""; break;
+ }
+
+ /* If the block is marked as a compressed lookahead only block, then
+ * simply return; ambiguity warning is given only at warning level 2.
+ */
+ if ( block->approx>0 )
+ {
+ if ( ParseWithPredicates )
+ {
+ if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */
+ if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */
+
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");
+ alt1->predicate=MR_predSimplifyALL(alt1->predicate);
+
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");
+ alt2->predicate=MR_predSimplifyALL(alt2->predicate);
+
+ MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);
+
+ if ( HoistPredicateContext
+ && (alt1->predicate!=NULL||alt2->predicate!=NULL) )
+ {
+ verify_context(alt1->predicate);
+ verify_context(alt2->predicate);
+ }
+
+ if ( HoistPredicateContext
+ && (alt1->predicate!=NULL||alt2->predicate!=NULL)
+ && WarningLevel>1 )
+ ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);
+ }
+
+ if ( WarningLevel>1 )
+ {
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ if ( jtype == aLoopBegin || jtype == aPlusBlk )
+ fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
+ else
+ fprintf(stderr, " warning(approx): alts %d and %d %sambiguous upon",
+ alt1->altnum, alt2->altnum, sub);
+ dumpAmbigMsg(fset, stderr, 0);
+ MR_traceAmbSource(fset,alt1,alt2);
+ }
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+
+ /* if all sets have degree 1 for k<LL_k, then must be ambig upon >=1 permutation;
+ * don't bother doing full LL(k) analysis.
+ * (This "if" block handles the LL(1) case)
+ */
+
+ n2 = 0;
+ for (i=1; i<LL_k; i++) n2 += set_deg(alt1->fset[i])+set_deg(alt2->fset[i]);
+
+ /* here STARTS the special case in which the lookahead sets for alt1 and alt2
+ all have degree 1 for k<LL_k (including LL_k=1)
+ */
+
+ if ( n2==2*(LL_k-1) )
+ {
+
+ /* TJP: added to fix the case where LL(1) and syntactic predicates didn't
+ * work. It now recognizes syntactic predicates, but does not like combo:
+ * LL(1)/syn/sem predicates. (10/24/93)
+ */
+
+ if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL )
+ {
+ if ( WarningLevel==1 )
+ {
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ if ( jtype == aLoopBegin || jtype == aPlusBlk )
+ fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
+ else
+ fprintf(stderr, " warning: alts %d and %d %sambiguous upon",
+ alt1->altnum, alt2->altnum, sub);
+ dumpAmbigMsg(fset, stderr, 0);
+ MR_traceAmbSource(fset,alt1,alt2);
+ }
+
+ ambig = NULL;
+ if ( LL_k>1 ) ambig = make_tree_from_sets(alt1->fset, alt2->fset);
+ if ( ParseWithPredicates )
+ {
+ if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */
+ if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */
+
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");
+ alt1->predicate=MR_predSimplifyALL(alt1->predicate);
+
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");
+ alt2->predicate=MR_predSimplifyALL(alt2->predicate);
+
+ MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);
+
+ if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )
+ {
+ verify_context(alt1->predicate);
+ verify_context(alt2->predicate);
+ }
+ if (HoistPredicateContext&&(alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1)
+ ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);
+ if ( WarningLevel == 1 &&
+ (alt1->predicate!=NULL||alt2->predicate!=NULL))
+ {
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ Tfree(ambig);
+ return;
+ }
+ }
+/* end TJP (10/24/93) */
+
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ if ( jtype == aLoopBegin || jtype == aPlusBlk )
+ fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
+ else
+ fprintf(stderr, " warning: alts %d and %d %sambiguous upon",
+ alt1->altnum, alt2->altnum, sub);
+ if ( elevel == 3 && LL_k>1 )
+ {
+ preorder(ambig);
+ fprintf(stderr, "\n");
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ Tfree(ambig);
+ return;
+ };
+
+ Tfree(ambig);
+ dumpAmbigMsg(fset, stderr, 0);
+
+ /* because this is a special case in which both alt1 and alt2 have
+ lookahead sets of degree 1 for k<LL_k (including k=1) the linear
+ lookahead style search is adequate
+ */
+
+ MR_traceAmbSource(fset,alt1,alt2);
+
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+
+ /* here ENDS the special case in which the lookahead sets for alt1 and alt2
+ all have degree 1 for k<LL_k (including LL_k=1)
+ */
+
+ /* in case tree construction runs out of memory, set info to make good err msg */
+
+ CurAmbigAlt1 = alt1->altnum;
+ CurAmbigAlt2 = alt2->altnum;
+ CurAmbigbtype = sub;
+ CurAmbigfile = alt1->file;
+ CurAmbigline = alt1->line;
+
+ /* Don't do full LL(n) analysis if (...)? block because the block,
+ by definition, defies LL(n) analysis.
+ If guess (...)? block and ambiguous then don't remove anything from
+ 2nd alt to resolve ambig.
+ Want to predict with LL sup 1 ( n ) decision not LL(n) if guess block
+ since it is much cheaper than LL(n). LL sup 1 ( n ) "covers" the LL(n)
+ lookahead information.
+
+ Note: LL(n) context cannot be computed for semantic predicates when
+ followed by (..)?.
+
+ If (..)? then we scream "AAAHHHH! No LL(n) analysis will help"
+
+ Is 'ambig' always defined if we enter this if? I hope so
+ because the 'ensure...()' func references it. TJP Nov 1993.
+ */
+
+ /* THM MR30: Instead of using first_item_is_guss_block we use
+ first_item_is_guess_block_extra which will look inside a
+ loop block for a guess block. In other words ( (...)? )*.
+ It there is an ambiguity in this circumstance then we suppress
+ the normal methods of resolving ambiguities.
+ */
+
+ if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL )
+ {
+ if ( ParseWithPredicates )
+ {
+ if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */
+ if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");
+ alt1->predicate=MR_predSimplifyALL(alt1->predicate);
+
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");
+ alt2->predicate=MR_predSimplifyALL(alt2->predicate);
+
+ MR_doPredicatesHelp(1,alt1,alt2,jtype,sub);
+
+ if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )
+ {
+ verify_context(alt1->predicate);
+ verify_context(alt2->predicate);
+ }
+ if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 )
+ ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);
+ if ( WarningLevel==1 &&
+ (alt1->predicate!=NULL||alt2->predicate!=NULL))
+ {
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+ }
+
+ if ( WarningLevel>1 )
+ {
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ if ( jtype == aLoopBegin || jtype == aPlusBlk )
+ fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
+ else
+ fprintf(stderr, " warning: alts %d and %d %sambiguous upon",
+ alt1->altnum, alt2->altnum, sub);
+ dumpAmbigMsg(fset, stderr, 0);
+ MR_traceAmbSource(fset,alt1,alt2);
+ }
+
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+
+ /* Not resolved with (..)? block. Do full LL(n) analysis */
+
+ /* ambig is the set of k-tuples truly in common between alt 1 and alt 2 */
+ /* MR11 VerifyAmbig once used fset destructively */
+
+ ambig = VerifyAmbig(alt1, alt2, ftbl, fset, &t, &u, &numAmbig);
+
+ /* are all things in intersection really ambigs? */
+
+ if (thisOverflow || numAmbig < n ) /* MR9 */
+ {
+ Tree *v;
+
+ /* remove ambig permutation from 2nd alternative to resolve ambig;
+ * We want to compute the set of artificial tuples, arising from
+ * LL sup 1 (n) compression, that collide with real tuples from the
+ * 2nd alternative. This is the set of "special case" tuples that
+ * the LL sup 1 (n) decision template maps incorrectly.
+ */
+
+ /* when generating code in genExpr() it does
+ *
+ * if ( genExprSets(j->fset) && !genExprTree(j->ftree)) {...
+ *
+ * Sooooo the j->ftree is the tree of alt2
+ * after removal of conflicts, not alt1 !
+ */
+
+ if ( ambig!=NULL )
+ {
+ /* at the top of ambig is an ALT node */
+
+ for (v=ambig->down; v!=NULL; v=v->right)
+ {
+ u = trm_perm(u, v); /* remove v FROM u */
+ }
+/* fprintf(stderr, "after rm alt2:"); preorder(u); fprintf(stderr, "\n");*/
+ }
+ Tfree( t );
+ alt1->ftree = tappend(alt1->ftree, u);
+ alt1->ftree = tleft_factor(alt1->ftree);
+ }
+
+ if ( ambig==NULL )
+ {
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+
+ ambig = tleft_factor(ambig);
+
+/* TJP:
+ * At this point, we surely have an LL(k) ambiguity. Check for predicates
+ */
+ if ( ParseWithPredicates )
+ {
+ if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */
+ if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");
+ alt1->predicate=MR_predSimplifyALL(alt1->predicate);
+
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");
+ alt2->predicate=MR_predSimplifyALL(alt2->predicate);
+
+ MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);
+
+ if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )
+ {
+ verify_context(alt1->predicate);
+ verify_context(alt2->predicate);
+ }
+ if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 )
+ ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);
+ if ( WarningLevel==1 &&
+ (alt1->predicate!=NULL||alt2->predicate!=NULL))
+ {
+
+ /* We found at least one pred for at least one of the alts;
+ * If warnings are low, just return.
+ */
+
+ Tfree(ambig);
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+ return;
+ }
+ /* else we're gonna give a warning */
+ }
+/* end TJP addition */
+
+ fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
+ if ( jtype == aLoopBegin || jtype == aPlusBlk )
+ fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
+ else
+ fprintf(stderr, " warning: alts %d and %d %sambiguous upon",
+ alt1->altnum, alt2->altnum, sub);
+ if ( elevel == 3 )
+ {
+ preorder(ambig->down); /* <===== k>1 ambiguity message data */
+ fprintf(stderr, "\n");
+ } else {
+ MR_skipped_e3_report=1;
+ dumpAmbigMsg(fset, stderr, 0);
+ };
+
+ MR_traceAmbSourceK(ambig,alt1,alt2); /* <====== k>1 ambiguity aid */
+
+ Tfree(ambig);
+
+ for (i=1; i<=CLL_k; i++) set_free( fset[i] );
+ free((char *)fset);
+ for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
+ free((char *)ftbl);
+}
+
+/* Don't analyze alpha block of (alpha)?beta; if (alpha)? then analyze
+ * Return the 1st node of the beta block if present else return j.
+ */
+Junction *
+#ifdef __USE_PROTOS
+analysis_point( Junction *j )
+#else
+analysis_point( j )
+Junction *j;
+#endif
+{
+ Junction *gblock;
+
+ /* MR13b When there was an action/predicate preceding a guess block
+ the guess block became invisible at the analysis_point.
+
+ first_item_is_guess_block accepts any kind of node,
+ despite the fact that the formal is a junction. But
+ I don't want to have to change it all over the place
+ until I know it works.
+ */
+
+ if ( j->ntype != nJunction && j->ntype != nAction) return j;
+
+ gblock = first_item_is_guess_block((Junction *)j);
+
+ if ( gblock!=NULL )
+ {
+ Junction *past = gblock->end;
+ Junction *p;
+ require(past!=NULL, "analysis_point: no end block on (...)? block");
+
+ for (p=(Junction *)past->p1; p!=NULL; )
+ {
+ if ( p->ntype==nAction )
+ {
+ p=(Junction *)((ActionNode *)p)->next;
+ continue;
+ }
+ if ( p->ntype!=nJunction )
+ {
+ past->alpha_beta_guess_end=1; /* MR14 */
+ return (Junction *)past->p1;
+ }
+ if ( p->jtype==EndBlk || p->jtype==EndRule )
+ {
+ return j;
+ }
+/* MR6 */
+/* MR6 A guess block is of the form "(alpha)? beta" or "(alpha)?". */
+/* MR6 When beta is omitted (second form) this means "(alpha)? alpha". */
+/* MR6 The program does not store another copy of alpha in this case. */
+/* MR6 During analysis when the program needs to know what follows the */
+/* MR6 guess clause. It calls this routine. */
+/* MR6 */
+/* MR6 If it is of the form "(alpha)? beta" it returns a pointer to beta.*/
+/* MR6 */
+/* MR6 If it is of the form "(alpha)?" it returns a pointer to the guess */
+/* MR6 block itself thereby reusing the junction tree. */
+/* MR6 */
+/* MR6 It works by searching the "next in sequence" chain (skipping actions) */
+/* MR6 searching for a RuleRef or Token node. (Those are the only 4 kinds */
+/* MR6 of nodes: Junctions, RuleRef, Token, and Action.) */
+/* MR6 */
+/* MR6 This won't work for the special case "(alpha)? ()" because it has no */
+/* MR6 rule references or token nodes. It eventually encounters a */
+/* MR6 junction of type EndBlk or EndRule and says to its caller: nothing */
+/* MR6 more here to analyze - must be of the form "(alpha)?". */
+/* MR6 */
+/* MR6 In the case of "(alpha)? ()" it should return a pointer to "()" */
+/* MR6 */
+/* MR6 I think. */
+/* MR6 */
+ if ( p->jtype!=Generic) { /* MR6 */
+ past->alpha_beta_guess_end=1; /* MR14 */
+ return (Junction *)past->p1; /* MR6 */
+ }; /* MR6 */
+ p=(Junction *)p->p1;
+ }
+ }
+ return j;
+}
+
+set
+#ifdef __USE_PROTOS
+First( Junction *j, int k, int jtype, int *max_k )
+#else
+First( j, k, jtype, max_k )
+Junction *j;
+int k;
+int jtype;
+int *max_k;
+#endif
+{
+ Junction *alt1, *alt2;
+ set a, rk, fCurBlk;
+ int savek;
+ int p1, p2;
+
+ int save_maintainBackTrace;
+
+ require(j->ntype==nJunction, "First: non junction passed");
+
+ /* C o m p u t e F I R S T s e t w i t h k l o o k a h e a d */
+ fCurBlk = rk = empty;
+ for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2 )
+ {
+ Junction * p = NULL;
+ Junction * p1junction = NULL;
+ p = analysis_point((Junction *)alt1->p1);
+ p1junction = (Junction *) (alt1->p1);
+#if 0
+ if (p != p1junction) {
+ fprintf(stdout,"Analysis point for #%d is #%d", p1junction->seq, p->seq); /* debug */
+ }
+#endif
+ REACH(p, k, &rk, alt1->fset[k]);
+ require(set_nil(rk), "rk != nil");
+ set_free(rk);
+ set_orin(&fCurBlk, alt1->fset[k]);
+ }
+
+ /* D e t e c t A m b i g u i t i e s */
+ *max_k = 1;
+ for (p1=1,alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2, p1++)
+ {
+ for (p2=1,alt2=(Junction *)alt1->p2; alt2!=NULL; alt2 = (Junction *)alt2->p2, p2++)
+ {
+ savek = k;
+ a = set_and(alt1->fset[k], alt2->fset[k]);
+ while ( !set_nil(a) )
+ {
+ /* if we have hit the max k requested, just give warning */
+ if ( j->approx==k ) {
+ }
+
+ if ( k==CLL_k )
+ {
+#ifdef NOT_USED
+*** int save_LL_k = LL_k;
+*** int save_CLL_k = CLL_k;
+*** /* Get new LL_k from interactive feature if enabled */
+*** if ( AImode )
+*** AmbiguityDialog(j, jtype, alt1, alt2, &CLL_k, &LL_k);
+#endif
+ *max_k = CLL_k;
+ save_maintainBackTrace=MR_MaintainBackTrace;
+ if (AlphaBetaTrace) MR_MaintainBackTrace=0;
+ HandleAmbiguity(j, alt1, alt2, jtype);
+ MR_MaintainBackTrace=save_maintainBackTrace;
+ break;
+ }
+ else
+ {
+ Junction *p = analysis_point((Junction *)alt1->p1);
+ Junction *q = analysis_point((Junction *)alt2->p1);
+ k++; /* attempt ambig alts again with more lookahead */
+
+ REACH(p, k, &rk, alt1->fset[k]);
+ require(set_nil(rk), "rk != nil");
+ REACH(q, k, &rk, alt2->fset[k]);
+ require(set_nil(rk), "rk != nil");
+ set_free(a);
+ a = set_and(alt1->fset[k], alt2->fset[k]);
+ if ( k > *max_k ) *max_k = k;
+ }
+ }
+ set_free(a);
+ k = savek;
+ }
+ }
+
+ return fCurBlk;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset2.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset2.c
new file mode 100644
index 00000000..273a25ba
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/fset2.c
@@ -0,0 +1,2250 @@
+/*
+ * fset2.c
+ *
+ * Compute FIRST sets for full LL(k)
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "pcctscfg.h"
+#include <stdlib.h>
+
+#ifdef PCCTS_USE_STDARG
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+
+/* ick! globals. Used by permute() to track which elements of a set have been used */
+
+static int *findex;
+set *fset; /* MR11 make global */
+static unsigned **ftbl;
+static set *constrain; /* pts into fset. constrains tToken() to 'constrain' */
+int ConstrainSearch;
+int maxk; /* set to initial k upon tree construction request */
+ /* MR11 make global */
+static Tree *FreeList = NULL;
+
+#ifdef __USE_PROTOS
+static int tmember_of_context(Tree *, Predicate *);
+#else
+static int tmember_of_context();
+#endif
+
+#ifdef TREE_DEBUG /* VBox: +def */
+set set_of_tnodes_in_use;
+int stop_on_tnode_seq_number=(-1); /* (-1) to disable */
+#endif
+
+/* Do root
+ * Then each sibling
+ */
+
+void
+#ifdef __USE_PROTOS
+preorder( Tree *tree )
+#else
+preorder( tree )
+Tree *tree;
+#endif
+{
+ if ( tree == NULL ) return;
+ if ( tree->down != NULL ) fprintf(stderr, " (");
+ if ( tree->token == ALT ) fprintf(stderr, " ALT");
+ else fprintf(stderr, " %s", TerminalString(tree->token));
+ if ( tree->token==EpToken ) fprintf(stderr, "(%d)", tree->v.rk);
+ preorder(tree->down);
+ if ( tree->down != NULL ) fprintf(stderr, " )");
+ preorder(tree->right);
+}
+
+#ifdef __USE_PROTOS
+int MR_tree_matches_constraints(int k,set * constrain,Tree *t)
+#else
+int MR_tree_matches_constraints(k,constrain,t)
+ int k;
+ set * constrain;
+ Tree * t;
+#endif
+{
+ int i;
+ Tree *u;
+
+ if (k == 0) return 1;
+
+ /* for testing guard predicates: if the guard tree is shorter
+ than the constraint then it is a match. The reason is that
+ a guard of (A B) should be equivalent to a guard of (A B . . .)
+ where "." matches every token. Thus a match which runs out
+ of tree before constraint is a match.
+ */
+
+ if (t == NULL) return 1;
+ require (set_deg(constrain[0]) == 1,
+ "MR_tree_matches_constraints: set_deg != 1");
+ i=set_int(constrain[0]);
+ if (t->token != i) return 0;
+ if (k-1 == 0) return 1;
+ for (u=t->down; u != NULL; u=u->right) {
+ if (MR_tree_matches_constraints(k-1,&constrain[1],u)) {
+ return 1;
+ };
+ };
+ return 0;
+}
+
+/* check the depth of each primary sibling to see that it is exactly
+ * k deep. e.g.;
+ *
+ * ALT
+ * |
+ * A ------- B
+ * | |
+ * C -- D E
+ *
+ * Remove all branches <= k deep.
+ *
+ * Added by TJP 9-23-92 to make the LL(k) constraint mechanism to work.
+ */
+
+static int pruneCount=0;
+static int prunePeak=200;
+
+Tree *
+#ifdef __USE_PROTOS
+prune( Tree *t, int k )
+#else
+prune( t, k )
+Tree *t;
+int k;
+#endif
+{
+ pruneCount++;
+ if (pruneCount > prunePeak+100) {
+ prunePeak=pruneCount;
+#if 0
+*** fprintf(stderr,"pruneCount=%d\n",pruneCount);
+/*** preorder(t); ***/
+*** fprintf(stderr,"\n",pruneCount);
+#endif
+ };
+ if ( t == NULL ) {
+ pruneCount--;
+ return NULL;
+ };
+ if ( t->token == ALT ) fatal_internal("prune: ALT node in FIRST tree");
+ if ( t->right!=NULL ) t->right = prune(t->right, k);
+ if ( k>1 )
+ {
+ if ( t->down!=NULL ) t->down = prune(t->down, k-1);
+ if ( t->down == NULL )
+ {
+ Tree *r = t->right;
+ t->right = NULL;
+ Tfree(t);
+ pruneCount--;
+ return r;
+ }
+ }
+ pruneCount--;
+ return t;
+}
+
+/* build a tree (root child1 child2 ... NULL) */
+#ifdef PCCTS_USE_STDARG
+Tree *tmake(Tree *root, ...)
+#else
+Tree *tmake(va_alist)
+va_dcl
+#endif
+{
+ Tree *w;
+ va_list ap;
+ Tree *child, *sibling=NULL, *tail=NULL;
+#ifndef PCCTS_USE_STDARG
+ Tree *root;
+#endif
+
+#ifdef PCCTS_USE_STDARG
+ va_start(ap, root);
+#else
+ va_start(ap);
+ root = va_arg(ap, Tree *);
+#endif
+ child = va_arg(ap, Tree *);
+ while ( child != NULL )
+ {
+#ifdef DUM
+ /* added "find end of child" thing TJP March 1994 */
+ for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
+#else
+ w = child;
+#endif
+
+ if ( sibling == NULL ) {sibling = child; tail = w;}
+ else {tail->right = child; tail = w;}
+ child = va_arg(ap, Tree *);
+ }
+
+ /* was "root->down = sibling;" */
+ if ( root==NULL ) root = sibling;
+ else root->down = sibling;
+
+ va_end(ap);
+ return root;
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tnode( int tok )
+#else
+tnode( tok )
+int tok;
+#endif
+{
+ Tree *p, *newblk;
+ static int n=0;
+
+ if ( FreeList == NULL )
+ {
+ /*fprintf(stderr, "tnode: %d more nodes\n", TreeBlockAllocSize);*/
+ if ( TreeResourceLimit > 0 )
+ {
+ if ( (n+TreeBlockAllocSize) >= TreeResourceLimit )
+ {
+ fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);
+ fprintf(stderr, " hit analysis resource limit while analyzing alts %d and %d %s\n",
+ CurAmbigAlt1,
+ CurAmbigAlt2,
+ CurAmbigbtype);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ }
+ newblk = (Tree *)calloc(TreeBlockAllocSize, sizeof(Tree));
+ if ( newblk == NULL )
+ {
+ fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);
+ fprintf(stderr, " out of memory while analyzing alts %d and %d %s\n",
+ CurAmbigAlt1,
+ CurAmbigAlt2,
+ CurAmbigbtype);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ n += TreeBlockAllocSize;
+ for (p=newblk; p<&(newblk[TreeBlockAllocSize]); p++)
+ {
+ p->right = FreeList; /* add all new Tree nodes to Free List */
+ FreeList = p;
+ }
+ }
+ p = FreeList;
+ FreeList = FreeList->right; /* remove a tree node */
+ p->right = NULL; /* zero out ptrs */
+ p->down = NULL;
+ p->token = tok;
+
+ TnodesAllocated++; /* MR10 */
+ TnodesInUse++; /* MR10 */
+ if (TnodesInUse > TnodesPeak) TnodesPeak=TnodesInUse; /* MR10 */
+
+#ifdef TREE_DEBUG
+ require(!p->in_use, "tnode: node in use!");
+ p->in_use = 1;
+ p->seq=TnodesAllocated;
+ set_orel( (unsigned) TnodesAllocated,&set_of_tnodes_in_use);
+ if (stop_on_tnode_seq_number == p->seq) {
+ fprintf(stderr,"\n*** just allocated tnode #%d ***\n",
+ stop_on_tnode_seq_number);
+ };
+#endif
+ return p;
+}
+
+static Tree *
+#ifdef __USE_PROTOS
+eofnode( int k )
+#else
+eofnode( k )
+int k;
+#endif
+{
+ Tree *t=NULL;
+ int i;
+
+ for (i=1; i<=k; i++)
+ {
+ t = tmake(tnode((TokenInd!=NULL?TokenInd[EofToken]:EofToken)), t, NULL);
+ }
+ return t;
+}
+
+
+
+void
+#ifdef __USE_PROTOS
+_Tfree( Tree *t )
+#else
+_Tfree( t )
+Tree *t;
+#endif
+{
+ if ( t!=NULL )
+ {
+#ifdef TREE_DEBUG
+ if (t->seq == stop_on_tnode_seq_number) {
+ fprintf(stderr,"\n*** just freed tnode #%d ***\n",t->seq);
+ };
+ require(t->in_use, "_Tfree: node not in use!");
+ t->in_use = 0;
+ set_rm( (unsigned) t->seq,set_of_tnodes_in_use);
+#endif
+ t->right = FreeList;
+ FreeList = t;
+ TnodesInUse--; /* MR10 */
+ }
+}
+
+/* tree duplicate */
+Tree *
+#ifdef __USE_PROTOS
+tdup( Tree *t )
+#else
+tdup( t )
+Tree *t;
+#endif
+{
+ Tree *u;
+
+ if ( t == NULL ) return NULL;
+ u = tnode(t->token);
+ u->v.rk = t->v.rk;
+ u->right = tdup(t->right);
+ u->down = tdup(t->down);
+ return u;
+}
+
+/* tree duplicate (assume tree is a chain downwards) */
+Tree *
+#ifdef __USE_PROTOS
+tdup_chain( Tree *t )
+#else
+tdup_chain( t )
+Tree *t;
+#endif
+{
+ Tree *u;
+
+ if ( t == NULL ) return NULL;
+ u = tnode(t->token);
+ u->v.rk = t->v.rk;
+ u->down = tdup(t->down);
+ return u;
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tappend( Tree *t, Tree *u )
+#else
+tappend( t, u )
+Tree *t;
+Tree *u;
+#endif
+{
+ Tree *w;
+
+/*** fprintf(stderr, "tappend(");
+ *** preorder(t); fprintf(stderr, ",");
+ *** preorder(u); fprintf(stderr, " )\n");
+*/
+ if ( t == NULL ) return u;
+ if ( t->token == ALT && t->right == NULL ) return tappend(t->down, u);
+ for (w=t; w->right!=NULL; w=w->right) {;}
+ w->right = u;
+ return t;
+}
+
+/* dealloc all nodes in a tree */
+void
+#ifdef __USE_PROTOS
+Tfree( Tree *t )
+#else
+Tfree( t )
+Tree *t;
+#endif
+{
+ if ( t == NULL ) return;
+ Tfree( t->down );
+ Tfree( t->right );
+ _Tfree( t );
+}
+
+/* find all children (alts) of t that require remaining_k nodes to be LL_k
+ * tokens long.
+ *
+ * t-->o
+ * |
+ * a1--a2--...--an <-- LL(1) tokens
+ * | | |
+ * b1 b2 ... bn <-- LL(2) tokens
+ * | | |
+ * . . .
+ * . . .
+ * z1 z2 ... zn <-- LL(LL_k) tokens
+ *
+ * We look for all [Ep] needing remaining_k nodes and replace with u.
+ * u is not destroyed or actually used by the tree (a copy is made).
+ */
+Tree *
+#ifdef __USE_PROTOS
+tlink( Tree *t, Tree *u, int remaining_k )
+#else
+tlink( t, u, remaining_k )
+Tree *t;
+Tree *u;
+int remaining_k;
+#endif
+{
+ Tree *p;
+ require(remaining_k!=0, "tlink: bad tree");
+
+ if ( t==NULL ) return NULL;
+ /*fprintf(stderr, "tlink: u is:"); preorder(u); fprintf(stderr, "\n");*/
+ if ( t->token == EpToken && t->v.rk == remaining_k )
+ {
+ require(t->down==NULL, "tlink: invalid tree");
+ if ( u == NULL ) {
+/* MR10 */ Tree *tt=t->right;
+/* MR10 */ _Tfree(t);
+/* MR10 */ return tt;
+ };
+ p = tdup( u );
+ p->right = t->right;
+ _Tfree( t );
+ return p;
+ }
+ t->down = tlink(t->down, u, remaining_k);
+ t->right = tlink(t->right, u, remaining_k);
+ return t;
+}
+
+/* remove as many ALT nodes as possible while still maintaining semantics */
+Tree *
+#ifdef __USE_PROTOS
+tshrink( Tree *t )
+#else
+tshrink( t )
+Tree *t;
+#endif
+{
+ if ( t == NULL ) return NULL;
+ t->down = tshrink( t->down );
+ t->right = tshrink( t->right );
+ if ( t->down == NULL )
+ {
+ if ( t->token == ALT )
+ {
+ Tree *u = t->right;
+ _Tfree(t);
+ return u; /* remove useless alts */
+ }
+ return t;
+ }
+
+ /* (? (ALT (? ...)) s) ==> (? (? ...) s) where s = sibling, ? = match any */
+ if ( t->token == ALT && t->down->right == NULL)
+ {
+ Tree *u = t->down;
+ u->right = t->right;
+ _Tfree( t );
+ return u;
+ }
+ /* (? (A (ALT t)) s) ==> (? (A t) s) where A is a token; s,t siblings */
+ if ( t->token != ALT && t->down->token == ALT && t->down->right == NULL )
+ {
+ Tree *u = t->down->down;
+ _Tfree( t->down );
+ t->down = u;
+ return t;
+ }
+ return t;
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tflatten( Tree *t )
+#else
+tflatten( t )
+Tree *t;
+#endif
+{
+ if ( t == NULL ) return NULL;
+ t->down = tflatten( t->down );
+ t->right = tflatten( t->right );
+ if ( t->down == NULL ) return t;
+
+ if ( t->token == ALT )
+ {
+ Tree *u;
+ /* find tail of children */
+ for (u=t->down; u->right!=NULL; u=u->right) {;}
+ u->right = t->right;
+ u = t->down;
+ _Tfree( t );
+ return u;
+ }
+ return t;
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tJunc( Junction *p, int k, set *rk )
+#else
+tJunc( p, k, rk )
+Junction *p;
+int k;
+set *rk;
+#endif
+{
+ Tree *t=NULL, *u=NULL;
+ Junction *alt;
+ Tree *tail=NULL, *r;
+
+#ifdef DBG_TRAV
+ fprintf(stderr, "tJunc(%d): %s in rule %s\n", k,
+ decodeJType[p->jtype], ((Junction *)p)->rname);
+#endif
+
+/* MR14 */ if (AlphaBetaTrace && p->alpha_beta_guess_end) {
+/* MR14 */ warnFL(
+/* MR14 */ "not possible to compute follow set for alpha in an \"(alpha)? beta\" block. ",
+/* MR14 */ FileStr[p->file],p->line);
+/* MR14 */ MR_alphaBetaTraceReport();
+/* MR14 */ };
+
+/* MR14 */ if (p->alpha_beta_guess_end) {
+/* MR14 */ return NULL;
+/* MR14 */ }
+
+ if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
+ p->jtype==aPlusBlk || p->jtype==aSubBlk || p->jtype==aOptBlk )
+ {
+ if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) {
+ require(p->lock!=NULL, "rJunc: lock array is NULL");
+ if ( p->lock[k] ) return NULL;
+ p->lock[k] = TRUE;
+ }
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR10 */ };
+
+ TRAV(p->p1, k, rk, tail);
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
+/* MR10 */ };
+
+ if ( p->jtype==RuleBlk ) {p->lock[k] = FALSE; return tail;}
+ r = tmake(tnode(ALT), tail, NULL);
+ for (alt=(Junction *)p->p2; alt!=NULL; alt = (Junction *)alt->p2)
+ {
+ /* if this is one of the added optional alts for (...)+ then break */
+ if ( alt->ignore ) break;
+
+ if ( tail==NULL ) {TRAV(alt->p1, k, rk, tail); r->down = tail;}
+ else
+ {
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR10 */ };
+
+ TRAV(alt->p1, k, rk, tail->right);
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
+/* MR10 */ };
+ if ( tail->right != NULL ) tail = tail->right;
+ }
+ }
+ if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) p->lock[k] = FALSE;
+#ifdef DBG_TREES
+ fprintf(stderr, "blk(%s) returns:",((Junction *)p)->rname); preorder(r); fprintf(stderr, "\n");
+#endif
+ if ( r->down == NULL ) {_Tfree(r); return NULL;}
+ return r;
+ }
+
+ if ( p->jtype==EndRule )
+ {
+ if ( p->halt ) /* don't want FOLLOW here? */
+ {
+/**** if ( ContextGuardTRAV ) return NULL; ****/
+ set_orel( (unsigned) k, rk); /* indicate this k value needed */ /* MR10 cast */
+ t = tnode(EpToken);
+ t->v.rk = k;
+ return t;
+ }
+ require(p->lock!=NULL, "rJunc: lock array is NULL");
+ if ( p->lock[k] ) return NULL;
+ /* if no FOLLOW assume k EOF's */
+ if ( p->p1 == NULL ) return eofnode(k);
+ p->lock[k] = TRUE;
+ }
+
+/* MR14 */ if (p->p1 != NULL && p->guess && p->guess_analysis_point == NULL) {
+/* MR14 */ Node * guess_point;
+/* MR14 */ guess_point=(Node *)analysis_point(p);
+/* MR14 */ if (guess_point == (Node *)p) {
+/* MR14 */ guess_point=p->p1;
+/* MR14 */ }
+/* MR14 */ p->guess_analysis_point=guess_point;
+/* MR14 */ }
+
+ if ( p->p2 == NULL )
+ {
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR10 */ };
+
+/* M14 */ if (p->guess_analysis_point != NULL) {
+/* M14 */ TRAV(p->guess_analysis_point, k, rk,t);
+/* M14 */ } else {
+ TRAV(p->p1, k, rk,t);
+/* M14 */ }
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
+/* MR10 */ };
+
+ if ( p->jtype==EndRule ) p->lock[k]=FALSE;
+ return t;
+ }
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR10 */ };
+
+/* M14 */ if (p->guess_analysis_point != NULL) {
+/* M14 */ TRAV(p->guess_analysis_point, k, rk,t);
+/* M14 */ } else {
+ TRAV(p->p1, k, rk,t);
+/* M14 */ }
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
+/* MR10 */ };
+
+ if ( p->jtype!=RuleBlk && /* MR14 */ !p->guess) TRAV(p->p2, k, rk, u);
+
+ if ( p->jtype==EndRule ) p->lock[k] = FALSE;/* unlock node */
+
+ if ( t==NULL ) return tmake(tnode(ALT), u, NULL);
+ return tmake(tnode(ALT), t, u, NULL);
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tRuleRef( RuleRefNode *p, int k, set *rk_out )
+#else
+tRuleRef( p, k, rk_out )
+RuleRefNode *p;
+int k;
+set *rk_out;
+#endif
+{
+ int k2;
+ Tree *t=NULL, *u=NULL;
+ Junction *r;
+ set rk, rk2;
+ int save_halt;
+ RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
+
+#ifdef DBG_TRAV
+ fprintf(stderr, "tRuleRef: %s\n", p->text);
+#endif
+ if ( q == NULL )
+ {
+ TRAV(p->next, k, rk_out, t);/* ignore undefined rules */
+ return t;
+ }
+ rk = rk2 = empty;
+ if (RulePtr == NULL) fatal("RulePtr==NULL");
+ r = RulePtr[q->rulenum];
+ if ( r->lock[k] ) return NULL;
+ save_halt = r->end->halt;
+ r->end->halt = TRUE; /* don't let reach fall off end of rule here */
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR10 */ };
+
+ TRAV(r, k, &rk, t);
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack);
+/* MR10 */ };
+
+ r->end->halt = save_halt;
+#ifdef DBG_TREES
+ fprintf(stderr, "after ruleref, t is:"); preorder(t); fprintf(stderr, "\n");
+#endif
+ t = tshrink( t );
+ while ( !set_nil(rk) ) { /* any k left to do? if so, link onto tree */
+ k2 = set_int(rk);
+ set_rm(k2, rk);
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR10 */ };
+
+ TRAV(p->next, k2, &rk2, u);
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack);
+/* MR10 */ };
+
+ t = tlink(t, u, k2); /* any alts missing k2 toks, add u onto end */
+ Tfree(u); /* MR10 */
+ }
+ set_free(rk); /* rk is empty, but free its memory */
+ set_orin(rk_out, rk2); /* remember what we couldn't do */
+ set_free(rk2);
+ return t;
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tToken( TokNode *p, int k, set *rk )
+#else
+tToken( p, k, rk )
+TokNode *p;
+int k;
+set *rk;
+#endif
+{
+ Tree *t=NULL, *tset=NULL, *u;
+
+ if (ConstrainSearch) {
+ if (MR_AmbSourceSearch) {
+ require(constrain>=fset&&constrain<=&(fset[CLL_k]),"tToken: constrain is not a valid set");
+ } else {
+ require(constrain>=fset&&constrain<=&(fset[LL_k]),"tToken: constrain is not a valid set");
+ };
+ constrain = &fset[maxk-k+1];
+ }
+
+#ifdef DBG_TRAV
+ fprintf(stderr, "tToken(%d): %s\n", k, TerminalString(p->token));
+ if ( ConstrainSearch ) {
+ fprintf(stderr, "constrain is:"); s_fprT(stderr, *constrain); fprintf(stderr, "\n");
+ }
+#endif
+
+ /* is it a meta token (set of tokens)? */
+
+ if ( !set_nil(p->tset) )
+ {
+ unsigned e=0;
+ set a;
+ Tree *n, *tail = NULL;
+
+ if ( ConstrainSearch ) {
+ a = set_and(p->tset, *constrain);
+ if (set_nil(a)) { /* MR10 */
+ set_free(a); /* MR11 */
+ return NULL; /* MR10 */
+ }; /* MR10 */
+ } else {
+ a = set_dup(p->tset);
+ };
+
+ for (; !set_nil(a); set_rm(e, a))
+ {
+ e = set_int(a);
+ n = tnode(e);
+ if ( tset==NULL ) { tset = n; tail = n; }
+ else { tail->right = n; tail = n; }
+ }
+ set_free( a );
+ }
+ else if ( ConstrainSearch && !set_el(p->token, *constrain) )
+ {
+/* fprintf(stderr, "ignoring token %s(%d)\n", TerminalString(p->token),
+ k);*/
+ return NULL;
+ }
+ else {
+ tset = tnode( p->token );
+ };
+
+/* MR10 */ if (MR_MaintainBackTrace) {
+/* MR10 */ if (k == 1) {
+/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p);
+/* MR13 */ if (MR_SuppressSearch) {
+/* MR13 */ MR_suppressSearchReport();
+/* MR13 */ } else {
+/* MR10 */ MR_backTraceReport();
+/* MR13 */ };
+/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack);
+/* MR11 */ Tfree(tset);
+/* MR11 */ return NULL;
+/* MR10 */ };
+/* MR10 */ };
+
+ if ( k == 1 ) return tset;
+
+ if (MR_MaintainBackTrace) {
+ MR_pointerStackPush(&MR_BackTraceStack,p);
+ };
+
+ TRAV(p->next, k-1, rk, t);
+
+ if (MR_MaintainBackTrace) {
+ Tfree(t);
+ Tfree(tset);
+ MR_pointerStackPop(&MR_BackTraceStack);
+ return NULL;
+ };
+
+ /* here, we are positive that, at least, this tree will not contribute
+ * to the LL(2) tree since it will be too shallow, IF t==NULL.
+ * If doing a context guard walk, then don't prune.
+ */
+ if ( t == NULL && !ContextGuardTRAV ) /* tree will be too shallow */
+ {
+ if ( tset!=NULL ) Tfree( tset );
+ return NULL;
+ }
+#ifdef DBG_TREES
+ fprintf(stderr, "tToken(%d)->next:",k); preorder(t); fprintf(stderr, "\n");
+#endif
+
+ /* if single token root, then just make new tree and return */
+ /* MR10 - set_nil(p->tset) isn't a good test because of ConstraintSearch */
+
+ if (tset->right == NULL) return tmake(tset, t, NULL); /* MR10 */
+
+ /* here we must make a copy of t as a child of each element of the tset;
+ * e.g., "T1..T3 A" would yield ( nil ( T1 A ) ( T2 A ) ( T3 A ) )
+ */
+ for (u=tset; u!=NULL; u=u->right)
+ {
+ /* make a copy of t and hook it onto bottom of u */
+ u->down = tdup(t);
+ }
+ Tfree( t );
+#ifdef DBG_TREES
+ fprintf(stderr, "range is:"); preorder(tset); fprintf(stderr, "\n");
+#endif
+ return tset;
+}
+
+Tree *
+#ifdef __USE_PROTOS
+tAction( ActionNode *p, int k, set *rk )
+#else
+tAction( p, k, rk )
+ActionNode *p;
+int k;
+set *rk;
+#endif
+{
+ Tree *t=NULL;
+ set *save_fset=NULL;
+ int i;
+
+ /* fprintf(stderr, "tAction\n"); */
+
+/* An MR_SuppressSearch is looking for things that can be
+ reached even when the predicate is false.
+
+ There are three kinds of predicates:
+ plain: r1: <<p>>? r2
+ guarded: r1: (A)? => <<p>>? r2
+ ampersand style: r1: (A)? && <<p>>? r2
+
+ Of the three kinds of predicates, only a guard predicate
+ has things which are reachable even when the predicate
+ is false. To be reachable the constraint must *not*
+ match the guard.
+
+*/
+
+ if (p->is_predicate && MR_SuppressSearch) {
+
+ Predicate *pred=p->guardpred;
+
+ if (pred == NULL) {
+ t=NULL;
+ goto EXIT;
+ };
+ constrain = &fset[maxk-k+1];
+ if (pred->k == 1) {
+ set dif;
+ dif=set_dif(*constrain,pred->scontext[1]);
+ if (set_nil(dif)) {
+ set_free(dif);
+ t=NULL;
+ goto EXIT;
+ };
+ set_free(dif);
+ } else {
+ if (MR_tree_matches_constraints(k,constrain,pred->tcontext)) {
+ t=NULL;
+ goto EXIT;
+ };
+ }
+ };
+
+ /* The ampersand predicate differs from the
+ other predicates because its first set
+ is a subset of the first set behind the predicate
+
+ r1: (A)? && <<p>>? r2 ;
+ r2: A | B;
+
+ In this case first[1] of r1 is A, even
+ though first[1] of r2 is {A B}.
+ */
+
+ if (p->is_predicate && p->ampersandPred != NULL) {
+
+ Predicate *pred=p->ampersandPred;
+ Tree *tAND;
+ Tree *tset;
+
+ if (k <= pred->k) {
+ if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);
+ TRAV(p->guardNodes,k,rk,t);
+ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
+ return t;
+ } else {
+ require (k>1,"tAction for ampersandpred: k <= 1");
+ if (ConstrainSearch) {
+ if (MR_AmbSourceSearch) {
+ require(constrain>=fset&&constrain<=&(fset[CLL_k]),
+ "tToken: constrain is not a valid set");
+ } else {
+ require(constrain>=fset&&constrain<=&(fset[LL_k]),
+ "tToken: constrain is not a valid set");
+ };
+ save_fset=(set *) calloc (CLL_k+1,sizeof(set));
+ require (save_fset != NULL,"tAction save_fset alloc");
+ for (i=1; i <= CLL_k ; i++) {
+ save_fset[i]=set_dup(fset[i]);
+ };
+ if (pred->k == 1) {
+ constrain = &fset[maxk-k+1];
+ set_andin(constrain,pred->scontext[1]);
+ if (set_nil(*constrain)) {
+ t=NULL;
+ goto EXIT;
+ };
+ } else {
+ constrain = &fset[maxk-k+1];
+ if (! MR_tree_matches_constraints(pred->k,constrain,pred->tcontext)) {
+ t=NULL;
+ goto EXIT;
+ }; /* end loop on i */
+ }; /* end loop on pred scontext/tcontext */
+ }; /* end if on k > pred->k */
+ }; /* end if on constrain search */
+
+ TRAV(p->next,k,rk,t);
+
+ if (t != NULL) {
+ t=tshrink(t);
+ t=tflatten(t);
+ t=tleft_factor(t);
+ if (pred->tcontext != NULL) {
+ tAND=MR_computeTreeAND(t,pred->tcontext);
+ } else {
+ tset=MR_make_tree_from_set(pred->scontext[1]);
+ tAND=MR_computeTreeAND(t,tset);
+ Tfree(tset);
+ };
+ Tfree(t);
+ t=tAND;
+ };
+ goto EXIT;
+
+ }; /* end if on ampersand predicate */
+
+ TRAV(p->next,k,rk,t);
+
+EXIT:
+ if (save_fset != NULL) {
+ for (i=1 ; i <= CLL_k ; i++) {
+ set_free(fset[i]);
+ fset[i]=save_fset[i];
+ };
+ free ( (char *) save_fset);
+ };
+ return t;
+}
+
+/* see if e exists in s as a possible input permutation (e is always a chain) */
+
+int
+#ifdef __USE_PROTOS
+tmember( Tree *e, Tree *s )
+#else
+tmember( e, s )
+Tree *e;
+Tree *s;
+#endif
+{
+ if ( e==NULL||s==NULL ) return 0;
+/** fprintf(stderr, "tmember(");
+*** preorder(e); fprintf(stderr, ",");
+*** preorder(s); fprintf(stderr, " )\n");
+*/
+ if ( s->token == ALT && s->right == NULL ) return tmember(e, s->down);
+ if ( e->token!=s->token )
+ {
+ if ( s->right==NULL ) return 0;
+ return tmember(e, s->right);
+ }
+ if ( e->down==NULL && s->down == NULL ) return 1;
+ if ( tmember(e->down, s->down) ) return 1;
+ if ( s->right==NULL ) return 0;
+ return tmember(e, s->right);
+}
+
+/* see if e exists in s as a possible input permutation (e is always a chain);
+ * Only check s to the depth of e. In other words, 'e' can be a shorter
+ * sequence than s.
+ */
+int
+#ifdef __USE_PROTOS
+tmember_constrained( Tree *e, Tree *s)
+#else
+tmember_constrained( e, s )
+Tree *e;
+Tree *s;
+#endif
+{
+ if ( e==NULL||s==NULL ) return 0;
+/** fprintf(stderr, "tmember_constrained(");
+*** preorder(e); fprintf(stderr, ",");
+*** preorder(s); fprintf(stderr, " )\n");
+**/
+ if ( s->token == ALT && s->right == NULL )
+ return tmember_constrained(e, s->down);
+ if ( e->token!=s->token )
+ {
+ if ( s->right==NULL ) return 0;
+ return tmember_constrained(e, s->right);
+ }
+ if ( e->down == NULL ) return 1; /* if s is matched to depth of e return */
+ if ( tmember_constrained(e->down, s->down) ) return 1;
+ if ( s->right==NULL ) return 0;
+ return tmember_constrained(e, s->right);
+}
+
+/* combine (? (A t) ... (A u) ...) into (? (A t u)) */
+Tree *
+#ifdef __USE_PROTOS
+tleft_factor( Tree *t )
+#else
+tleft_factor( t )
+Tree *t;
+#endif
+{
+ Tree *u, *v, *trail, *w;
+
+ /* left-factor what is at this level */
+ if ( t == NULL ) return NULL;
+ for (u=t; u!=NULL; u=u->right)
+ {
+ trail = u;
+ v=u->right;
+ while ( v!=NULL )
+ {
+ if ( u->token == v->token )
+ {
+ if ( u->down!=NULL )
+ {
+ for (w=u->down; w->right!=NULL; w=w->right) {;}
+ w->right = v->down; /* link children together */
+ }
+ else u->down = v->down;
+ trail->right = v->right; /* unlink factored node */
+ _Tfree( v );
+ v = trail->right;
+ }
+ else {trail = v; v=v->right;}
+ }
+ }
+ /* left-factor what is below */
+ for (u=t; u!=NULL; u=u->right) u->down = tleft_factor( u->down );
+ return t;
+}
+
+/* remove the permutation p from t if present */
+Tree *
+#ifdef __USE_PROTOS
+trm_perm( Tree *t, Tree *p )
+#else
+trm_perm( t, p )
+Tree *t;
+Tree *p;
+#endif
+{
+ /*
+ fprintf(stderr, "trm_perm(");
+ preorder(t); fprintf(stderr, ",");
+ preorder(p); fprintf(stderr, " )\n");
+ */
+ if ( t == NULL || p == NULL ) return NULL;
+ if ( t->token == ALT )
+ {
+ t->down = trm_perm(t->down, p);
+ if ( t->down == NULL ) /* nothing left below, rm cur node */
+ {
+ Tree *u = t->right;
+ _Tfree( t );
+ return trm_perm(u, p);
+ }
+ t->right = trm_perm(t->right, p); /* look for more instances of p */
+ return t;
+ }
+ if ( p->token != t->token ) /* not found, try a sibling */
+ {
+ t->right = trm_perm(t->right, p);
+ return t;
+ }
+ t->down = trm_perm(t->down, p->down);
+ if ( t->down == NULL ) /* nothing left below, rm cur node */
+ {
+ Tree *u = t->right;
+ _Tfree( t );
+ return trm_perm(u, p);
+ }
+ t->right = trm_perm(t->right, p); /* look for more instances of p */
+ return t;
+}
+
+/* add the permutation 'perm' to the LL_k sets in 'fset' */
+void
+#ifdef __USE_PROTOS
+tcvt( set *fset, Tree *perm )
+#else
+tcvt( fset, perm )
+set *fset;
+Tree *perm;
+#endif
+{
+ if ( perm==NULL ) return;
+ set_orel(perm->token, fset);
+ tcvt(fset+1, perm->down);
+}
+
+/* for each element of ftbl[k], make it the root of a tree with permute(ftbl[k+1])
+ * as a child.
+ */
+Tree *
+#ifdef __USE_PROTOS
+permute( int k, int max_k )
+#else
+permute( k, max_k )
+int k, max_k;
+#endif
+{
+ Tree *t, *u;
+
+ if ( k>max_k ) return NULL;
+ if ( ftbl[k][findex[k]] == nil ) return NULL;
+ t = permute(k+1, max_k);
+ if ( t==NULL&&k<max_k ) /* no permutation left below for k+1 tokens? */
+ {
+ findex[k+1] = 0;
+ (findex[k])++; /* try next token at this k */
+ return permute(k, max_k);
+ }
+
+ u = tmake(tnode(ftbl[k][findex[k]]), t, NULL);
+ if ( k == max_k ) (findex[k])++;
+ return u;
+}
+
+/* Compute LL(k) trees for alts alt1 and alt2 of p.
+ * function result is tree of ambiguous input permutations
+ *
+ * ALGORITHM may change to look for something other than LL_k size
+ * trees ==> maxk will have to change.
+ */
+Tree *
+#ifdef __USE_PROTOS
+VerifyAmbig( Junction *alt1, Junction *alt2, unsigned **ft, set *fs, Tree **t, Tree **u, int *numAmbig )
+#else
+VerifyAmbig( alt1, alt2, ft, fs, t, u, numAmbig )
+Junction *alt1;
+Junction *alt2;
+unsigned **ft;
+set *fs;
+Tree **t;
+Tree **u;
+int *numAmbig;
+#endif
+{
+ set rk;
+ Tree *perm, *ambig=NULL;
+ Junction *p;
+ int k;
+ int tnodes_at_start=TnodesAllocated;
+ int tnodes_at_end;
+ int tnodes_used;
+ set *save_fs;
+ int j;
+
+ save_fs=(set *) calloc(CLL_k+1,sizeof(set));
+ require(save_fs != NULL,"save_fs calloc");
+
+ for (j=0; j <= CLL_k ; j++) save_fs[j]=set_dup(fs[j]);
+
+ maxk = LL_k; /* NOTE: for now, we look for LL_k */
+ ftbl = ft;
+ fset = fs;
+ constrain = &(fset[1]);
+ findex = (int *) calloc(LL_k+1, sizeof(int));
+ if ( findex == NULL )
+ {
+ fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);
+ fprintf(stderr, " out of memory while analyzing alts %d and %d of %s\n",
+ CurAmbigAlt1,
+ CurAmbigAlt2,
+ CurAmbigbtype);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ for (k=1; k<=LL_k; k++) findex[k] = 0;
+
+ rk = empty;
+ ConstrainSearch = 1; /* consider only tokens in ambig sets */
+
+ p = analysis_point((Junction *)alt1->p1);
+ TRAV(p, LL_k, &rk, *t);
+ *t = tshrink( *t );
+ *t = tflatten( *t );
+ *t = tleft_factor( *t ); /* MR10 */
+ *t = prune(*t, LL_k);
+ *t = tleft_factor( *t );
+
+/*** fprintf(stderr, "after shrink&flatten&prune&left_factor:"); preorder(*t); fprintf(stderr, "\n");*/
+ if ( *t == NULL )
+ {
+/*** fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/
+ Tfree( *t ); /* kill if impossible to have ambig */
+ *t = NULL;
+ }
+
+ p = analysis_point((Junction *)alt2->p1);
+
+ TRAV(p, LL_k, &rk, *u);
+ *u = tshrink( *u );
+ *u = tflatten( *u );
+ *t = tleft_factor( *t ); /* MR10 */
+ *u = prune(*u, LL_k);
+ *u = tleft_factor( *u );
+/* fprintf(stderr, "after shrink&flatten&prune&lfactor:"); preorder(*u); fprintf(stderr, "\n");*/
+ if ( *u == NULL )
+ {
+/* fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/
+ Tfree( *u );
+ *u = NULL;
+ }
+
+ for (k=1; k<=LL_k; k++) set_clr( fs[k] );
+
+ ambig = tnode(ALT);
+ k = 0;
+ if ( *t!=NULL && *u!=NULL )
+ {
+ while ( (perm=permute(1,LL_k))!=NULL )
+ {
+/* fprintf(stderr, "chk perm:"); preorder(perm); fprintf(stderr, "\n");*/
+ if ( tmember(perm, *t) && tmember(perm, *u) )
+ {
+/* fprintf(stderr, "ambig upon"); preorder(perm); fprintf(stderr, "\n");*/
+
+ k++;
+ perm->right = ambig->down;
+ ambig->down = perm;
+ tcvt(&(fs[1]), perm);
+ }
+ else Tfree( perm );
+ }
+ }
+
+ for (j=0; j <= CLL_k ; j++) fs[j]=save_fs[j];
+ free( (char *) save_fs);
+
+ tnodes_at_end=TnodesAllocated;
+ tnodes_used=tnodes_at_end - tnodes_at_start;
+
+ if (TnodesReportThreshold > 0 && tnodes_used > TnodesReportThreshold) {
+ fprintf(stdout,"There were %d tuples whose ambiguity could not be resolved by full lookahead\n",k);
+ fprintf(stdout,"There were %d tnodes created to resolve ambiguity between:\n\n",tnodes_used);
+ fprintf(stdout," Choice 1: %s line %d file %s\n",
+ MR_ruleNamePlusOffset( (Node *) alt1),alt1->line,FileStr[alt1->file]);
+ fprintf(stdout," Choice 2: %s line %d file %s\n",
+ MR_ruleNamePlusOffset( (Node *) alt2),alt2->line,FileStr[alt2->file]);
+ for (j=1; j <= CLL_k ; j++) {
+ fprintf(stdout,"\n Intersection of lookahead[%d] sets:\n",j);
+ MR_dumpTokenSet(stdout,2,fs[j]);
+ };
+ fprintf(stdout,"\n");
+ };
+
+ *numAmbig = k;
+ if ( ambig->down == NULL ) {_Tfree(ambig); ambig = NULL;}
+ free( (char *)findex );
+/* fprintf(stderr, "final ambig:"); preorder(ambig); fprintf(stderr, "\n");*/
+ return ambig;
+}
+
+static Tree *
+#ifdef __USE_PROTOS
+bottom_of_chain( Tree *t )
+#else
+bottom_of_chain( t )
+Tree *t;
+#endif
+{
+ if ( t==NULL ) return NULL;
+ for (; t->down != NULL; t=t->down) {;}
+ return t;
+}
+
+/*
+ * Make a tree from k sets where the degree of the first k-1 sets is 1.
+ */
+Tree *
+#ifdef __USE_PROTOS
+make_tree_from_sets( set *fset1, set *fset2 )
+#else
+make_tree_from_sets( fset1, fset2 )
+set *fset1;
+set *fset2;
+#endif
+{
+ set inter;
+ int i;
+ Tree *t=NULL, *n, *u;
+ unsigned *p,*q;
+ require(LL_k>1, "make_tree_from_sets: LL_k must be > 1");
+
+ /* do the degree 1 sets first */
+ for (i=1; i<=LL_k-1; i++)
+ {
+ inter = set_and(fset1[i], fset2[i]);
+ require(set_deg(inter)==1, "invalid set to tree conversion");
+ n = tnode(set_int(inter));
+ if (t==NULL) t=n; else tmake(t, n, NULL);
+ set_free(inter);
+ }
+
+ /* now add the chain of tokens at depth k */
+ u = bottom_of_chain(t);
+ inter = set_and(fset1[LL_k], fset2[LL_k]);
+ if ( (q=p=set_pdq(inter)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
+ /* first one is linked to bottom, then others are sibling linked */
+ n = tnode(*p++);
+ u->down = n;
+ u = u->down;
+ while ( *p != nil )
+ {
+ n = tnode(*p);
+ u->right = n;
+ u = u->right;
+ p++;
+ }
+ free((char *)q);
+
+ return t;
+}
+
+/* create and return the tree of lookahead k-sequences that are in t, but not
+ * in the context of predicates in predicate list p.
+ */
+Tree *
+#ifdef __USE_PROTOS
+tdif( Tree *ambig_tuples, Predicate *p, set *fset1, set *fset2 )
+#else
+tdif( ambig_tuples, p, fset1, fset2 )
+Tree *ambig_tuples;
+Predicate *p;
+set *fset1;
+set *fset2;
+#endif
+{
+ unsigned **ft;
+ Tree *dif=NULL;
+ Tree *perm;
+ set b;
+ int i,k;
+
+ if ( p == NULL ) return tdup(ambig_tuples);
+
+ ft = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));
+ require(ft!=NULL, "cannot allocate ft");
+ for (i=1; i<=CLL_k; i++)
+ {
+ b = set_and(fset1[i], fset2[i]);
+ ft[i] = set_pdq(b);
+ set_free(b);
+ }
+ findex = (int *) calloc(LL_k+1, sizeof(int));
+ if ( findex == NULL )
+ {
+ fatal_internal("out of memory in tdif while checking predicates");
+ }
+ for (k=1; k<=LL_k; k++) findex[k] = 0;
+
+#ifdef DBG_TRAV
+ fprintf(stderr, "tdif_%d[", p->k);
+ preorder(ambig_tuples);
+ fprintf(stderr, ",");
+ preorder(p->tcontext);
+ fprintf(stderr, "] =");
+#endif
+
+ ftbl = ft;
+ while ( (perm=permute(1,p->k))!=NULL )
+ {
+#ifdef DBG_TRAV
+ fprintf(stderr, "test perm:"); preorder(perm); fprintf(stderr, "\n");
+#endif
+ if ( tmember_constrained(perm, ambig_tuples) &&
+ !tmember_of_context(perm, p) )
+ {
+#ifdef DBG_TRAV
+ fprintf(stderr, "satisfied upon"); preorder(perm); fprintf(stderr, "\n");
+#endif
+ k++;
+ if ( dif==NULL ) dif = perm;
+ else
+ {
+ perm->right = dif;
+ dif = perm;
+ }
+ }
+ else Tfree( perm );
+ }
+
+#ifdef DBG_TRAV
+ preorder(dif);
+ fprintf(stderr, "\n");
+#endif
+
+ for (i=1; i<=CLL_k; i++) free( (char *)ft[i] );
+ free((char *)ft);
+ free((char *)findex);
+
+ return dif;
+}
+
+/* is lookahead sequence t a member of any context tree for any
+ * predicate in p?
+ */
+static int
+#ifdef __USE_PROTOS
+tmember_of_context( Tree *t, Predicate *p )
+#else
+tmember_of_context( t, p )
+Tree *t;
+Predicate *p;
+#endif
+{
+ for (; p!=NULL; p=p->right)
+ {
+ if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST )
+ return tmember_of_context(t, p->down);
+ if ( tmember_constrained(t, p->tcontext) ) return 1;
+ if ( tmember_of_context(t, p->down) ) return 1;
+ }
+ return 0;
+}
+
+int
+#ifdef __USE_PROTOS
+is_single_tuple( Tree *t )
+#else
+is_single_tuple( t )
+Tree *t;
+#endif
+{
+ if ( t == NULL ) return 0;
+ if ( t->right != NULL ) return 0;
+ if ( t->down == NULL ) return 1;
+ return is_single_tuple(t->down);
+}
+
+
+/* MR10 Check that a context guard contains only allowed things */
+/* MR10 (mainly token references). */
+
+#ifdef __USE_PROTOS
+int contextGuardOK(Node *p,int h,int *hmax)
+#else
+int contextGuardOK(p,h,hmax)
+ Node *p;
+ int h;
+ int *hmax;
+#endif
+{
+ Junction *j;
+ TokNode *tn;
+
+ if (p == NULL) return 1;
+ if (p->ntype == nToken) {
+ h++;
+ if (h > *hmax) *hmax=h;
+ tn=(TokNode *)p;
+ if (tn->el_label != NULL) {
+ warnFL(eMsg1("a label (\"%s\") for a context guard element is meaningless",tn->el_label),
+ FileStr[p->file],p->line);
+ };
+ return contextGuardOK( ( (TokNode *) p)->next,h,hmax);
+ } else if (p->ntype == nAction) {
+ goto Fail;
+ } else if (p->ntype == nRuleRef) {
+ goto Fail;
+ } else {
+ require (p->ntype == nJunction,"Unexpected ntype");
+ j=(Junction *) p;
+ if (j->jtype != Generic &&
+ j->jtype != aSubBlk && /* pretty sure this one is allowed */
+/**** j->jtype != aOptBlk && ****/ /* pretty sure this one is allowed */ /* MR11 not any more ! */
+ j->jtype != EndBlk) {
+ errFL("A context guard may not contain an option block: {...} or looping block: (...)* or (...)+",
+ FileStr[p->file],p->line);
+ contextGuardOK(j->p1,h,hmax);
+ return 0;
+ };
+ /* do both p1 and p2 so use | rather than || */
+ return contextGuardOK(j->p2,h,hmax) | contextGuardOK(j->p1,h,hmax);
+ };
+Fail:
+ errFL("A context guard may contain only Token references - guard will be ignored",
+ FileStr[p->file],p->line);
+ contextGuardOK( ( (ActionNode *) p)->next,h,hmax);
+ return 0;
+}
+
+/*
+ * Look at a (...)? generalized-predicate context-guard and compute
+ * either a lookahead set (k==1) or a lookahead tree for k>1. The
+ * k level is determined by the guard itself rather than the LL_k
+ * variable. For example, ( A B )? is an LL(2) guard and ( ID )?
+ * is an LL(1) guard. For the moment, you can only have a single
+ * tuple in the guard. Physically, the block must look like this
+ * --o-->TOKEN-->o-->o-->TOKEN-->o-- ... -->o-->TOKEN-->o--
+ * An error is printed for any other type.
+ */
+Predicate *
+#ifdef __USE_PROTOS
+computePredFromContextGuard(Graph blk,int *msgDone) /* MR10 */
+#else
+computePredFromContextGuard(blk,msgDone) /* MR10 */
+ Graph blk;
+ int *msgDone; /* MR10 */
+#endif
+{
+ Junction *junc = (Junction *)blk.left, *p;
+ Tree *t=NULL;
+ Predicate *pred = NULL;
+ set scontext, rk;
+ int ok;
+ int hmax=0;
+
+ require(junc!=NULL && junc->ntype == nJunction, "bad context guard");
+
+/* MR10 Check for anything other than Tokens and generic junctions */
+
+ *msgDone=0; /* MR10 */
+ ok=contextGuardOK( (Node *)junc,0,&hmax); /* MR10 */
+ if (! ok) { /* MR10 */
+ *msgDone=1; /* MR10 */
+ return NULL; /* MR10 */
+ }; /* MR10 */
+ if (hmax == 0) {
+errFL("guard is 0 tokens long",FileStr[junc->file],junc->line); /* MR11 */
+ *msgDone=1;
+ return NULL;
+ };
+ if (hmax > CLL_k) { /* MR10 */
+errFL(eMsgd2("guard is %d tokens long - lookahead is limited to max(k,ck)==%d", /* MR10 */
+ hmax,CLL_k), /* MR10 */
+ FileStr[junc->file],junc->line); /* MR10 */
+ *msgDone=1; /* MR10 */
+ return NULL; /* MR10 */
+ }; /* MR10 */
+
+ rk = empty;
+ p = junc;
+ pred = new_pred();
+ pred->k = hmax; /* MR10 should be CLL_k, not LLK ? */
+ if (hmax > 1 ) /* MR10 was LL_k */
+ {
+ ConstrainSearch = 0;
+ ContextGuardTRAV = 1;
+ TRAV(p, hmax, &rk, t); /* MR10 was LL_k */
+ ContextGuardTRAV = 0;
+ set_free(rk);
+ t = tshrink( t );
+ t = tflatten( t );
+ t = tleft_factor( t );
+/*
+ fprintf(stderr, "ctx guard:");
+ preorder(t);
+ fprintf(stderr, "\n");
+*/
+ pred->tcontext = t;
+ }
+ else
+ {
+ REACH(p, 1, &rk, scontext);
+ require(set_nil(rk), "rk != nil");
+ set_free(rk);
+/*
+ fprintf(stderr, "LL(1) ctx guard is:");
+ s_fprT(stderr, scontext);
+ fprintf(stderr, "\n");
+*/
+ pred->scontext[1] = scontext;
+ }
+
+ list_add(&ContextGuardPredicateList,pred); /* MR13 */
+
+ return pred;
+}
+
+/* MR13
+ When the context guard is originally computed the
+ meta-tokens are not known.
+*/
+
+#ifdef __USE_PROTOS
+void recomputeContextGuard(Predicate *pred)
+#else
+void recomputeContextGuard(pred)
+ Predicate *pred;
+#endif
+{
+ Tree * t=NULL;
+ set scontext;
+ set rk;
+ ActionNode * actionNode;
+ Junction * p;
+
+ actionNode=pred->source;
+ require (actionNode != NULL,"context predicate's source == NULL");
+
+ p=actionNode->guardNodes;
+ require (p != NULL,"context predicate's guardNodes == NULL");
+
+ rk = empty;
+ if (pred->k > 1 )
+ {
+ ConstrainSearch = 0;
+ ContextGuardTRAV = 1;
+ TRAV(p, pred->k, &rk, t);
+ ContextGuardTRAV = 0;
+ set_free(rk);
+ t = tshrink( t );
+ t = tflatten( t );
+ t = tleft_factor( t );
+ Tfree(pred->tcontext);
+ pred->tcontext = t;
+ }
+ else
+ {
+ REACH(p, 1, &rk, scontext);
+ require(set_nil(rk), "rk != nil");
+ set_free(rk);
+ set_free(pred->scontext[1]);
+ pred->scontext[1] = scontext;
+ }
+}
+
+/* MR11 - had enough of flags yet ? */
+
+int MR_AmbSourceSearch=0;
+int MR_AmbSourceSearchGroup=0;
+int MR_AmbSourceSearchChoice=0;
+int MR_AmbSourceSearchLimit=0;
+int MR_matched_AmbAidRule=0;
+
+static set *matchSets[2]={NULL,NULL};
+static int *tokensInChain=NULL;
+static Junction *MR_AmbSourceSearchJ[2];
+
+void MR_traceAmbSourceKclient()
+{
+ int i;
+ set *save_fset;
+ int save_ConstrainSearch;
+ set incomplete;
+ Tree *t;
+
+ if (matchSets[0] == NULL) {
+ matchSets[0]=(set *) calloc (CLL_k+1,sizeof(set));
+ require (matchSets[0] != NULL,"matchSets[0] alloc");
+ matchSets[1]=(set *) calloc (CLL_k+1,sizeof(set));
+ require (matchSets[1] != NULL,"matchSets[1] alloc");
+ };
+
+ for (i=1 ; i <= MR_AmbSourceSearchLimit ; i++) {
+ set_clr(matchSets[0][i]);
+ set_orel( (unsigned) tokensInChain[i],
+ &matchSets[0][i]);
+ set_clr(matchSets[1][i]);
+ set_orel( (unsigned) tokensInChain[i],
+ &matchSets[1][i]);
+ };
+
+ save_fset=fset;
+ save_ConstrainSearch=ConstrainSearch;
+
+
+
+ for (i=0 ; i < 2 ; i++) {
+
+#if 0
+** fprintf(stdout," Choice:%d Depth:%d ",i+1,MR_AmbSourceSearchLimit);
+** fprintf(stdout,"(");
+** for (j=1 ; j <= MR_AmbSourceSearchLimit ; j++) {
+** if (j != 1) fprintf(stdout," ");
+** fprintf(stdout,"%s",TerminalString(tokensInChain[j]));
+** };
+** fprintf(stdout,")\n\n");
+#endif
+
+ fset=matchSets[i];
+
+ MR_AmbSourceSearch=1;
+ MR_MaintainBackTrace=1;
+ MR_AmbSourceSearchChoice=i;
+ ConstrainSearch=1;
+
+ maxk = MR_AmbSourceSearchLimit;
+
+ incomplete=empty;
+ t=NULL;
+
+ constrain = &(fset[1]);
+ MR_pointerStackReset(&MR_BackTraceStack);
+
+ TRAV(MR_AmbSourceSearchJ[i],maxk,&incomplete,t);
+
+ Tfree(t);
+
+ require (set_nil(incomplete),"MR_traceAmbSourceK TRAV incomplete");
+ require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");
+
+ set_free(incomplete);
+ };
+
+ ConstrainSearch=save_ConstrainSearch;
+ fset=save_fset;
+ MR_AmbSourceSearch=0;
+ MR_MaintainBackTrace=0;
+ MR_AmbSourceSearchChoice=0;
+}
+
+#ifdef __USE_PROTOS
+Tree *tTrunc(Tree *t,int depth)
+#else
+Tree *tTrunc(t,depth)
+ Tree *t;
+#endif
+{
+ Tree *u;
+
+ require ( ! (t == NULL && depth > 0),"tree too short");
+
+ if (depth == 0) return NULL;
+
+ if (t->token == ALT) {
+ u=tTrunc(t->down,depth);
+ } else {
+ u=tnode(t->token);
+ u->down=tTrunc(t->down,depth-1);
+ };
+ if (t->right != NULL) u->right=tTrunc(t->right,depth);
+ return u;
+}
+
+#ifdef __USE_PROTOS
+void MR_iterateOverTree(Tree *t,int chain[])
+#else
+void MR_iterateOverTree(t,chain)
+ Tree *t;
+ int chain[];
+#endif
+{
+ if (t == NULL) return;
+ chain[0]=t->token;
+ if (t->down != NULL) {
+ MR_iterateOverTree(t->down,&chain[1]);
+ } else {
+ MR_traceAmbSourceKclient();
+ };
+ MR_iterateOverTree(t->right,&chain[0]);
+ chain[0]=0;
+}
+
+#ifdef __USE_PROTOS
+void MR_traceAmbSourceK(Tree *t,Junction *alt1,Junction *alt2)
+#else
+void MR_traceAmbSourceK(t,alt1,alt2)
+ Tree *t;
+ Junction *alt1;
+ Junction *alt2;
+#endif
+{
+ int i;
+ int depth;
+ int maxDepth;
+ Tree *truncatedTree;
+
+ if (MR_AmbAidRule == NULL) return;
+
+ if ( ! (
+ strcmp(MR_AmbAidRule,alt1->rname) == 0 ||
+ strcmp(MR_AmbAidRule,alt2->rname) == 0 ||
+ MR_AmbAidLine==alt1->line ||
+ MR_AmbAidLine==alt2->line
+ )
+ ) return;
+
+ MR_matched_AmbAidRule++;
+
+ /* there are no token sets in trees, only in TokNodes */
+
+ MR_AmbSourceSearchJ[0]=analysis_point( (Junction *) alt1->p1);
+ MR_AmbSourceSearchJ[1]=analysis_point( (Junction *) alt2->p1);
+
+ if (tokensInChain == NULL) {
+ tokensInChain=(int *) calloc (CLL_k+1,sizeof(int));
+ require (tokensInChain != NULL,"tokensInChain alloc");
+ };
+
+ MR_AmbSourceSearchGroup=0;
+
+ fprintf(stdout,"\n");
+ fprintf(stdout," Ambiguity Aid ");
+ fprintf(stdout,
+ (MR_AmbAidDepth <= LL_k ?
+ "(-k %d -aa %s %s -aad %d)\n\n" :
+ "(-k %d -aa %s %s [-k value limits -aad %d])\n\n"),
+ LL_k,
+ MR_AmbAidRule,
+ (MR_AmbAidMultiple ? "-aam" : ""),
+ MR_AmbAidDepth);
+
+ for (i=0 ; i < 2 ; i++) {
+ fprintf(stdout," Choice %d: %-25s line %d file %s\n",
+ (i+1),
+ MR_ruleNamePlusOffset( (Node *) MR_AmbSourceSearchJ[i]),
+ MR_AmbSourceSearchJ[i]->line,
+ FileStr[MR_AmbSourceSearchJ[i]->file]);
+ };
+
+ fprintf(stdout,"\n");
+
+ if (MR_AmbAidDepth < LL_k) {
+ maxDepth=MR_AmbAidDepth;
+ } else {
+ maxDepth=LL_k;
+ };
+
+ for (depth=1 ; depth <= maxDepth; depth++) {
+ MR_AmbSourceSearchLimit=depth;
+ if (depth < LL_k) {
+ truncatedTree=tTrunc(t,depth);
+ truncatedTree=tleft_factor(truncatedTree);
+ MR_iterateOverTree(truncatedTree,&tokensInChain[1]); /* <===== */
+ Tfree(truncatedTree);
+ } else {
+ MR_iterateOverTree(t,tokensInChain); /* <===== */
+ };
+ fflush(stdout);
+ fflush(stderr);
+ };
+
+ fprintf(stdout,"\n");
+ MR_AmbSourceSearch=0;
+ MR_MaintainBackTrace=0;
+ MR_AmbSourceSearchGroup=0;
+ MR_AmbSourceSearchChoice=0;
+ MR_AmbSourceSearchLimit=0;
+
+}
+
+
+/* this if for k=1 grammars only
+
+ this is approximate only because of the limitations of linear
+ approximation lookahead. Don't want to do a k=3 search when
+ the user only specified a ck=3 grammar
+*/
+
+#ifdef __USE_PROTOS
+void MR_traceAmbSource(set *matchSets,Junction *alt1, Junction *alt2)
+#else
+void MR_traceAmbSource(matchSets,alt1,alt2)
+ set *matchSets;
+ Junction *alt1;
+ Junction *alt2;
+#endif
+{
+ set *save_fset;
+ Junction *p[2];
+ int i;
+ int j;
+ set *dup_matchSets;
+ set intersection;
+ set incomplete;
+ set tokensUsed;
+ int depth;
+
+ if (MR_AmbAidRule == NULL) return;
+ if ( ! (
+ strcmp(MR_AmbAidRule,alt1->rname) == 0 ||
+ strcmp(MR_AmbAidRule,alt2->rname) == 0 ||
+ MR_AmbAidLine==alt1->line ||
+ MR_AmbAidLine==alt2->line
+ )
+ ) return;
+
+ MR_matched_AmbAidRule++;
+
+ save_fset=fset;
+
+ dup_matchSets=(set *) calloc(CLL_k+1,sizeof(set));
+ require (dup_matchSets != NULL,"Can't allocate dup_matchSets");
+
+ p[0]=analysis_point( (Junction *) alt1->p1);
+ p[1]=analysis_point( (Junction *) alt2->p1);
+
+ fprintf(stdout,"\n");
+
+ fprintf(stdout," Ambiguity Aid ");
+ fprintf(stdout,
+ (MR_AmbAidDepth <= CLL_k ?
+ "(-ck %d -aa %s %s -aad %d)\n\n" :
+ "(-ck %d -aa %s %s [-ck value limits -aad %d])\n\n"),
+ CLL_k,
+ MR_AmbAidRule,
+ (MR_AmbAidMultiple ? "-aam" : ""),
+ MR_AmbAidDepth);
+
+ for (i=0 ; i < 2 ; i++) {
+ fprintf(stdout," Choice %d: %-25s line %d file %s\n",
+ (i+1),
+ MR_ruleNamePlusOffset( (Node *) p[i]),
+ p[i]->line,FileStr[p[i]->file]);
+ };
+
+ for (j=1; j <= CLL_k ; j++) {
+ fprintf(stdout,"\n Intersection of lookahead[%d] sets:\n",j);
+ intersection=set_and(alt1->fset[j],alt2->fset[j]);
+ MR_dumpTokenSet(stdout,2,intersection);
+ set_free(intersection);
+ };
+
+ fprintf(stdout,"\n");
+
+ require (1 <= MR_AmbAidDepth && MR_AmbAidDepth <= CLL_k,
+ "illegal MR_AmbAidDepth");
+
+ MR_AmbSourceSearchGroup=0;
+ for (depth=1; depth <= MR_AmbAidDepth; depth++) {
+ MR_AmbSourceSearchLimit=depth;
+ for (i=0 ; i < 2 ; i++) {
+
+/*** fprintf(stdout," Choice:%d Depth:%d\n\n",i+1,depth); ***/
+
+ for (j=0 ; j <= CLL_k ; j++) { dup_matchSets[j]=set_dup(matchSets[j]); };
+ fset=dup_matchSets;
+
+ fflush(output);
+ fflush(stdout);
+
+ MR_AmbSourceSearch=1;
+ MR_MaintainBackTrace=1;
+ MR_AmbSourceSearchChoice=i;
+
+ maxk = depth;
+ tokensUsed=empty;
+ incomplete=empty;
+
+ constrain = &(fset[1]);
+ MR_pointerStackReset(&MR_BackTraceStack);
+
+ REACH(p[i],depth,&incomplete,tokensUsed);
+
+ fflush(output);
+ fflush(stdout);
+
+ require (set_nil(incomplete),"MR_traceAmbSource REACH incomplete");
+ require (MR_BackTraceStack.count == 0,"1: MR_BackTraceStack.count != 0");
+
+ set_free(incomplete);
+ set_free(tokensUsed);
+
+ for (j=0 ; j <= CLL_k ; j++) { set_free(dup_matchSets[j]); };
+ };
+ };
+
+ fprintf(stdout,"\n");
+
+ MR_AmbSourceSearch=0;
+ MR_MaintainBackTrace=0;
+ MR_AmbSourceSearchGroup=0;
+ MR_AmbSourceSearchChoice=0;
+ MR_AmbSourceSearchLimit=0;
+
+ fset=save_fset;
+ free ( (char *) dup_matchSets);
+}
+
+static int itemCount;
+
+void MR_backTraceDumpItemReset() {
+ itemCount=0;
+}
+
+#ifdef __USE_PROTOS
+void MR_backTraceDumpItem(FILE *f,int skip,Node *n)
+#else
+void MR_backTraceDumpItem(f,skip,n)
+ FILE *f;
+ int skip;
+ Node *n;
+#endif
+{
+ TokNode *tn;
+ RuleRefNode *rrn;
+ Junction *j;
+ ActionNode *a;
+
+ switch (n->ntype) {
+ case nToken:
+ itemCount++; if (skip) goto EXIT;
+ tn=(TokNode *)n;
+ if (set_nil(tn->tset)) {
+ fprintf(f," %2d #token %-23s",itemCount,TerminalString(tn->token));
+ } else {
+ fprintf(f," %2d #tokclass %-20s",itemCount,TerminalString(tn->token));
+ };
+ break;
+ case nRuleRef:
+ itemCount++; if (skip) goto EXIT;
+ rrn=(RuleRefNode *)n;
+ fprintf(f," %2d to %-27s",itemCount,rrn->text);
+ break;
+ case nAction:
+ a=(ActionNode *)n;
+ goto EXIT;
+ case nJunction:
+
+ j=(Junction *)n;
+
+ switch (j->jtype) {
+ case aSubBlk:
+ if (j->guess) {
+ itemCount++; if (skip) goto EXIT;
+ fprintf(f," %2d %-30s",itemCount,"in (...)? block at");
+ break;
+ };
+/****** fprintf(f," %2d %-32s",itemCount,"in (...) block at"); *******/
+/****** break; *******/
+ goto EXIT;
+ case aOptBlk:
+ itemCount++; if (skip) goto EXIT;
+ fprintf(f," %2d %-30s",itemCount,"in {...} block");
+ break;
+ case aLoopBlk:
+ itemCount++; if (skip) goto EXIT;
+ fprintf(f," %2d %-30s",itemCount,"in (...)* block");
+ break;
+ case EndBlk:
+ if (j->alpha_beta_guess_end) {
+ itemCount++; if (skip) goto EXIT;
+ fprintf(f," %2d %-30s",itemCount,"end (...)? block at");
+ break;
+ };
+ goto EXIT;
+/****** fprintf(f," %2d %-32s",itemCount,"end of a block at"); *****/
+/****** break; *****/
+ case RuleBlk:
+ itemCount++; if (skip) goto EXIT;
+ fprintf(f," %2d %-30s",itemCount,j->rname);
+ break;
+ case Generic:
+ goto EXIT;
+ case EndRule:
+ itemCount++; if (skip) goto EXIT;
+ fprintf (f," %2d end %-26s",itemCount,j->rname);
+ break;
+ case aPlusBlk:
+ itemCount++; if (skip) goto EXIT;
+ fprintf(f," %2d %-30s",itemCount,"in (...)+ block");
+ break;
+ case aLoopBegin:
+ goto EXIT;
+ };
+ break;
+ };
+ fprintf(f," %-23s line %-4d %s\n",MR_ruleNamePlusOffset(n),n->line,FileStr[n->file]);
+EXIT:
+ return;
+}
+
+
+static PointerStack previousBackTrace={0,0,NULL};
+
+#ifdef __USE_PROTOS
+void MR_backTraceReport(void)
+#else
+void MR_backTraceReport()
+#endif
+{
+ int i;
+ int match = 0;
+ int limitMatch;
+
+ Node *p;
+ TokNode *tn;
+ set remainder;
+ int depth;
+
+ /* Even when doing a k=2 search this routine can get
+ called when there is only 1 token on the stack.
+ This is because something like rRuleRef can change
+ the search value of k from 2 to 1 temporarily.
+ It does this because the it wants to know the k=1
+ first set before it does a k=2 search
+ */
+
+ depth=0;
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ p=(Node *) MR_BackTraceStack.data[i];
+ if (p->ntype == nToken) depth++;
+ };
+
+/* MR14 */ if (MR_AmbSourceSearch) {
+/* MR14 */ require (depth <= MR_AmbSourceSearchLimit,"depth > MR_AmbSourceSearchLimit");
+/* MR14 */ }
+
+ /* MR23 THM - Traceback report was being called at the wrong time for -alpha reports */
+ /* Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu) */
+
+ if (MR_AmbSourceSearchLimit == 0 || depth < MR_AmbSourceSearchLimit) {
+ return;
+ };
+
+ MR_backTraceDumpItemReset();
+
+ limitMatch=MR_BackTraceStack.count;
+ if (limitMatch > previousBackTrace.count) {
+ limitMatch=previousBackTrace.count;
+ };
+
+ for (match=0; match < limitMatch; match++) {
+ if (MR_BackTraceStack.data[match] !=
+ previousBackTrace.data[match]) {
+ break;
+ };
+ };
+
+ /* not sure at the moment why there would be duplicates */
+
+ if (match != MR_BackTraceStack.count) {
+
+ fprintf(stdout," Choice:%d Depth:%d Group:%d",
+ (MR_AmbSourceSearchChoice+1),
+ MR_AmbSourceSearchLimit,
+ ++MR_AmbSourceSearchGroup);
+
+ depth=0;
+ fprintf(stdout," (");
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ p=(Node *) MR_BackTraceStack.data[i];
+ if (p->ntype != nToken) continue;
+ tn=(TokNode *)p;
+ if (depth != 0) fprintf(stdout," ");
+ fprintf(stdout, "%s", TerminalString(tn->token));
+ depth++;
+ if (! MR_AmbAidMultiple) {
+ if (set_nil(tn->tset)) {
+ set_rm( (unsigned) tn->token,fset[depth]);
+ } else {
+ remainder=set_dif(fset[depth],tn->tset);
+ set_free(fset[depth]);
+ fset[depth]=remainder;
+ };
+ };
+ };
+ fprintf(stdout,")\n");
+
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ MR_backTraceDumpItem(stdout, (i<match) ,(Node *) MR_BackTraceStack.data[i]);
+ };
+ fprintf(stdout,"\n");
+ fflush(stdout);
+
+ MR_pointerStackReset(&previousBackTrace);
+
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ MR_pointerStackPush(&previousBackTrace,MR_BackTraceStack.data[i]);
+ };
+
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_setConstrainPointer(set * newConstrainValue)
+#else
+void MR_setConstrainPointer(newConstrainValue)
+ set * newConstrainValue;
+#endif
+{
+ constrain=newConstrainValue;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c
new file mode 100644
index 00000000..851b5651
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/gen.c
@@ -0,0 +1,4797 @@
+/*
+ * gen.c
+ *
+ * Generate C code (ANSI, K&R, C++)
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "pcctscfg.h"
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+
+#define NumExprPerLine 4
+static int on1line=0;
+static set tokensRefdInBlock;
+
+ /* T r a n s l a t i o n T a b l e s */
+
+/* C_Trans[node type] == pointer to function that knows how to translate that node. */
+#ifdef __cplusplus
+void (*C_Trans[NumNodeTypes+1])(...) = {
+ NULL,
+ NULL, /* See next table.
+Junctions have many types */
+ (void (*)(...)) genRuleRef,
+ (void (*)(...)) genToken,
+ (void (*)(...)) genAction
+ };
+#else
+void (*C_Trans[NumNodeTypes+1])() = {
+ NULL,
+ NULL, /* See next table.
+Junctions have many types */
+ genRuleRef,
+ genToken,
+ genAction
+ };
+#endif
+
+/* C_JTrans[Junction type] == pointer to function that knows how to translate that
+ * kind of junction node.
+ */
+#ifdef __cplusplus
+void (*C_JTrans[NumJuncTypes+1])(...) = {
+ NULL,
+ (void (*)(...)) genSubBlk,
+ (void (*)(...)) genOptBlk,
+ (void (*)(...)) genLoopBlk,
+ (void (*)(...)) genEndBlk,
+ (void (*)(...)) genRule,
+ (void (*)(...)) genJunction,
+ (void (*)(...)) genEndRule,
+ (void (*)(...)) genPlusBlk,
+ (void (*)(...)) genLoopBegin
+ };
+#else
+void (*C_JTrans[NumJuncTypes+1])() = {
+ NULL,
+ genSubBlk,
+ genOptBlk,
+ genLoopBlk,
+ genEndBlk,
+ genRule,
+ genJunction,
+ genEndRule,
+ genPlusBlk,
+ genLoopBegin
+ };
+#endif
+
+#define PastWhiteSpace(s) while (*(s) == ' ' || *(s) == '\t') {s++;}
+
+static int tabs = 0;
+
+/* MR6 Got tired of text running off page when using standard tab stops */
+
+#define TAB { int i; \
+ if (TabWidth==0) { \
+ for (i=0; i<tabs; i++) fputc('\t', output); \
+ } else { \
+ for (i=0; i<tabs*TabWidth; i++) fputc(' ',output); \
+ }; \
+ }
+
+static void
+#ifdef __USE_PROTOS
+tab( void )
+#else
+tab( )
+#endif
+TAB
+
+#ifdef __USE_PROTOS
+static char *tokenFollowSet(TokNode *);
+static ActionNode *findImmedAction( Node * );
+static void dumpRetValAssign(char *, char *, RuleRefNode *); /* MR30 */
+static void dumpAfterActions(FILE *output);
+static set ComputeErrorSet(Junction *, int, int);
+static void makeErrorClause(Junction *, set, int, int);
+static void DumpFuncHeader( Junction *, RuleEntry * );
+static int has_guess_block_as_first_item(Junction *);
+static int genExprSets(set *, int);
+static void genExprTree( Tree *t, int k );
+static void genExprTreeOriginal( Tree *t, int k ); /* MR10 */
+static char * findOuterHandlerLabel(ExceptionGroup *eg); /* MR7 */
+static void OutLineInfo(FILE *file,int line,char *fileName); /* MR14 */
+#else
+static char *tokenFollowSet();
+static ActionNode *findImmedAction();
+static void dumpRetValAssign();
+static void dumpAfterActions();
+static set ComputeErrorSet();
+static void makeErrorClause();
+static void DumpFuncHeader();
+static int has_guess_block_as_first_item();
+static int genExprSets();
+static void genExprTree();
+static void genExprTreeOriginal(); /* MR10 */
+static char * findOuterHandlerLabel(); /* MR7 */
+static void OutLineInfo(); /* MR14 */
+#endif
+
+#define gen(s) {tab(); fprintf(output, s);}
+#define gen1(s,a) {tab(); fprintf(output, s,a);}
+#define gen2(s,a,b) {tab(); fprintf(output, s,a,b);}
+#define gen3(s,a,b,c) {tab(); fprintf(output, s,a,b,c);}
+#define gen4(s,a,b,c,d) {tab(); fprintf(output, s,a,b,c,d);}
+#define gen5(s,a,b,c,d,e) {tab(); fprintf(output, s,a,b,c,d,e);}
+#define gen6(s,a,b,c,d,e,f) {tab(); fprintf(output, s,a,b,c,d,e,f);}
+#define gen7(s,a,b,c,d,e,f,g) {tab(); fprintf(output, s,a,b,c,d,e,f,g);}
+
+#define _gen(s) {fprintf(output, s);}
+#define _gen1(s,a) {fprintf(output, s,a);}
+#define _gen2(s,a,b) {fprintf(output, s,a,b);}
+#define _gen3(s,a,b,c) {fprintf(output, s,a,b,c);}
+#define _gen4(s,a,b,c,d){fprintf(output, s,a,b,c,d);}
+#define _gen5(s,a,b,c,d,e){fprintf(output, s,a,b,c,d,e);}
+#define _gen6(s,a,b,c,d,e,f){fprintf(output, s,a,b,c,d,e,f);}
+#define _gen7(s,a,b,c,d,e,f,g){fprintf(output, s,a,b,c,d,e,f,g);}
+
+
+/* MR11 a convenient place to set a break point */
+
+#ifdef __USE_PROTOS
+void MR_break(void)
+#else
+void MR_break()
+#endif
+{
+ return;
+}
+
+/* MR10 genTraceOut(Junction *) */
+
+#ifdef __USE_PROTOS
+static void genTraceOut(Junction *q)
+#else
+static void genTraceOut(q)
+ Junction *q;
+#endif
+{
+ if ( TraceGen ) {
+ if ( GenCC ) {gen1("zzTRACEOUT(\"%s\");\n", q->rname);}
+ else gen1("zzTRACEOUT((ANTLRChar *)\"%s\");\n", q->rname);
+ }
+}
+
+static void
+#ifdef __USE_PROTOS
+warn_about_using_gk_option(void)
+#else
+warn_about_using_gk_option()
+#endif
+{
+ static int warned_already=0;
+
+ if ( !DemandLookahead || warned_already ) return;
+ warned_already = 1;
+ warnNoFL("-gk option could cause trouble for <<...>>? predicates");
+}
+
+void
+#ifdef __USE_PROTOS
+freeBlkFsets( Junction *q )
+#else
+freeBlkFsets( q )
+Junction *q;
+#endif
+{
+ int i;
+ Junction *alt;
+ require(q!=NULL, "freeBlkFsets: invalid node");
+
+ for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
+ {
+ for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]);
+ }
+}
+
+/*
+ * Generate a local variable allocation for each token references
+ * in this block.
+ */
+static void
+#ifdef __USE_PROTOS
+genTokenPointers( Junction *q )
+#else
+genTokenPointers( q )
+Junction *q;
+#endif
+{
+ /* Rule refs are counted and can be referenced, but their
+ * value is not set to anything useful ever.
+ *
+ * The ptrs are to be named _tij where i is the current level
+ * and j is the element number within an alternative.
+ */
+ int first=1, t=0;
+ set a;
+ tokensRefdInBlock = q->tokrefs;
+
+ if ( set_deg(q->tokrefs) == 0 ) return;
+ a = set_dup(q->tokrefs);
+ gen("ANTLRTokenPtr ");
+ for (; !set_nil(a); set_rm(t, a))
+ {
+ t = set_int(a);
+ if ( first ) first = 0;
+ else _gen(",");
+ if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t);
+ _gen2("_t%d%d", BlkLevel, t);
+ if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);}
+ else _gen("=NULL");
+ }
+ _gen(";\n");
+ set_free(a);
+}
+
+static int
+#ifdef __USE_PROTOS
+hasDefaultException(ExceptionGroup *eg)
+#else
+hasDefaultException(eg)
+ExceptionGroup *eg;
+#endif
+{
+ ListNode *q;
+
+ for (q = eg->handlers->next; q!=NULL; q=q->next)
+ {
+ ExceptionHandler *eh = (ExceptionHandler *)q->elem;
+ if ( strcmp("default", eh->signalname)==0 ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+static void
+#ifdef __USE_PROTOS
+dumpException(ExceptionGroup *eg, int no_default_case)
+#else
+dumpException(eg, no_default_case)
+ExceptionGroup *eg;
+int no_default_case;
+#endif
+{
+ char *outerLabel; /* MR7 */
+ int altHandler=0; /* MR7 */
+ int namedHandler=0; /* MR7 */
+
+ outerLabel=findOuterHandlerLabel(eg); /* MR7 */
+
+ if (eg->label != NULL) { /* MR7 */
+ namedHandler=1; /* MR7 */
+ } else if (eg->forRule) { /* MR7 */
+ /* nothing */ /* MR20 */
+ } else { /* MR7 */
+ altHandler=1; /* MR7 */
+ }; /* MR7 */
+
+#if 0
+** if (! eg->used) { /* MR7 */
+** warnFL("exception group never used", /* MR7 */
+** FileStr[eg->altstart->file],eg->altstart->line); /* MR7 */
+** }; /* MR7 */
+#endif
+
+ if (namedHandler) { /* MR7 */
+ gen1("switch ( _signal ) { /* [%s] */\n",eg->label); /* MR7 */
+ } else { /* MR7 */
+ gen("switch ( _signal ) {\n"); /* MR7 */
+ gen("case NoSignal: break; /* MR7 */\n"); /* MR7 */
+ }; /* MR7 */
+ {
+ ListNode *q;
+ for (q = eg->handlers->next; q!=NULL; q=q->next)
+ {
+ ExceptionHandler *eh = (ExceptionHandler *)q->elem;
+ if ( strcmp("default", eh->signalname)==0 ) {
+ gen("default :\n");
+ tabs++;
+ dumpAction(eh->action, output, tabs, -1, 1, 1);
+ gen("_signal=NoSignal; /* MR7 */\n"); /* MR7 */
+ gen("break; /* MR7 */\n"); /* MR7 */
+ tabs--;
+ gen("}\n");
+
+ /* copied from later code in dumpException */ /* MR7 */
+
+ if (namedHandler) { /* MR7 */
+ gen("if (_signal != NoSignal)"); /* MR7 */
+ _gen1(" goto %s_handler; /* MR7 */\n",outerLabel);/* MR7 */
+ } else if (altHandler) { /* MR7 */
+ gen1("goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */
+ };
+ return;
+ }
+ gen1("case %s :\n", eh->signalname);
+ tabs++;
+ if ( eh->action != NULL )
+ {
+ dumpAction(eh->action, output, tabs, -1, 1, 1);
+ gen("break; /* MR7 */\n"); /* MR7 */
+ }
+ tabs--;
+ }
+ }
+ if ( no_default_case ) return;
+
+ gen("default :\n");
+ tabs++; /* MR7 */
+ gen("break; /* MR7 */\n"); /* MR7 */
+ tabs--; /* MR7 */
+
+ tabs++;
+/***** gen("*_retsignal = _signal;\n"); *****/
+
+ tabs--;
+ gen("}\n");
+
+ if (namedHandler) { /* MR7 */
+ gen("if (_signal != NoSignal)"); /* MR7 */
+ _gen1(" goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */
+ } else if (altHandler) { /* MR7 */
+ gen1("goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */
+ };
+
+}
+
+static void
+#ifdef __USE_PROTOS
+dumpExceptions(ListNode *list)
+#else
+dumpExceptions(list)
+ListNode *list;
+#endif
+{
+ ListNode *p;
+
+ for (p = list->next; p!=NULL; p=p->next)
+ {
+ ExceptionGroup *eg = (ExceptionGroup *) p->elem;
+ _gen2("%s%s_handler:\n",
+ eg->label==NULL?"":eg->label,
+ eg->altID==NULL?"":eg->altID);
+ if ( eg->altID!=NULL ) dumpException(eg, 0);
+ else {
+ /* This must be the rule exception handler */
+ dumpException(eg, 1);
+ if ( !hasDefaultException(eg) )
+ {
+ gen("default :\n");
+ tabs++;
+ gen("zzdflthandlers(_signal,_retsignal);\n");
+ tabs--;
+ gen("}\n");
+ }
+ }
+ }
+}
+
+/* For each element label that is found in a rule, generate a unique
+ * Attribute (and AST pointer if GenAST) variable.
+ */
+void
+#ifdef __USE_PROTOS
+genElementLabels(ListNode *list)
+#else
+genElementLabels(list)
+ListNode *list;
+#endif
+{
+ int first=1;
+ ListNode *p;
+
+ if ( GenCC ) {gen("ANTLRTokenPtr");}
+ else {gen("Attrib");}
+ for (p = list->next; p!=NULL; p=p->next)
+ {
+ char *ep = (char *)p->elem;
+ if ( first ) first = 0;
+ else _gen(",");
+ if ( GenCC ) {_gen1(" %s=NULL",ep);}
+ else {_gen1(" %s",ep);}
+ }
+ _gen(";\n");
+
+ if ( !GenAST ) return;
+
+ first = 1;
+ gen("AST");
+ for (p = list->next; p!=NULL; p=p->next)
+ {
+ char *ep = (char *)p->elem;
+ if ( first ) first = 0;
+ else _gen(",");
+ _gen1(" *%s_ast=NULL",ep);
+ }
+ _gen(";\n");
+}
+
+/*
+ * Generate a local variable allocation for each token or rule reference
+ * in this block.
+ */
+static void
+#ifdef __USE_PROTOS
+genASTPointers( Junction *q )
+#else
+genASTPointers( q )
+Junction *q;
+#endif
+{
+ int first=1, t;
+ set a;
+
+ a = set_or(q->tokrefs, q->rulerefs);
+ if ( set_deg(a) > 0 )
+ {
+ gen("AST ");
+ for (; !set_nil(a); set_rm(t, a))
+ {
+ t = set_int(a);
+ if ( first ) first = 0;
+ else _gen(",");
+ _gen2("*_ast%d%d=NULL", BlkLevel, t);
+ }
+ set_free(a);
+ }
+ _gen(";\n");
+}
+
+static void
+#ifdef __USE_PROTOS
+BLOCK_Head( void )
+#else
+BLOCK_Head( )
+#endif
+{
+ gen("{\n");
+ tabs++;
+ if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel);
+}
+
+static void
+#ifdef __USE_PROTOS
+BLOCK_Tail( void )
+#else
+BLOCK_Tail( )
+#endif
+{
+ if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel);
+ if ( !GenCC ) gen("}\n");
+ tabs--;
+ gen("}\n");
+}
+
+static void
+#ifdef __USE_PROTOS
+BLOCK_Preamble( Junction *q )
+#else
+BLOCK_Preamble( q )
+Junction *q;
+#endif
+{
+ ActionNode *a;
+ Junction *begin;
+
+ BLOCK_Head();
+ if ( GenCC ) genTokenPointers(q);
+ if ( GenCC&&GenAST ) genASTPointers(q);
+ if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;\n");
+ if ( q->parm != NULL && !q->predparm ) gen1("zzaPush(%s);\n", q->parm)
+ else if ( !GenCC ) gen("zzMake0;\n");
+ if ( !GenCC ) gen("{\n");
+ if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1);
+ else begin = q;
+ if ( has_guess_block_as_first_item(begin) )
+ {
+ gen("zzGUESS_BLOCK\n");
+ }
+ if ( q->jtype == aLoopBegin )
+ a = findImmedAction( ((Junction *)q->p1)->p1 ); /* look at aLoopBlk */
+ else
+ a = findImmedAction( q->p1 );
+ if ( a!=NULL && !a->is_predicate) {
+/* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1);
+ a->done = 1; /* remove action. We have already handled it */
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+genCombinedPredTreeContextOrig( Predicate *p )
+#else
+genCombinedPredTreeContextOrig( p )
+Predicate *p;
+#endif
+{
+ static set *ctx=NULL; /* genExprSets() is destructive, make copy*/
+ require(p!=NULL, "can't make context tree for NULL pred tree");
+
+#ifdef DBG_PRED
+ fprintf(stderr, "enter genCombinedPredTreeContextOrig(%s,0x%x) with sets:\n", p->expr, p);
+ s_fprT(stderr, p->scontext[1]);
+ fprintf(stderr, "\n");
+#endif
+ if ( p->down == NULL )
+ {
+/*** if ( p->k>1 && p->tcontext!=NULL ) ***/
+ if ( p->tcontext!=NULL )
+ {
+ _gen("(");
+ genExprTree(p->tcontext, 1);
+ _gen(")");
+ }
+/*** else if ( p->k==1 && set_deg(p->scontext[1])>0 ) ***/
+ else if ( set_deg(p->scontext[1])>0 )
+ {
+ if ( ctx==NULL ) ctx = (set *)calloc(CLL_k+1, sizeof(set));
+ require(ctx!=NULL, "ctx cannot allocate");
+ ctx[0]=empty;
+ ctx[1]=set_dup(p->scontext[1]);
+ _gen("(");
+ genExprSets(&(ctx[0]), p->k);
+ _gen(")");
+ set_free(ctx[1]);
+ }
+ else if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) {
+ fatal_internal("pred tree is orphan OR or AND list");
+ }
+ else {
+ if (! HoistPredicateContext) {
+ _gen(" 1 /* no context: prc is off */ ");
+ } else {
+ fatal_internal("pred tree context is empty");
+ };
+ }
+ return;
+ }
+
+/* MR10 - make AND just like OR */
+
+ if ( p->expr == PRED_AND_LIST )
+ {
+ Predicate *list = p->down;
+ for (; list!=NULL; list=list->right)
+ {
+ genCombinedPredTreeContextOrig(list);
+ if ( list->right!=NULL ) _gen("|| /* MR10 was wrong */ ");
+ };
+ return;
+ }
+
+ if ( p->expr == PRED_OR_LIST )
+ {
+ Predicate *list = p->down;
+ for (; list!=NULL; list=list->right)
+ {
+ genCombinedPredTreeContextOrig(list);
+ if ( list->right!=NULL ) _gen("||");
+ };
+ return;
+ };
+
+ fatal("pred tree is really wacked");
+}
+
+/* [genCombinedPredTreeContext] */
+
+void
+#ifdef __USE_PROTOS
+genCombinedPredTreeContext( Predicate *p )
+#else
+genCombinedPredTreeContext( p )
+Predicate *p;
+#endif
+{
+ Tree *t;
+ int predDepth=0;
+
+ if (0 && ! MR_usingPredNames && ! MRhoisting) {
+ genCombinedPredTreeContextOrig(p);
+ } else {
+/* MR13 */ MR_pred_depth(p,&predDepth);
+/* MR13 */ if (predDepth == 1) {
+/* MR13 */
+/* MR13 */ set scontext[2];
+/* MR13 */ scontext[0]=empty;
+/* MR13 */ scontext[1]=MR_compute_pred_set(p);
+/* MR13 */ if (set_nil(scontext[1])) {
+/* MR13 */ _gen(" 1 /* MR12 no context (-prc off) */ ");
+/* MR13 */ } else {
+/* MR13 */ _gen("(");
+/* MR13 */ genExprSets(&scontext[0], 1);
+/* MR13 */ set_free(scontext[1]);
+/* MR13 */ _gen(")");
+/* MR13 */ };
+
+ } else {
+ t=MR_compute_pred_tree_context(p);
+ if (t == NULL) {
+ _gen(" 1 /* MR12 no context (-prc off) */ ");
+ } else {
+ _gen("(");
+ genExprTree(t, 1);
+ Tfree(t); /* MR10 */
+ _gen(")");
+ };
+ };
+ };
+}
+
+/* [genPredTreeGate] */
+
+void
+#ifdef __USE_PROTOS
+genPredTreeGate( Predicate *p, int in_and_expr )
+#else
+genPredTreeGate( p, in_and_expr )
+Predicate *p;
+int in_and_expr;
+#endif
+{
+ if ( in_and_expr )
+ {
+ _gen("!(");
+ genCombinedPredTreeContext(p);
+ _gen(")||");
+ if ( p->down!=NULL ) _gen("\n");
+ }
+ else
+ {
+ _gen("(");
+ genCombinedPredTreeContext(p);
+ _gen(")&&");
+ if ( p->down!=NULL ) _gen("\n");
+ }
+}
+
+#ifdef __USE_PROTOS
+void genPredEntry(Predicate *p,int outer)
+#else
+void genPredEntry(p,outer)
+ Predicate *p;
+ int outer;
+#endif
+{
+ int inverted=0;
+ Predicate *q;
+ int localOuter=outer;
+ int needRP=0;
+
+ if (p == NULL) return;
+
+ if (p->predEntry != NULL && p->predEntry->predLiteral != NULL) {
+ if (p->inverted != p->predEntry->pred->inverted) {
+ _gen("! /* inverted pred */ (");
+ needRP=1;
+ } else {
+ if (!localOuter) _gen("(");
+ needRP=1;
+ };
+ dumpAction(p->predEntry->predLiteral,output,0,p->source->file,p->source->line,0);
+ if (needRP) _gen(")");
+ return;
+ };
+
+ inverted=p->inverted;
+
+ if (inverted) {
+ _gen(" ! /* inverted pred */ (");
+ localOuter=1;
+ };
+
+ if (p->expr == PRED_OR_LIST) {
+ if (!localOuter) _gen("(");
+ for (q=p->down; q != NULL ; q=q->right) {
+ genPredEntry(q,0);
+ if (q->right != NULL) _gen(" || ");
+ };
+ if (!localOuter) _gen(")");
+ } else if (p->expr == PRED_AND_LIST) {
+ if (!localOuter) _gen("(");
+ for (q=p->down; q != NULL ; q=q->right) {
+ genPredEntry(q,0);
+ if (q->right != NULL) _gen(" && ");
+ };
+ if (!localOuter) _gen(")");
+ } else {
+ if (!localOuter) _gen("(");
+ require (p->source != NULL,"predEntry->source == NULL");
+ require (p->source->inverted == 0,"dumpPredEntry p->source->inverted != 0");
+ dumpAction(p->source->action,output,0,p->source->file,p->source->line,0);
+ if (!localOuter) _gen(")");
+ };
+
+ if (inverted) {
+ _gen(")");
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+dumpPredAction(ActionNode *anode,
+ char *s,FILE *output,int tabs,int file,int line,int final_newline)
+#else
+dumpPredAction(anode,
+ s,output,tabs,file,line,final_newline)
+
+ ActionNode *anode;
+ char *s;
+ FILE *output;
+ int tabs;
+ int file;
+ int line;
+ int final_newline;
+#endif
+{
+ PredEntry *predEntry=anode->predEntry;
+ int inverted=anode->inverted;
+ Predicate *workPred;
+
+ if (predEntry == NULL) {
+
+ /* inline predicate literal */
+
+ require(inverted == 0,"dumpPredAction action->inverted");
+ dumpAction(s,output,tabs,file,line,final_newline);
+
+ } else {
+
+ /* a reference to a predicate - possibly with an inverted source */
+
+ if (predEntry->predLiteral != NULL) {
+ if (inverted) _gen("! /* inverted pred */ (");
+ dumpAction(predEntry->predLiteral,output,0,anode->file,anode->line,0);
+ if (inverted) _gen(")");
+ } else {
+ workPred=predicate_dup(predEntry->pred);
+ if (inverted) workPred->inverted=!workPred->inverted;
+ genPredEntry(workPred,1);
+ predicate_free(workPred);
+ };
+ };
+}
+
+/* [genPred] */
+
+void
+#ifdef __USE_PROTOS
+genPred(Predicate *p, Node *j,int suppress_sva)
+#else
+genPred(p,j,suppress_sva)
+ Predicate *p;
+ Node *j;
+ int suppress_sva;
+#endif
+{
+ if ( FoundException && !suppress_sva) {_gen("(_sva=(");} /* MR11 suppress_sva */
+ else {_gen("(");}
+ if ( GenLineInfo && j->file != -1 ) _gen("\n");
+ if (p->source != NULL && p->source->ampersandPred != NULL) {
+ if (p->source->ampersandPred->k == 1) {
+
+ set ctx[2];
+
+ ctx[0]=empty;
+ ctx[1]=set_dup(p->source->ampersandPred->scontext[1]);
+
+ _gen("(");
+ genExprSets(&(ctx[0]), p->k);
+ _gen(") && ");
+ set_free(ctx[1]);
+ } else {
+ _gen("( ");
+ genExprTree(p->source->ampersandPred->tcontext,1);
+ _gen(" ) && ");
+ };
+ };
+
+ dumpPredAction((ActionNode *)p->source,
+ p->expr, output, 0, -1 /*indicates no line info*/, j->line, 0);
+
+ if ( FoundException && !suppress_sva) /* MR11 suppress_sva */
+ {_gen("),_sva)");} /* MR10 - get red of "meant ==" messages */
+ else {_gen(")");}
+}
+
+void
+#ifdef __USE_PROTOS
+MR_distinctORcontextOpt(Predicate *p,Node *j,int in_and_expr)
+#else
+MR_distinctORcontextOpt(p,j,in_and_expr)
+ Predicate *p;
+ Node *j;
+ int in_and_expr;
+#endif
+{
+ Predicate *q;
+
+ _gen(" /* MR10 Distinct OR context optimization */ \n");
+
+ if (in_and_expr) {
+ gen("zzpf=0,\n");
+ for (q=p->down; q != NULL; q=q->right) {
+ gen("( ");
+ genCombinedPredTreeContext(q);
+ _gen(" && (zzpf=1, ");
+ genPred(q,j,0);
+ _gen(" )) ||\n");
+ };
+ gen("!zzpf)");
+ } else {
+ require (0,
+ "MR_distinctORcontextOpt: can't get here when using MR_predSimplify");
+#if 0
+** for (q=p->down; q != NULL; q=q->right) {
+** gen("( ");
+** genCombinedPredTreeContext(q);
+** _gen(" && ");
+** genPred(q,j);
+** if (q->right != NULL) {
+** _gen(" ) ||\n");
+** };
+** };
+** gen(")");
+#endif
+ };
+}
+
+void
+#ifdef __USE_PROTOS
+genPredTreeOrig( Predicate *p, Node *j, int in_and_expr )
+#else
+genPredTreeOrig( p, j, in_and_expr )
+Predicate *p;
+Node *j;
+int in_and_expr;
+#endif
+{
+
+/* MR10 */ int allHaveContext=1;
+/* MR10 */ int noneHaveContext=1;
+
+/* MR10 */ MR_predContextPresent(p,&allHaveContext,&noneHaveContext);
+
+ if ( ! noneHaveContext ) /* MR10 context guards ignored when -prc off */
+ {
+ _gen("(");
+ genPredTreeGate(p, in_and_expr);
+ }
+
+ /* if leaf node, just gen predicate */
+
+ if ( p->down==NULL )
+ {
+ genPred(p,j,0);
+ if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+ return;
+ }
+
+ /* if AND list, do both preds (only two possible) */
+ if ( p->expr == PRED_AND_LIST )
+ {
+#if 0
+** _gen("(");
+** genPredTreeOrig(p->down, j, 1);
+** _gen("&&");
+** genPredTreeOrig(p->down->right, j, 1);
+** _gen(")");
+** if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+** return;
+#endif
+ /* MR11 - make it work with AND with more than two children - like OR */
+
+ Predicate *list;
+ _gen("(");
+ list = p->down;
+ for (; list!=NULL; list=list->right)
+ {
+ genPredTreeOrig(list, j, 1);
+ if ( list->right!=NULL ) _gen("&&");
+ }
+ _gen(")");
+ if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+ return;
+ };
+
+ if ( p->expr == PRED_OR_LIST )
+ {
+ Predicate *list;
+ _gen("(");
+ list = p->down;
+ for (; list!=NULL; list=list->right)
+ {
+ genPredTreeOrig(list, j, 0);
+ if ( list->right!=NULL ) _gen("||");
+ }
+ _gen(")");
+ if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+ return;
+ }
+
+ fatal_internal("genPredTreeOrig: predicate tree is wacked");
+}
+
+#if 0
+** Predicate member dummyPredDepth is no longer used in MR10
+** but we might need it again in the future
+**
+** if (MRhoisting) {
+** if ( !noneHaveContext &&
+** ! in_and_expr &&
+** p->source != NULL &&
+** p->source->dummyPredicateDepth > 0 &&
+** p->down == NULL) {
+** _gen("(");
+** genCombinedPredTreeContext(p);
+** _gen(" )\n");
+** return;
+** };
+** };
+#endif
+
+/* [genPredTree] */
+
+/* in_and_expr
+
+ what to do if the context is wrong
+ what to do if the context is correct but the predicate is false
+
+ remember: if the context is wrong it's the same as if the
+ predicate is true as far as enabling an alternative
+
+ Consider (AND p q r)
+
+ if in an ... && ... expression then you don't want
+ the entire predicate chain to fail just because the
+ context for one component is wrong: so return true
+
+ Consider (OR p q r)
+
+ if in an ... || ... expression then you don't want
+ the entire predicate chain to succeed just because
+ the context for one component is correct when the
+ corresponding test is false: so return false when
+ the context is correct but the test is false.
+*/
+
+void
+#ifdef __USE_PROTOS
+genPredTree( Predicate *p, Node *j, int in_and_expr, int suppress_sva )
+#else
+genPredTree( p, j, in_and_expr, suppress_sva)
+ Predicate *p;
+ Node *j;
+ int in_and_expr;
+ int suppress_sva;
+#endif
+{
+
+ int allHaveContext=1;
+ int noneHaveContext=1;
+ Tree *groupTree;
+ Tree *oneTree;
+ Predicate *q;
+ int identicalORcontextOptimization=0;
+ int identicalANDcontextOptimization=0;
+
+ if (0 && !MR_usingPredNames && !MRhoisting) {
+ genPredTreeOrig(p,j,in_and_expr);
+ return;
+ };
+
+ MR_predContextPresent(p,&allHaveContext,&noneHaveContext);
+
+ if ( ! noneHaveContext ) { /* MR10 context guards ignored when -prc off */
+
+ _gen("(");
+
+ /* MR10 optimize OR predicates which are all leaves */
+
+ if (p->expr == PRED_OR_LIST && MR_allPredLeaves(p->down)) {
+ groupTree=MR_compute_pred_tree_context(p);
+ for (q=p->down ; q != NULL ; q=q->right) {
+ oneTree=MR_compute_pred_tree_context(q);
+ if (! MR_tree_equ(groupTree,oneTree)) {
+ Tfree(oneTree);
+ break;
+ };
+ Tfree(oneTree);
+ };
+ Tfree(groupTree);
+ if (q == NULL) {
+ _gen("/* MR10 individual OR gates suppressed when all predicates are leaves");
+ _gen(" with identical context */\n");
+ genPredTreeGate(p,in_and_expr); /* use the parent's in_and_expr for this gate */
+ identicalORcontextOptimization=1;
+ } else {
+ MR_distinctORcontextOpt(p,j,in_and_expr);
+ return;
+ };
+ } else if (p->expr == PRED_AND_LIST && MR_allPredLeaves(p->down)) {
+
+ /* MR12 optimize AND predicates which are all leaves */
+
+ groupTree=MR_compute_pred_tree_context(p);
+ for (q=p->down ; q != NULL ; q=q->right) {
+ oneTree=MR_compute_pred_tree_context(q);
+ if (! MR_tree_equ(groupTree,oneTree)) {
+ Tfree(oneTree);
+ break;
+ };
+ Tfree(oneTree);
+ };
+ Tfree(groupTree);
+ if (q == NULL) {
+ _gen("/* MR12 individual AND gates suppressed when all predicates are leaves");
+ _gen(" with identical context */\n");
+ genPredTreeGate(p,in_and_expr); /* use the parent's in_and_expr for this gate */
+ identicalANDcontextOptimization=1;
+ } else {
+ genPredTreeGate(p, in_and_expr);
+ };
+ } else {
+ genPredTreeGate(p, in_and_expr);
+ };
+ }
+
+ /* if leaf node, just gen predicate */
+
+ if ( p->down==NULL )
+ {
+ genPred(p,j,suppress_sva);
+ if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+ return;
+ }
+
+ /* if AND list, do both preds (only two possible) */
+ /* MR10 not any more ! */
+
+ if ( p->expr == PRED_AND_LIST )
+ {
+ Predicate *list;
+ _gen("(");
+ list = p->down;
+ for (; list != NULL; list=list->right) {
+ if (identicalANDcontextOptimization) {
+ genPred(list, j,suppress_sva);
+ } else {
+ genPredTree(list, j, 1, suppress_sva); /* in and context */
+ };
+ if ( list->right!=NULL ) _gen("&&");
+ };
+ _gen(")");
+ if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+ return;
+ }
+
+ if ( p->expr == PRED_OR_LIST )
+ {
+ Predicate *list;
+ _gen("(");
+ list = p->down;
+ for (; list!=NULL; list=list->right)
+ {
+ if (identicalORcontextOptimization) {
+ genPred(list, j,suppress_sva);
+ } else {
+ genPredTree(list, j, 0, suppress_sva);
+ };
+ if ( list->right!=NULL ) _gen("||");
+ }
+ _gen(")");
+ if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */
+ return;
+ }
+
+ fatal_internal("predicate tree is wacked");
+}
+
+/* [genPredTreeMainXX] */
+
+Predicate * /* MR10 */
+#ifdef __USE_PROTOS
+genPredTreeMainXX( Predicate *p, Node *j ,int in_and_expr)
+#else
+genPredTreeMainXX( p, j ,in_and_expr)
+ Predicate *p;
+ Node *j;
+ int in_and_expr;
+#endif
+{
+
+ int allHaveContext=1;
+ int noneHaveContext=1;
+
+#if 0
+ fprintf(stderr,"Pred before\n");
+ dumppred(p);
+ fprintf(stderr,"\n");
+ fprintf(stderr,"Pred after\n");
+ dumppred(p);
+ fprintf(stderr,"\n");
+#endif
+
+ p=MR_predSimplifyALL(p); /* MR10 */
+
+ require (MR_predicate_context_completed(p),"predicate context is not complete");
+
+ MR_cleanup_pred_trees(p); /* MR10 */
+
+ MR_predContextPresent(p,&allHaveContext,&noneHaveContext);
+ if (!noneHaveContext & !allHaveContext) {
+ warnFL("predicate contains elements both with and without context",
+ FileStr[j->file],j->line);
+ };
+
+ if (InfoP) {
+ _gen("\n#if 0\n\n");
+ MR_dumpPred(p,1);
+ _gen("#endif\n");
+ };
+ genPredTree(p,j,in_and_expr,0);
+ return p;
+}
+
+Predicate * /* MR10 */
+#ifdef __USE_PROTOS
+genPredTreeMain( Predicate *p, Node *j)
+#else
+genPredTreeMain( p, j)
+ Predicate *p;
+ Node *j;
+#endif
+{
+ return genPredTreeMainXX(p,j,1);
+}
+
+static void
+#ifdef __USE_PROTOS
+genExprTreeOriginal( Tree *t, int k )
+#else
+genExprTreeOriginal( t, k )
+Tree *t;
+int k;
+#endif
+{
+ require(t!=NULL, "genExprTreeOriginal: NULL tree");
+
+ if ( t->token == ALT )
+ {
+ _gen("("); genExprTreeOriginal(t->down, k); _gen(")");
+ if ( t->right!=NULL )
+ {
+ _gen("||");
+ on1line++;
+ if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }
+ _gen("("); genExprTreeOriginal(t->right, k); _gen(")");
+ }
+ return;
+ }
+ if ( t->down!=NULL ) _gen("(");
+ _gen1("LA(%d)==",k);
+ if ( TokenString(t->token) == NULL ) _gen1("%d", t->token)
+ else _gen1("%s", TokenString(t->token));
+ if ( t->down!=NULL )
+ {
+ _gen("&&");
+ on1line++;
+ if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }
+ _gen("("); genExprTreeOriginal(t->down, k+1); _gen(")");
+ }
+ if ( t->down!=NULL ) _gen(")");
+ if ( t->right!=NULL )
+ {
+ _gen("||");
+ on1line++;
+ if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }
+ _gen("("); genExprTreeOriginal(t->right, k); _gen(")");
+ }
+}
+
+#ifdef __USE_PROTOS
+static void MR_LAtokenString(int k,int token)
+#else
+static void MR_LAtokenString(k,token)
+ int k;
+ int token;
+#endif
+{
+ char *ts;
+
+ ts=TokenString(token);
+ if (ts == NULL) {
+ _gen2(" LA(%d)==%d",k,token);
+ } else {
+ _gen2(" LA(%d)==%s",k,ts);
+ };
+}
+
+
+#ifdef __USE_PROTOS
+static int MR_countLeaves(Tree *t)
+#else
+static int MR_countLeaves(t)
+ Tree *t;
+#endif
+{
+ if (t == NULL) return 0;
+ if (t->token == ALT) {
+ return MR_countLeaves(t->down)+MR_countLeaves(t->right);
+ } else {
+ return 1+MR_countLeaves(t->down)+MR_countLeaves(t->right);
+ };
+}
+
+#ifdef __USE_PROTOS
+static void MR_genOneLine(Tree *tree,int k)
+#else
+static void MR_genOneLine(tree,k)
+ Tree *tree;
+ int k;
+#endif
+{
+ if (tree == NULL) return;
+ if (tree->token == ALT) {
+ MR_genOneLine(tree->down,k);
+ } else {
+ MR_LAtokenString(k,tree->token);
+ if (tree->down != NULL &&
+ tree->down->right == NULL) {
+ _gen(" &&");
+ MR_genOneLine(tree->down,k+1);
+ } else if (tree->down != NULL) {
+ _gen(" && (");
+ MR_genOneLine(tree->down,k+1);
+ _gen(")");
+ };
+ };
+ if (tree->right != NULL) {
+ _gen(" ||");
+ MR_genOneLine(tree->right,k);
+ };
+}
+
+static int across;
+static int depth;
+static int lastkonline;
+
+#ifdef __USE_PROTOS
+static void MR_genMultiLine(Tree *tree,int k)
+#else
+static void MR_genMultiLine(tree,k)
+ Tree *tree;
+ int k;
+#endif
+{
+ int i;
+
+ if (tree == NULL) return;
+ if (tree->token == ALT) {
+ MR_genMultiLine(tree,k);
+ } else {
+ MR_LAtokenString(k,tree->token);
+ lastkonline=k;
+ across++;
+ if (tree->down != NULL && tree->down->right == NULL) {
+ if (across > 3) {
+ _gen("\n");
+ across=0;
+ lastkonline=0;
+ for (i=0 ; i < depth+k ; i++) _gen(" ");
+ _gen("&&");
+ } else {
+ _gen(" &&");
+ };
+ MR_genMultiLine(tree->down,k+1);
+ } else if (tree->down != NULL) {
+ _gen("\n");
+ lastkonline=0;
+ across=0;
+ for (i=0 ; i < depth+k ; i++) _gen(" ");
+ _gen("&& (");
+ MR_genMultiLine(tree->down,k+1);
+ _gen(")");
+ };
+ };
+ if (tree->right != NULL) {
+ if (k < lastkonline) {
+ _gen("\n");
+ across=0;
+ lastkonline=0;
+ for (i=0; i < depth+k-1 ; i++) _gen(" ");
+ _gen("||");
+ } else if (across > 3 ) {
+ _gen("\n");
+ across=0;
+ lastkonline=0;
+ for (i=0; i < depth+k ; i++) _gen(" ");
+ _gen("||");
+ } else {
+ _gen(" ||");
+ };
+ MR_genMultiLine(tree->right,k);
+ };
+}
+
+#ifdef __USE_PROTOS
+static void genExprTree(Tree *tree,int k)
+#else
+static void genExprTree(tree,k)
+ Tree *tree;
+ int k;
+#endif
+{
+ int count;
+
+#if 0
+ /* MR20 THM This was probably an error.
+ The routine should probably reference that static
+ "across" and this declaration hides it.
+ */
+
+ int across;
+#endif
+
+ require (tree != NULL,"genExprTree: tree is NULL");
+ require (k > 0,"genExprTree: k <= 0");
+
+ if (0 && !MRhoisting) { /* MR11 make new version standard */
+ genExprTreeOriginal(tree,k);
+ } else {
+ count=MR_countLeaves(tree);
+ if (count < 5) {
+ MR_genOneLine(tree,k);
+ } else {
+ _gen("\n");
+ across=0;
+ depth=0;
+ lastkonline=0;
+ MR_genMultiLine(tree,k);
+ _gen("\n");
+ };
+ };
+}
+
+
+/*
+ * Generate LL(k) type expressions of the form:
+ *
+ * (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) &&
+ * (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) &&
+ * .....
+ * (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn)
+ *
+ * If GenExprSetsOpt generate:
+ *
+ * (setwdi[LA(1)]&(1<<j)) && (setwdi[LA(2)]&(1<<j)) ...
+ *
+ * where n is set_deg(expr) and Ti is some random token and k is the last nonempty
+ * set in fset <=CLL_k.
+ * k=1..CLL_k where CLL_k >= 1.
+ *
+ * This routine is visible only to this file and cannot answer a TRANS message.
+ *
+ */
+
+/* [genExpr] */
+
+static int
+#ifdef __USE_PROTOS
+genExpr( Junction *j )
+#else
+genExpr( j )
+Junction *j;
+#endif
+{
+ int max_k;
+
+ /* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead
+ * from CLL_k..LL_k
+ */
+ {
+ int limit;
+ if ( j->ftree!=NULL ) limit = LL_k;
+ else limit = CLL_k;
+ max_k = genExprSets(j->fset, limit);
+ }
+
+ /* Do tests for real tuples from other productions that conflict with
+ * artificial tuples generated by compression (using sets of tokens
+ * rather than k-trees).
+ */
+ if ( j->ftree != NULL )
+ {
+ _gen(" && !("); genExprTree(j->ftree, 1); _gen(")");
+ }
+
+ if ( ParseWithPredicates && j->predicate!=NULL )
+ {
+ Predicate *p = j->predicate;
+ warn_about_using_gk_option();
+ _gen("&&");
+ j->predicate=genPredTreeMain(p, (Node *)j); /* MR10 */
+ }
+
+ return max_k;
+}
+
+static int
+#ifdef __USE_PROTOS
+genExprSets( set *fset, int limit )
+#else
+genExprSets( fset, limit )
+set *fset;
+int limit;
+#endif
+{
+ int k = 1;
+ int max_k = 0;
+ unsigned *e, *g, firstTime=1;
+
+ if (set_nil(fset[1])) {
+ _gen(" 0 /* MR13 empty set expression - undefined rule ? infinite left recursion ? */ ");
+ MR_BadExprSets++;
+ };
+
+ if ( GenExprSetsOpt )
+ {
+ while ( k <= limit && !set_nil(fset[k]) ) /* MR11 */
+ {
+ if ( set_deg(fset[k])==1 ) /* too simple for a set? */
+ {
+ int e;
+ _gen1("(LA(%d)==",k);
+ e = set_int(fset[k]);
+ if ( TokenString(e) == NULL ) _gen1("%d)", e)
+ else _gen1("%s)", TokenString(e));
+ }
+ else
+ {
+ NewSet();
+ FillSet( fset[k] );
+ _gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<<setnum);
+ }
+ if ( k>max_k ) max_k = k;
+ if ( k == CLL_k ) break;
+ k++;
+ if ( k<=limit && !set_nil(fset[k]) ) _gen(" && "); /* MR11 */
+ on1line++;
+ if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }
+ }
+ return max_k;
+ }
+
+ while ( k<= limit && !set_nil(fset[k]) ) /* MR11 */
+ {
+ if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set");
+ for (; *e!=nil; e++)
+ {
+ if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; }
+ on1line++;
+ if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }
+ _gen1("LA(%d)==",k);
+ if ( TokenString(*e) == NULL ) _gen1("%d", *e)
+ else _gen1("%s", TokenString(*e));
+ }
+ free( (char *)g );
+ _gen(")");
+ if ( k>max_k ) max_k = k;
+ if ( k == CLL_k ) break;
+ k++;
+ if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); } /* MR11 */
+ on1line++;
+ if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); }
+ }
+ return max_k;
+}
+
+/*
+ * Generate code for any type of block. If the last alternative in the block is
+ * empty (not even an action) don't bother doing it. This permits us to handle
+ * optional and loop blocks as well.
+ *
+ * Only do this block, return after completing the block.
+ * This routine is visible only to this file and cannot answer a TRANS message.
+ */
+static set
+#ifdef __USE_PROTOS
+genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly, int * lastAltEmpty /* MR23 */)
+#else
+genBlk( q, jtype, max_k, need_right_curly, lastAltEmpty /* MR23 */)
+Junction *q;
+int jtype;
+int *max_k;
+int *need_right_curly;
+int *lastAltEmpty; /* MR23 */
+#endif
+{
+ set f;
+ Junction *alt;
+ int a_guess_in_block = 0;
+ require(q!=NULL, "genBlk: invalid node");
+ require(q->ntype == nJunction, "genBlk: not junction");
+ *need_right_curly=0;
+ *lastAltEmpty = 0; /* MR23 */
+ if ( q->p2 == NULL ) /* only one alternative? Then don't need if */
+ {
+ if (first_item_is_guess_block((Junction *)q->p1)!=NULL )
+ {
+ if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) {
+ warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line);
+ };
+ gen("zzGUESS\n"); /* guess anyway to make output code consistent */
+/* MR10 disable */ /**** gen("if ( !zzrv )\n"); ****/
+/* MR10 */ gen("if ( !zzrv ) {\n"); tabs++; (*need_right_curly)++;
+ };
+ TRANS(q->p1);
+ return empty; /* no decision to be made-->no error set */
+ }
+
+ f = First(q, 1, jtype, max_k);
+ for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
+ {
+ if ( alt->p2 == NULL ) /* chk for empty alt */
+ {
+ Node *p = alt->p1;
+ if ( p->ntype == nJunction )
+ {
+ /* we have empty alt */
+/* MR23
+ There is a conflict between giving good error information for non-exceptions
+ and making life easy for those using parser exception handling. Consider:
+
+ r: { A } b;
+ b: B;
+
+ with input "C"
+
+ Before MR21 the error message would be "expecting B - found C". After MR21
+ the error message would be "expect A, B - found C". This was good, but it
+ caused problems for those using parser exceptions because the reference to
+ B was generated inside the {...} where B really wasn't part of the block.
+
+ In MR23 this has been changed for the case where exceptions are in use to
+ not generate the extra check in the tail of the {A} block.
+*/
+
+
+/* MR23 */ if (isEmptyAlt( ((Junction *)p)->p1, (Node *)q->end)) {
+/* MR23 */ *lastAltEmpty = 1;
+/* MR23 */ if (FoundException) {
+/* MR23 */ /* code to restore state if a prev alt didn't follow guess */
+/* MR23 */ if ( a_guess_in_block && jtype != aPlusBlk) {
+/* MR23 */ gen("if ( !zzrv ) zzGUESS_DONE; /* MR28 */\n");
+/* MR23 */ }
+/* MR23 */ break;
+/* MR23 */ };
+/* MR28 */ if (jtype == aPlusBlk) {
+/* MR28 */ break;
+/* MR28 */ }
+/* MR23 */ }
+ }
+ } /* end of for loop on alt */
+
+/* MR10 */ if (alt->p2 == NULL &&
+/* MR10 */ ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) {
+/* MR10 */ if (first_item_is_guess_block(alt)) {
+/* MR10 */ warnFL("(...)? as last alternative of block is unnecessary",
+/* MR10 */ FileStr[alt->file],alt->line);
+/* MR10 */ };
+/* MR10 */ };
+
+ if ( alt != q ) gen("else ")
+ else
+ {
+ if ( DemandLookahead ) {
+ if ( !GenCC ) {gen1("LOOK(%d);\n", *max_k);}
+ else gen1("look(%d);\n", *max_k);
+ }
+ }
+
+ if ( alt!=q )
+ {
+ _gen("{\n");
+ tabs++;
+ (*need_right_curly)++;
+ /* code to restore state if a prev alt didn't follow guess */
+ if ( a_guess_in_block )
+ gen("if ( !zzrv ) zzGUESS_DONE;\n");
+ }
+ if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL )
+ {
+ a_guess_in_block = 1;
+ gen("zzGUESS\n");
+ }
+ gen("if ( ");
+ if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && ");
+ genExpr(alt);
+ _gen(" ) ");
+ _gen("{\n");
+ tabs++;
+ TRANS(alt->p1);
+ --tabs;
+ gen("}\n");
+/* MR10 */ if (alt->p2 == NULL) {
+/* MR10 */ if (first_item_is_guess_block(alt)) {
+/* MR10 */ gen("/* MR10 */ else {\n");
+/* MR10 */ tabs++;
+/* MR10 */ (*need_right_curly)++;
+/* MR10 */ /* code to restore state if a prev alt didn't follow guess */
+/* MR10 */ gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;\n");
+/* MR10 */ gen("/* MR10 */ if (0) {} /* last alternative of block is guess block */\n");
+/* MR10 */ };
+/* MR10 */ };
+ }
+ return f;
+}
+
+static int
+#ifdef __USE_PROTOS
+has_guess_block_as_first_item( Junction *q )
+#else
+has_guess_block_as_first_item( q )
+Junction *q;
+#endif
+{
+ Junction *alt;
+
+ for (alt=q; alt != NULL; alt= (Junction *) alt->p2 )
+ {
+ if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1;
+ }
+ return 0;
+}
+
+static int
+#ifdef __USE_PROTOS
+has_guess_block_as_last_item( Junction *q )
+#else
+has_guess_block_as_last_item( q )
+Junction *q;
+#endif
+{
+ Junction *alt;
+
+ if (q == NULL) return 0;
+ for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {};
+ return first_item_is_guess_block( (Junction *) alt->p1) != NULL;
+}
+
+/* MR30 See description of first_item_is_guess_block for background */
+
+Junction *
+#ifdef __USE_PROTOS
+first_item_is_guess_block_extra(Junction *q )
+#else
+first_item_is_guess_block_extra(q)
+Junction *q;
+#endif
+{
+ while ( q!=NULL &&
+ ( ( q->ntype==nAction ) ||
+ ( q->ntype==nJunction &&
+ (q->jtype==Generic || q->jtype == aLoopBlk)
+ )
+ )
+ )
+ {
+ if ( q->ntype==nJunction ) q = (Junction *)q->p1;
+ else q = (Junction *) ((ActionNode *)q)->next;
+ }
+
+ if ( q==NULL ) return NULL;
+ if ( q->ntype!=nJunction ) return NULL;
+ if ( q->jtype!=aSubBlk ) return NULL;
+ if ( !q->guess ) return NULL;
+
+ return q;
+}
+
+/* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node
+ * of (...)?; This function ignores actions and predicates.
+ */
+
+Junction *
+#ifdef __USE_PROTOS
+first_item_is_guess_block( Junction *q )
+#else
+first_item_is_guess_block( q )
+Junction *q;
+#endif
+{
+ Junction * qOriginal = q; /* DEBUG */
+
+ /* MR14 Couldn't find aSubBlock which was a guess block when it lay
+ behind aLoopBlk. The aLoopBlk only appear in conjunction with
+ aLoopBegin, but the routine didn't know that. I think.
+
+ MR14a Added extra parentheses to clarify precedence
+
+ MR30 This appears to have been a mistake. The First set was then
+ computed incorrectly for:
+
+ r : ( (A)? B
+ | C
+ )*
+
+ The routine analysis_point was seeing the guess block when
+ it was still analyzing the loopBegin block. As a consequence,
+ when it looked for the analysis_point it was processing the B, but
+ skipping over the C alternative altogether because it thought
+ it was looking at a guess block, not realizing there was a loop
+ block in front of the loopBegin.
+
+ loopBegin loopBlk subBlk/guess A G EB G B EB EB EB ER
+ | | | ^ ^
+ | | | |
+ | +-> G C G ----------------------+ |
+ | |
+ +--- G G G -------------------------------------+
+
+ Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu).
+
+ MR30 This is still more complicated. This fix caused ambiguity messages
+ to be reported for "( (A B)? )* A B" but not for "( (A B)? )+". Why is
+ there a difference when these are outwardly identical ? It is because the
+ start of a (...)* block is represented by two nodes: a loopBegin block
+ followed by a loopBlock whereas the start of a (...)+ block is
+ represented as a single node: a plusBlock. So if first_item_is_guess_block
+ is called when the current node is a loopBegin it starts with the
+ loop block rather than the sub block which follows the loop block.
+ However, we can't just skip past the loop block because some routines
+ depend on the old implementation. So, we provide a new implementation
+ which does skip the loopBlock. However, which should be called when ?
+ I'm not sure, but my guess is that first_item_is_guess_block_extra (the
+ new one) should only be called for the ambiguity routines.
+
+ */
+
+ while ( q!=NULL &&
+ ( ( q->ntype==nAction ) ||
+ ( q->ntype==nJunction &&
+ (q->jtype==Generic /*** || q->jtype == aLoopBlk ***/ ) /*** MR30 Undo MR14 change ***/
+ )
+ )
+ )
+ {
+ if ( q->ntype==nJunction ) q = (Junction *)q->p1;
+ else q = (Junction *) ((ActionNode *)q)->next;
+ }
+
+ if ( q==NULL ) return NULL;
+ if ( q->ntype!=nJunction ) return NULL;
+ if ( q->jtype!=aSubBlk ) return NULL;
+ if ( !q->guess ) return NULL;
+
+ return q;
+}
+
+/* MR1 */
+/* MR1 10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs */
+/* MR1 */
+
+#define STRINGIZEBUFSIZE 1024
+
+static char stringizeBuf[STRINGIZEBUFSIZE];
+char *
+#ifdef __USE_PROTOS
+stringize(char * s)
+#else
+stringize(s)
+char *s;
+#endif
+
+{
+ char *p;
+ char *stop;
+
+ p=stringizeBuf;
+ stop=&stringizeBuf[1015];
+
+ if (s != 0) {
+ while (*s != 0) {
+ if (p >= stop) {
+ goto stringizeStop;
+ } else if (*s == '\n') {
+ *p++='\\';
+ *p++='n';
+ *p++='\\';
+ *p++=*s++;
+ } else if (*s == '\\') {
+ *p++=*s;
+ *p++=*s++;
+ } else if (*s == '\"') {
+ *p++='\\';
+ *p++=*s++;
+ while (*s != 0) {
+ if (p >= stop) {
+ goto stringizeStop;
+ } else if (*s == '\n') {
+ *p++='\\';
+ *p++=*s++;
+ } else if (*s == '\\') {
+ *p++=*s++;
+ *p++=*s++;
+ } else if (*s == '\"') {
+ *p++='\\';
+ *p++=*s++;
+ break;
+ } else {
+ *p++=*s++;
+ };
+ };
+ } else if (*s == '\'') {
+ *p++=*s++;
+ while (*s != 0) {
+ if (p >= stop) {
+ goto stringizeStop;
+ } else if (*s == '\'') {
+ *p++=*s++;
+ break;
+ } else if (*s == '\\') {
+ *p++=*s++;
+ *p++=*s++;
+ } else if (*s == '\"') {
+ *p++='\\';
+ *p++=*s++;
+ break;
+ } else {
+ *p++=*s++;
+ };
+ };
+ } else {
+ *p++=*s++;
+ };
+ };
+ };
+ goto stringizeExit;
+stringizeStop:
+ *p++='.';
+ *p++='.';
+ *p++='.';
+stringizeExit:
+ *p=0;
+ return stringizeBuf;
+}
+
+#ifdef __USE_PROTOS
+int isNullAction(char *s)
+#else
+int isNullAction(s)
+ char *s;
+#endif
+{
+ char *p;
+ for (p=s; *p != '\0' ; p++) {
+ if (*p != ';' && *p !=' ') return 0;
+ };
+ return 1;
+}
+/* MR1 */
+/* MR1 End of Routine to stringize code for failed predicates msgs */
+/* MR1 */
+
+/* Generate an action. Don't if action is NULL which means that it was already
+ * handled as an init action.
+ */
+void
+#ifdef __USE_PROTOS
+genAction( ActionNode *p )
+#else
+genAction( p )
+ActionNode *p;
+#endif
+{
+ require(p!=NULL, "genAction: invalid node and/or rule");
+ require(p->ntype==nAction, "genAction: not action");
+
+ if ( !p->done ) /* MR10 */ /* MR11 */
+ {
+ if ( p->is_predicate)
+ {
+ if ( p->guardpred != NULL )
+ {
+ Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */
+ gen("if (!");
+ guardDup=genPredTreeMain(guardDup, (Node *)p);
+ predicate_free(guardDup);
+ }
+/* MR10 */ else if (p->ampersandPred != NULL) {
+/* MR10 */ gen("if (!");
+/* MR10 */ p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p);
+/* MR10 */ }
+ else
+ {
+ gen("if (!(");
+ /* make sure that '#line n' is on front of line */
+ if ( GenLineInfo && p->file != -1 ) _gen("\n");
+ dumpPredAction(p,p->action, output, 0, p->file, p->line, 0);
+ _gen(")");
+ }
+
+/* MR23 Change failed predicate macro to have three arguments:
+
+ macro arg 1: The stringized predicate itself
+ macro arg 2: 0 => no user-defined error action
+ 1 => user-defined error action
+ macro arg 3: The user-defined error action
+
+ This gives the user more control of the error action.
+*/
+ tabs++;
+ gen3(") {zzfailed_pred(\"%s\",%s, { %s } );}\n", /* MR23 */
+ stringize(p->action), /* MR23 */
+ (p->pred_fail == NULL ? /* MR23/MR27 */
+ "0 /* report */" : "1 /* user action */"), /* MR23/MR27 */
+ (p->pred_fail == NULL ? /* MR23 */
+ "; /* no user action */" : p->pred_fail)); /* MR23 */
+ tabs--;
+ }
+ else /* not a predicate */
+ {
+ if (! isNullAction(p->action) && !p->noHoist) {
+ if ( FoundGuessBlk ) {
+ if ( GenCC ) {
+ gen("if ( !guessing ) {\n");
+ } else {
+ gen("zzNON_GUESS_MODE {\n");
+ };
+ };
+ dumpActionPlus(p, p->action, output, tabs, p->file, p->line, 1); /* MR21 */
+ if ( FoundGuessBlk ) gen("}\n");
+ };
+ }
+ }
+ TRANS(p->next)
+}
+
+/*
+ * if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in
+ * else pass addr of temp root ptr (&_ast) (don't zzlink it in).
+ *
+ * if ! modifies rule-ref, then never link it in and never pass zzSTR.
+ * Always pass address of temp root ptr.
+ */
+void
+#ifdef __USE_PROTOS
+genRuleRef( RuleRefNode *p )
+#else
+genRuleRef( p )
+RuleRefNode *p;
+#endif
+{
+ Junction *q;
+ char *handler_id = "";
+ RuleEntry *r, *r2;
+ char *parm = "", *exsig = "";
+
+ int genRuleRef_emittedGuessGuard=0; /* MR10 */
+
+ require(p!=NULL, "genRuleRef: invalid node and/or rule");
+ require(p->ntype==nRuleRef, "genRuleRef: not rule reference");
+
+ if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )
+ handler_id = p->altstart->exception_label;
+
+ r = (RuleEntry *) hash_get(Rname, p->text);
+ if ( r == NULL )
+ {
+ warnFL( eMsg1("rule %s not defined",
+ p->text), FileStr[p->file], p->line );
+ return;
+ }
+
+/* MR8 5-Aug-97 Reported by S.Bochnak@microtool.com.pl */
+/* Don't do assign when no return values declared */
+/* Move definition of q up and use it to guard p->assign */
+
+ q = RulePtr[r->rulenum]; /* find definition of ref'd rule */ /* MR8 */
+
+ r2 = (RuleEntry *) hash_get(Rname, p->rname);
+ if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
+
+ OutLineInfo(output,p->line,FileStr[p->file]);
+
+ if ( GenCC && GenAST ) {
+ gen("_ast = NULL;\n");
+ }
+
+ if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) { /* MR8 */
+ if ( GenCC ) {
+ gen("if ( !guessing ) {\n");
+ } else {
+ gen("zzNON_GUESS_MODE {\n");
+ };
+ tabs++; /* MR11 */
+ genRuleRef_emittedGuessGuard=1; /* MR11 */
+ };
+
+ if ( FoundException ) exsig = "&_signal";
+
+ tab();
+ if ( GenAST )
+ {
+ if ( GenCC ) {
+/**** if ( r2->noAST || p->astnode==ASTexclude )
+****/
+ {
+/**** _gen("_ast = NULL;\n");
+****/
+ parm = "&_ast";
+ }
+/*** we always want to set just a pointer now, then set correct
+pointer after
+
+ else {
+ _gen("_astp =
+(_tail==NULL)?(&_sibling):(&(_tail->_right));\n");
+ parm = "_astp";
+ }
+****/
+ }
+ else {
+ if ( r2->noAST || p->astnode==ASTexclude )
+ {
+ _gen("_ast = NULL; ");
+ parm = "&_ast";
+ }
+ else parm = "zzSTR";
+ }
+ if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */
+ {
+ if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */
+ else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
+ }
+ if ( FoundException ) {
+ _gen5("%s%s(%s,&_signal%s%s); ",
+ RulePrefix,
+ p->text,
+ parm,
+ (p->parms!=NULL)?",":"",
+ (p->parms!=NULL)?p->parms:"");
+ if ( p->ex_group!=NULL ) {
+ _gen("\n");
+ gen("if (_signal) {\n");
+ tabs++;
+ dumpException(p->ex_group, 0);
+ tabs--;
+ gen("}");
+ }
+ else {
+ _gen1("if (_signal) goto %s_handler;", handler_id);
+ }
+ }
+ else {
+ _gen5("%s%s(%s%s%s);",
+ RulePrefix,
+ p->text,
+ parm,
+ (p->parms!=NULL)?",":"",
+ (p->parms!=NULL)?p->parms:"");
+ }
+ if ( GenCC && (r2->noAST || p->astnode==ASTexclude) )
+ {
+ /* rule has a ! or element does */
+ /* still need to assign to #i so we can play with it */
+ _gen("\n");
+ gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum);
+ }
+ else if ( !r2->noAST && p->astnode == ASTinclude )
+ {
+ /* rule doesn't have a ! and neither does element */
+/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) {
+/* MR10 */ _gen("\n");
+/* MR10 */ if (GenCC) gen ("if (!guessing) { /* MR10 */")
+/* MR10 */ else gen ("if (!zzguessing) { /* MR10 */\n");
+/* MR10 */ tabs++;
+/* MR10 */ };
+ if ( GenCC ) {
+ _gen("\n");
+ gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);\n");
+ gen2("_ast%d%d = (AST *)_ast;\n", BlkLevel-1, p->elnum);
+ tab();
+ }
+ else _gen(" ");
+ if ( GenCC ) {
+ _gen("ASTBase::"); }
+ else _gen("zz");
+ _gen("link(_root, &_sibling, &_tail);");
+
+/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) { /* MR10 */
+/* MR10 */ _gen("\n");
+/* MR10 */ tabs--;
+/* MR10 */ if (GenCC) gen ("}; /* MR10 */")
+/* MR10 */ else gen ("}; /* MR10 */");
+/* MR10 */ };
+ }
+ }
+ else
+ {
+ if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */
+ {
+ if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */
+ else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum);
+ }
+ if ( FoundException ) {
+ _gen4("%s%s(&_signal%s%s); ",
+ RulePrefix,
+ p->text,
+ (p->parms!=NULL)?",":"",
+ (p->parms!=NULL)?p->parms:"");
+ if ( p->ex_group!=NULL ) {
+ _gen("\n");
+ gen("if (_signal) {\n");
+ tabs++;
+ dumpException(p->ex_group, 0);
+ tabs--;
+ gen("}");
+ }
+ else {
+ _gen1("if (_signal) goto %s_handler;", handler_id);
+ }
+ }
+ else {
+ _gen3("%s%s(%s);",
+ RulePrefix,
+ p->text,
+ (p->parms!=NULL)?p->parms:"");
+ }
+ if ( p->assign!=NULL && q->ret!=NULL ) _gen("\n"); /* MR8 */
+ }
+
+ if ( p->assign!=NULL && q->ret!=NULL) { /* MR8 */
+ if ( hasMultipleOperands(p->assign) ) /* MR23 */
+ {
+ _gen("\n");
+ dumpRetValAssign(p->assign, q->ret, p); /* MR30 */
+ _gen("}");
+ }
+ }
+ _gen("\n");
+
+ /* Handle element labels now */
+ if ( p->el_label!=NULL )
+ {
+ if ( GenAST )
+ {
+ if ( GenCC ) {
+ gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);
+ }
+ else {gen1("%s_ast = zzastCur;\n", p->el_label);}
+ }
+ else if (!GenCC ) {
+ gen1("%s = zzaCur;\n", p->el_label);
+ }
+ }
+
+ if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) { /* MR8 */
+ /* in guessing mode, don't branch to handler upon error */
+ tabs--; /* MR11 */
+ gen("} else {\n");
+ tabs++; /* MR11 */
+ if ( FoundException ) {
+ gen6("%s%s(%s%s&_signal%s%s);\n",
+ RulePrefix,
+ p->text,
+ parm,
+ (*parm!='\0')?",":"",
+ (p->parms!=NULL)?",":"",
+ (p->parms!=NULL)?p->parms:"");
+ }
+ else {
+ gen5("%s%s(%s%s%s);\n",
+ RulePrefix,
+ p->text,
+ parm,
+ (p->parms!=NULL && *parm!='\0')?",":"",
+ (p->parms!=NULL)?p->parms:"");
+ }
+ tabs--; /* MR11 */
+ gen("}\n");
+ }
+ TRANS(p->next)
+}
+
+/*
+ * Generate code to match a token.
+ *
+ * Getting the next token is tricky. We want to ensure that any action
+ * following a token is executed before the next GetToken();
+ */
+void
+#ifdef __USE_PROTOS
+genToken( TokNode *p )
+#else
+genToken( p )
+TokNode *p;
+#endif
+{
+ RuleEntry *r;
+ char *handler_id = "";
+ ActionNode *a;
+ char *set_name;
+ char *set_nameErrSet;
+ int complement;
+ int ast_label_in_action = 0; /* MR27 */
+ int pushedCmodeAST = 0; /* MR27 */
+
+ require(p!=NULL, "genToken: invalid node and/or rule");
+ require(p->ntype==nToken, "genToken: not token");
+ if ( p->altstart!=NULL && p->altstart->exception_label!=NULL )
+ handler_id = p->altstart->exception_label;
+
+ r = (RuleEntry *) hash_get(Rname, p->rname);
+ if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;}
+
+/*
+ * MR27 Has the element label been referenced as an AST (with the # operator) ?
+ * If so, then we'll want to build the AST even though the user has used
+ * the ! operator.
+ */
+/* MR27 */ if (GenAST && p->el_label != NULL) {
+/* MR27 */ ast_label_in_action = list_search_cstring(r->ast_labels_in_actions,
+/* MR27 */ p->el_label);
+/* MR27 */ }
+
+ OutLineInfo(output,p->line,FileStr[p->file]);
+
+ if ( !set_nil(p->tset) ) /* implies '.', ~Tok, or tokenclass */
+ {
+ unsigned e;
+ unsigned eErrSet = 0;
+ set b;
+ set bErrSet; /* MR23 */
+ b = set_dup(p->tset);
+ bErrSet = set_dup(p->tset); /* MR23 */
+ complement = p->complement; /* MR23 */
+ if ( p->tclass!=NULL && complement == 0 /* MR23 */) { /* token class not complemented*/
+ static char buf[MaxRuleName+20]; /* MR23 */
+ static char bufErrSet[MaxRuleName+20]; /* MR23 */
+ if ( p->tclass->dumped ) {
+ e = p->tclass->setnum;
+ eErrSet = p->tclass->setnumErrSet;
+ }
+ else {
+ e = DefErrSet(&b, 0, TokenString(p->token));
+ eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errset");
+ p->tclass->dumped = 1; /* indicate set has been created */
+ p->tclass->setnum = e;
+ p->tclass->setnumErrSet = eErrSet; /* MR23 */
+ }
+ sprintf(buf, "%s_set", TokenString(p->token));
+ sprintf(bufErrSet, "%s_errset", TokenString(p->token)); /* MR23 */
+ set_name = buf;
+ set_nameErrSet = bufErrSet; /* MR23 */
+ }
+
+ /* MR23 - Forgot about the case of ~TOKCLASS. */
+
+ else if ( p->tclass!=NULL && complement != 0 /* MR23 */)
+ {
+ static char buf[MaxRuleName+20]; /* MR23 */
+ static char bufErrSet[MaxRuleName+20]; /* MR23 */
+ if ( p->tclass->dumpedComplement ) {
+ e = p->tclass->setnumComplement;
+ eErrSet = p->tclass->setnumErrSetComplement;
+ }
+ else {
+ e = DefErrSetWithSuffix(0, &b, 0, TokenString(p->token), "_setbar");
+ eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errsetbar");
+ p->tclass->dumpedComplement = 1; /* indicate set has been created */
+ p->tclass->setnumComplement = e;
+ p->tclass->setnumErrSetComplement = eErrSet; /* MR23 */
+ }
+ sprintf(buf, "%s_setbar", TokenString(p->token));
+ sprintf(bufErrSet, "%s_errsetbar", TokenString(p->token)); /* MR23 */
+ set_name = buf;
+ set_nameErrSet = bufErrSet; /* MR23 */
+ }
+ else { /* wild card */
+ static char buf[sizeof("zzerr")+10];
+ static char bufErrSet[sizeof("zzerr")+10];
+ int n = DefErrSet( &b, 0, NULL );
+ int nErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, NULL, "_set");
+ if ( GenCC ) sprintf(buf, "err%d", n);
+ else sprintf(buf, "zzerr%d", n);
+ if ( GenCC ) sprintf(bufErrSet, "err%d", nErrSet);
+ else sprintf(bufErrSet, "zzerr%d", nErrSet);
+ set_name = buf;
+ set_nameErrSet = bufErrSet;
+ }
+
+ if ( !FoundException ) {
+/* MR23 */ gen2("zzsetmatch(%s, %s);", set_name, set_nameErrSet);
+ }
+ else if ( p->ex_group==NULL ) {
+ if ( p->use_def_MT_handler )
+ gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);",
+ set_name,
+ p->token,
+ tokenFollowSet(p))
+ else
+ gen2("zzsetmatch_wsig(%s, %s_handler);",
+ set_name,
+ handler_id);
+ }
+ else
+ {
+ gen1("if ( !_setmatch_wsig(%s) ) {\n", set_name);
+ tabs++;
+/* MR6 */ if (FoundGuessBlk) {
+/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}
+/* MR6 */ else gen("if ( zzguessing ) goto fail;\n");
+/* MR6 */ };
+ gen("_signal=MismatchedToken;\n");
+ dumpException(p->ex_group, 0);
+ tabs--;
+ gen("}\n");
+ }
+ set_free(b);
+ set_free(bErrSet);
+ }
+ else if ( TokenString(p->token)!=NULL )
+ {
+ if ( FoundException ) {
+ if ( p->use_def_MT_handler )
+ gen2("zzmatch_wdfltsig(%s,%s);",TokenString(p->token),tokenFollowSet(p))
+ else if ( p->ex_group==NULL )
+ {
+ gen2("zzmatch_wsig(%s, %s_handler);",
+ TokenString(p->token),
+ handler_id);
+ }
+ else
+ {
+/* MR6 */ if (GenCC) {
+/* MR6 */ gen1("if ( !_match_wsig(%s) ) {\n", TokenString(p->token));
+/* MR6 */ } else {
+/* MR6 */ gen1("if ( !_zzmatch_wsig(%s) ) {\n", TokenString(p->token));
+/* MR6 */ };
+ tabs++;
+/* MR6 */ if (FoundGuessBlk) {
+/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}
+/* MR6 */ else gen("if ( zzguessing ) goto fail;\n");
+/* MR6 */ };
+ gen("_signal=MismatchedToken;\n");
+ dumpException(p->ex_group, 0);
+ tabs--;
+ gen("}\n");
+ }
+ }
+ else gen1("zzmatch(%s);", TokenString(p->token));
+ }
+ else {
+ if ( FoundException ) {
+ if ( p->use_def_MT_handler )
+ gen2("zzmatch_wdfltsig((ANTLRTokenType)%d,%s);",
+ p->token,tokenFollowSet(p))
+ else
+ gen2("zzmatch_wsig(%d,%s_handler);",p->token,handler_id);
+ }
+ else {gen1("zzmatch(%d);", p->token);}
+ }
+
+ a = findImmedAction( p->next );
+ /* generate the token labels */
+ if ( GenCC && p->elnum>0 )
+ {
+ /* If building trees in C++, always gen the LT() assigns */
+ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST )
+ {
+/* MR10 */ if ( FoundGuessBlk ) {
+/* MR10 */ gen("\n");
+/* MR10 */ if (p->label_used_in_semantic_pred) {
+/* MR10 */ gen2(" _t%d%d = (ANTLRTokenPtr)LT(1); /* MR10 */\n", BlkLevel-1, p->elnum);
+/* MR10 */ } else {
+/* MR10 */ gen("if ( !guessing ) {\n"); tab();
+/* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);\n", BlkLevel-1, p->elnum);
+/* MR10 */ gen("}\n");
+/* MR10 */ };
+/* MR10 */ } else {
+/* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);", BlkLevel-1, p->elnum);
+/* MR10 */ };
+/* MR10 */
+ }
+
+/*
+ * MR23 labase is never used in the C++ runtime library.
+ * and this code is generated only in C++ mode
+ */
+
+/*** if ( LL_k>1 ) / * MR23 disabled */
+/*** if ( !DemandLookahead ) _gen(" labase++;"); / * MR23 disabled */
+/*** _gen("\n"); / * MR23 disabled */
+/*** tab(); / * MR23 disabled */
+ }
+ if ( GenAST )
+ {
+ if ( FoundGuessBlk &&
+ (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) )
+ {
+ if ( GenCC ) {_gen("if ( !guessing ) {\n"); tab();}
+ else {_gen("zzNON_GUESS_MODE {\n"); tab();}
+ }
+
+/* MR27 addition when labels referenced when operator ! used */
+
+ pushedCmodeAST = 0; /* MR27 */
+ if (ast_label_in_action && (p->astnode == ASTexclude || r->noAST)) {
+ _gen("\n");
+ if (GenCC) {
+/* MR13 */ if (NewAST) {
+/* MR13 */ gen4("_ast%d%d = newAST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);
+/* MR13 */ } else {
+/* MR13 */ gen4("_ast%d%d = new AST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);
+/* MR13 */ }
+ }
+ else {
+ pushedCmodeAST = 1;
+ gen("zzastPush(zzmk_ast(zzastnew(),zzaCur)); /* MR27 */");
+ }
+ }
+
+/* end MR27 addition for labels referenced when operator ! used */
+
+ if (!r->noAST )
+ {
+ if (GenCC && !(p->astnode == ASTexclude) ) {
+ _gen("\n");
+/* MR13 */ if (NewAST) {
+/* MR13 */ gen4("_ast%d%d = newAST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);
+/* MR13 */ } else {
+/* MR13 */ gen4("_ast%d%d = new AST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum);
+/* MR13 */ }
+ tab();
+ }
+ if ( GenCC && !(p->astnode == ASTexclude) )
+ {_gen2("_ast%d%d->", BlkLevel-1, p->elnum);}
+ else _gen(" ");
+ if ( p->astnode==ASTchild ) {
+ if ( !GenCC ) _gen("zz");
+ _gen("subchild(_root, &_sibling, &_tail);");
+ }
+ else if ( p->astnode==ASTroot ) {
+ if ( !GenCC ) _gen("zz");
+ _gen("subroot(_root, &_sibling, &_tail);");
+ }
+ if ( GenCC && !(p->astnode == ASTexclude) ) {
+ _gen("\n");
+ tab();
+ }
+ }
+ else if ( !GenCC ) {
+ if (! pushedCmodeAST) _gen(" zzastDPush;");
+ }
+ if ( FoundGuessBlk &&
+ (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) )
+ {gen("}\n"); tab();}
+ }
+
+ /* Handle element labels now */
+ if ( p->el_label!=NULL )
+ {
+ int done_NON_GUESSMODE=0;
+
+ _gen("\n");
+
+/* MR10 */ /* do Attrib / Token ptr for token label used in semantic pred */
+/* MR10 */ /* for these cases do assign even in guess mode */
+/* MR10 */
+/* MR10 */ if (p->label_used_in_semantic_pred) {
+/* MR10 */ if ( GenCC ) {
+/* MR10 */ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {
+/* MR10 */ gen3("%s = _t%d%d;", p->el_label, BlkLevel-1, p->elnum);
+/* MR10 */ } else {
+/* MR10 */ gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label);
+/* MR10 */ };
+/* MR10 */ } else {
+/* MR10 */ gen1("%s = zzaCur;", p->el_label);
+/* MR10 */ };
+/* MR10 */ if (FoundGuessBlk) _gen(" /* MR10 */");
+/* MR10 */ _gen("\n");
+/* MR10 */ };
+
+ /* Do Attrib / Token ptr */
+
+/* MR10 */ if (! p->label_used_in_semantic_pred) {
+/* MR10 */
+/* MR10 */ if ( FoundGuessBlk ) {
+/* MR10 */ if (! done_NON_GUESSMODE) {
+/* MR10 */ done_NON_GUESSMODE=1;
+/* MR10 */ if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();}
+/* MR10 */ else {gen("zzNON_GUESS_MODE {\n"); tab();}
+/* MR10 */ };
+/* MR10 */ };
+/* MR10 */
+/* MR10 */ if ( GenCC ) {
+/* MR10 */ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) {
+/* MR10 */ gen3("%s = _t%d%d;\n", p->el_label, BlkLevel-1, p->elnum);
+/* MR10 */ } else {
+/* MR10 */ gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label);
+/* MR10 */ };
+/* MR10 */ } else {
+/* MR10 */ gen1("%s = zzaCur;\n", p->el_label);
+/* MR10 */ };
+/* MR10 */ };
+
+ /* Do AST ptr */
+
+ if (GenAST && (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST) )) /* MR27 */
+ {
+
+/* MR10 */ if ( FoundGuessBlk ) {
+/* MR10 */ if (! done_NON_GUESSMODE) {
+/* MR10 */ done_NON_GUESSMODE=1;
+/* MR10 */ if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();}
+/* MR10 */ else {gen("zzNON_GUESS_MODE {\n"); tab();}
+/* MR10 */ };
+/* MR10 */ };
+
+ if ( GenCC ) {
+ gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum);
+ }
+ else {gen1("%s_ast = zzastCur;\n", p->el_label);}
+ }
+
+/* MR10 */ if (done_NON_GUESSMODE) {
+/* MR10 */ gen("}\n"); tab();
+/* MR10 */ };
+
+ }
+
+ /* Handle any actions immediately following action */
+ if ( a != NULL ) /* MR10 */ /* MR11 */
+ {
+ /* delay next token fetch until after action */
+ _gen("\n");
+ if ( a->is_predicate)
+ {
+#if 0
+/* Disabled in MR30 ************************************************************
+ And moved into genAction
+ *****************************************************************************
+*/
+
+ gen("if (!(");
+
+ /* make sure that '#line n' is on front of line */ /* MR14 */
+ if ( GenLineInfo && p->file != -1 ) _gen("\n"); /* MR14 */
+ dumpPredAction(a,a->action, output, 0, a->file, a->line, 0);
+
+/* MR23 Change failed predicate macro to have three arguments:
+
+ macro arg 1: The stringized predicate itself
+ macro arg 2: 0 => no user-defined error action
+ 1 => user-defined error action
+ macro arg 3: The user-defined error action
+
+ This gives the user more control of the error action.
+*/
+ _gen(")) \n");
+ tabs++;
+ gen3(" {zzfailed_pred(\"%s\",%s,{ %s } );}\n", /* MR23 */
+ stringize(a->action), /* MR23 */
+ (a->pred_fail == NULL ? /* MR23/MR27 */
+ "0 /* report */" : "1 /* user action */"), /* MR23/MR27 */
+ (a->pred_fail == NULL ? /* MR23 */
+ "; /* no user action */" : a->pred_fail)); /* MR23 */
+ tabs--;
+/* Disabled in MR30 ************************************************************
+ And moved into genAction
+ *****************************************************************************
+*/
+#endif
+ }
+ else /* MR9 a regular action - not a predicate action */
+ {
+
+/* MR23: Search an action which is not a predicate for LT(i),
+ LA(i), or LATEXT(i) in order to warn novice users that
+ it refers to the previous matched token, not the next
+ one. This is different than the case for semantic
+ predicates.
+*/
+
+/* MR23 */ if (GenCC) {
+/* MR23 */ if (strstr(a->action, "LT(") != NULL) LTinTokenAction = 1;
+/* MR23 */ }
+/* MR23 */ else {
+/* MR23 */ if (strstr(a->action, "LA(") != NULL) LTinTokenAction = 1;
+/* MR23 */ if (strstr(a->action, "LATEXT(") != NULL) LTinTokenAction = 1;
+/* MR23 */ }
+
+ if ( FoundGuessBlk ) {
+ if ( GenCC ) {gen("if ( !guessing ) {\n");}
+ else gen("zzNON_GUESS_MODE {\n");
+ }
+ dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); /* MR21 */
+ if ( FoundGuessBlk ) gen("}\n");
+ a->done = 1; /* MR30 */
+ }
+/*** a->done = 1; MR30 Moved up into then branch for true actions, but not predicates ***/
+ if ( !DemandLookahead ) {
+ if ( GenCC ) {
+ if ( FoundException && p->use_def_MT_handler ) gen("if (!_signal)");
+ _gen(" consume();")
+ if ( FoundException && p->use_def_MT_handler )
+ _gen(" _signal=NoSignal;");
+ _gen("\n");
+ }
+ else
+ {
+ if ( FoundException && p->use_def_MT_handler ) _gen("if (!_signal)");
+ _gen(" zzCONSUME;\n");
+ if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");
+ _gen("\n");
+ }
+ }
+ else gen("\n");
+ if (a->done) { /* MR30 */
+ TRANS( a->next ); /* MR30 */
+ } /* MR30 */
+ else { /* MR30 */
+ TRANS( p->next ); /* MR30 */
+ } /* MR30 */
+ }
+ else
+ {
+ if ( !DemandLookahead ) {
+ if ( GenCC ) {
+ if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");
+ _gen(" consume();")
+ if (FoundException&&p->use_def_MT_handler) _gen(" _signal=NoSignal;");
+ _gen("\n");
+ }
+ else {
+ if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)");
+ _gen(" zzCONSUME;");
+ if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;");
+ _gen("\n");
+ }
+ }
+ else _gen("\n");
+ TRANS(p->next);
+ }
+}
+
+/* MR21
+ *
+ * There was a bug in the code generation for {...} which causes it
+ * to omit the optional tokens from the error messages. The easiest
+ * way to fix this was to make the opt block look like a sub block:
+ *
+ * { a | b | c }
+ *
+ * becomes (internally):
+ *
+ * ( a | b | c | )
+ *
+ * The code for genOptBlk is now identical to genSubBlk except for
+ * cosmetic changes.
+ */
+
+void
+#ifdef __USE_PROTOS
+genOptBlk( Junction *q )
+#else
+genOptBlk( q )
+Junction *q;
+#endif
+{
+ int max_k;
+ set f;
+ int need_right_curly;
+ set savetkref;
+ int lastAltEmpty; /* MR23 */
+ savetkref = tokensRefdInBlock;
+ require(q->ntype == nJunction, "genOptBlk: not junction");
+ require(q->jtype == aOptBlk, "genOptBlk: not opt block");
+
+ OutLineInfo(output,q->line,FileStr[q->file]);
+ BLOCK_Preamble(q);
+ BlkLevel++;
+ BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */
+ f = genBlk(q, aOptBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+/* MR23
+ Bypass error clause generation when exceptions are used in {...} block
+ See multi-line note in genBlk near call to isEmptyAlt.
+*/
+ if (! FoundException) {
+ if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}
+ }
+ else {
+ gen("/* MR23 skip error clause for {...} when exceptions in use */\n");
+ }
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ freeBlkFsets(q);
+ --BlkLevel;
+ BLOCK_Tail();
+
+ if ( q->guess )
+ {
+ gen("zzGUESS_DONE\n");
+ }
+
+ /* must duplicate if (alpha)?; one guesses (validates), the
+ * second pass matches */
+ if ( q->guess && analysis_point(q)==q )
+ {
+ OutLineInfo(output,q->line,FileStr[q->file]);
+ BLOCK_Preamble(q);
+ BlkLevel++;
+ f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+ if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ freeBlkFsets(q);
+ --BlkLevel;
+ BLOCK_Tail();
+ }
+
+ tokensRefdInBlock = savetkref;
+ if (q->end->p1 != NULL) TRANS(q->end->p1);
+}
+
+/*
+ * Generate code for a loop blk of form:
+ *
+ * |---|
+ * v |
+ * --o-G-o-->o--
+ */
+void
+#ifdef __USE_PROTOS
+genLoopBlk( Junction *begin, Junction *q, Junction *start, int max_k )
+#else
+genLoopBlk( begin, q, start, max_k )
+Junction *begin;
+Junction *q;
+Junction *start; /* where to start generating code from */
+int max_k;
+#endif
+{
+ set f;
+ int need_right_curly;
+ set savetkref;
+ Junction *guessBlock; /* MR10 */
+ int singleAlt; /* MR10 */
+ int lastAltEmpty; /* MR23 */
+
+ savetkref = tokensRefdInBlock;
+ require(q->ntype == nJunction, "genLoopBlk: not junction");
+ require(q->jtype == aLoopBlk, "genLoopBlk: not loop block");
+
+ if ( q->visited ) return;
+ q->visited = TRUE;
+
+ /* first_item_is_guess_block doesn't care what kind of node it is */
+
+ guessBlock=first_item_is_guess_block( (Junction *) q->p1); /* MR10 */
+ singleAlt=q->p2==NULL; /* MR10 */
+
+ if (singleAlt && !guessBlock) /* MR10 */ /* only one alternative? */
+ {
+ if ( DemandLookahead ) {
+ if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}
+ else gen1("look(%d);\n", max_k);
+ }
+ gen("while ( ");
+ if ( begin!=NULL ) genExpr(begin);
+ else genExpr(q);
+ /* if no predicates have been hoisted for this single alt (..)*
+ * do so now
+ */
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ if ( ParseWithPredicates && begin->predicate==NULL )
+ {
+ Predicate *a = MR_find_predicates_and_supp((Node *)q->p1);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+
+ if ( a!=NULL )
+ {
+ _gen("&&");
+ a=genPredTreeMain(a, (Node *)q); /* MR10 */
+ }
+/* MR10 */ if (MRhoisting) {
+/* MR10 */ predicate_free(a);
+/* MR10 */ };
+ }
+ _gen(" ) {\n");
+ tabs++;
+ TRANS(q->p1);
+ if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);
+ if ( DemandLookahead ) {
+ if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}
+ else gen1("look(%d);\n", max_k);
+ }
+ --tabs;
+ gen("}\n");
+ freeBlkFsets(q);
+ q->visited = FALSE;
+ tokensRefdInBlock = savetkref;
+ return;
+ }
+ gen("for (;;) {\n"); /* MR20 G. Hobbelt */
+ tabs++;
+/* MR6 */
+/* MR6 "begin" can never be null when called from genLoopBegin */
+/* MR6 because q==(Junction *)begin->p1 and we know q is valid */
+/* MR6 */
+/* MR6 from genLoopBegin: */
+/* MR6 */
+/* MR6 if ( LL_k>1 && !set_nil(q->fset[2]) ) */
+/* MR6 genLoopBlk( q, (Junction *)q->p1, q, max_k ); */
+/* MR6 else genLoopBlk( q, (Junction *)q->p1, NULL, max_k ); */
+/* MR6 */
+ if ( begin!=NULL )
+ {
+ if ( DemandLookahead )
+ {
+ if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}
+ else gen1("look(%d);\n", max_k);
+ }
+ /* The bypass arc of the (...)* predicts what to do when you fail, but
+ * ONLY after having tested the loop start expression. To avoid this,
+ * we simply break out of the (...)* loop when we find something that
+ * is not in the prediction of the loop (all alts thereof).
+ */
+ gen("if ( !(");
+
+/*** TJP says: It used to use the prediction expression for the bypass arc
+ of the (...)*. HOWEVER, if a non LL^1(k) decision was found, this
+ thing would miss the ftree stored in the aLoopBegin node and generate
+ an LL^1(k) decision anyway.
+
+ *** genExpr((Junction *)begin->p2);
+ ***/
+
+ genExpr((Junction *)begin);
+ _gen(")) break;\n");
+
+ }
+
+ /* generate code for terminating loop (this is optional branch) */
+
+ f = genBlk(q, aLoopBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+ set_free(f);
+ freeBlkFsets(q);
+
+ /* generate code for terminating loop (this is optional branch) */
+
+/* MR6 */
+/* MR6 30-May-97 Bug reported by Manuel Ornato */
+/* MR6 A definite bug involving the exit from a loop block */
+/* MR6 In 1.23 and later versions (including 1.33) Instead */
+/* MR6 exiting the block and reporting a syntax error the */
+/* MR6 code loops forever. */
+/* MR6 Looking at 1.20 which generates proper code it is not */
+/* MR6 clear which of two changes should be undone. */
+/* MR6 This is my best guess. */
+/* MR6 From earlier MR6 note we know that begin can never be */
+/* MR6 null when genLoopBlk called from genLoopBegin */
+/* MR6 */
+/* MR6 */ if ( begin==NULL) {
+/* MR6 */ /* code for exiting loop "for sure" */
+/* MR6 */ gen("/* Suppressed by MR6 */ /*** else break; ***/\n");
+/* MR6 */ };
+
+/* MR10 */if (singleAlt && guessBlock) {
+/* MR10 */ tabs--;
+/* MR6 */ gen("} else break; /* MR6 code for exiting loop \"for sure\" */\n");
+/* MR10 */ need_right_curly--;
+/* MR10 */ } else {
+/* MR6 */ gen("else break; /* MR6 code for exiting loop \"for sure\" */\n");
+/* MR10 */ };
+
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);
+ --tabs;
+ gen("}\n");
+ q->visited = FALSE;
+ tokensRefdInBlock = savetkref;
+}
+
+/*
+ * Generate code for a loop blk of form:
+ *
+ * |---|
+ * v |
+ * --o-->o-->o-G-o-->o--
+ * | ^
+ * v |
+ * o-----------o
+ *
+ * q->end points to the last node (far right) in the blk.
+ *
+ * Note that q->end->jtype must be 'EndBlk'.
+ *
+ * Generate code roughly of the following form:
+ *
+ * do {
+ * ... code for alternatives ...
+ * } while ( First Set of aLoopBlk );
+ *
+ * OR if > 1 alternative
+ *
+ * do {
+ * ... code for alternatives ...
+ * else break;
+ * } while ( 1 );
+ */
+void
+#ifdef __USE_PROTOS
+genLoopBegin( Junction *q )
+#else
+genLoopBegin( q )
+Junction *q;
+#endif
+{
+ set f;
+ int i;
+ int max_k;
+ set savetkref;
+ savetkref = tokensRefdInBlock;
+ require(q!=NULL, "genLoopBegin: invalid node and/or rule");
+ require(q->ntype == nJunction, "genLoopBegin: not junction");
+ require(q->jtype == aLoopBegin, "genLoopBegin: not loop block");
+ require(q->p2!=NULL, "genLoopBegin: invalid Loop Graph");
+
+ OutLineInfo(output,q->line,FileStr[q->file]);
+
+ BLOCK_Preamble(q);
+ BlkLevel++;
+ BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */
+ f = First(q, 1, aLoopBegin, &max_k);
+ /* If not simple LL(1), must specify to start at LoopBegin, not LoopBlk */
+ if ( LL_k>1 && !set_nil(q->fset[2]) )
+ genLoopBlk( q, (Junction *)q->p1, q, max_k );
+ else genLoopBlk( q, (Junction *)q->p1, NULL, max_k );
+
+ for (i=1; i<=CLL_k; i++) set_free(q->fset[i]);
+ for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]);
+ --BlkLevel;
+ BLOCK_Tail();
+ set_free(f);
+ tokensRefdInBlock = savetkref;
+/* MR21 */ if (MR_BlkErr) {
+/* MR21 */ set f, fArray[2];
+/* MR21 */ f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ );
+/* MR21 */ fArray[0]= empty;
+/* MR21 */ fArray[1]= set_dup(f);
+/* MR21 */ gen("if (");
+/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */
+/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n");
+/* MR21 */ tabs++;
+/* MR21 */ tab();
+/* MR21 */ _gen("/* nothing */ }\n");
+/* MR21 */ tab();
+/* MR21 */ makeErrorClause(q,f,1,0 /* use plus block bypass ? */ ); /* frees set */
+/* MR21 */ tabs--;
+/* MR21 */ };
+ if (q->end->p1 != NULL) TRANS(q->end->p1);
+}
+
+/*
+ * Generate code for a loop blk of form:
+ *
+ * |---|
+ * v |
+ * --o-G-o-->o--
+ *
+ * q->end points to the last node (far right) in the blk.
+ * Note that q->end->jtype must be 'EndBlk'.
+ *
+ * Generate code roughly of the following form:
+ *
+ * do {
+ * ... code for alternatives ...
+ * } while ( First Set of aPlusBlk );
+ *
+ * OR if > 1 alternative
+ *
+ * do {
+ * ... code for alternatives ...
+ * else if not 1st time through, break;
+ * } while ( 1 );
+ */
+void
+#ifdef __USE_PROTOS
+genPlusBlk( Junction *q )
+#else
+genPlusBlk( q )
+Junction *q;
+#endif
+{
+ int max_k;
+ set f;
+ int need_right_curly;
+ int lastAltEmpty; /* MR23 */
+ set savetkref;
+ Junction *guessBlock; /* MR10 */
+ int singleAlt; /* MR10 */
+
+ savetkref = tokensRefdInBlock;
+ require(q!=NULL, "genPlusBlk: invalid node and/or rule");
+ require(q->ntype == nJunction, "genPlusBlk: not junction");
+ require(q->jtype == aPlusBlk, "genPlusBlk: not Plus block");
+ require(q->p2 != NULL, "genPlusBlk: not a valid Plus block");
+
+ if ( q->visited ) return;
+ q->visited = TRUE;
+ OutLineInfo(output,q->line,FileStr[q->file]);
+ BLOCK_Preamble(q);
+ BlkLevel++;
+
+ BlockPreambleOption((Junction *)q, q->pFirstSetSymbol); /* MR21 */
+
+ /* first_item_is_guess_block doesn't care what kind of node it is */
+
+ guessBlock=first_item_is_guess_block( (Junction *)q->p1); /* MR10 */
+
+ /* if the ignore flag is set on the 2nd alt and that alt is empty,
+ * then it is the implied optional alternative that we added for (...)+
+ * and, hence, only 1 alt.
+ */
+
+/* MR10 Reported by Pulkkinen Esa (esap@cs.tut.fi)
+ * Outer code for guess blocks ignored when there is only one alt
+ * for a (...)+ block.
+ * Force use of regular code rather than "optimized" code for that case
+ */
+
+ singleAlt=( ( (Junction *) q->p2)->p2 == NULL) &&
+ ( ( (Junction *) q->p2)->ignore ); /* only one alternative? */
+
+ if (singleAlt && !guessBlock) /* MR10 */
+ {
+
+ Predicate *a=NULL;
+ /* if the only alt has a semantic predicate, hoist it; must test before
+ * entering loop.
+ */
+ if ( ParseWithPredicates )
+ {
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+ a = MR_find_predicates_and_supp((Node *)q);
+ require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
+
+ if ( a!=NULL ) {
+ gen("if (");
+ a=genPredTreeMain(a, (Node *)q); /* MR10 */
+ _gen(") {\n");
+ }
+ }
+ gen("do {\n");
+ tabs++;
+ TRANS(q->p1);
+ if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1);
+ f = First(q, 1, aPlusBlk, &max_k);
+ if ( DemandLookahead ) {
+ if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}
+ else gen1("look(%d);\n", max_k);
+ }
+ --tabs;
+ gen("} while ( ");
+ if ( q->parm!=NULL && q->predparm ) _gen1("(%s) && ", q->parm);
+ genExpr(q);
+ if ( ParseWithPredicates && a!=NULL )
+ {
+ if (! MR_comparePredicates(q->predicate,a)) {
+ _gen("&&");
+ a=genPredTreeMain(a, (Node *)q); /* MR10 */
+ };
+ }
+ _gen(" );\n");
+ if ( ParseWithPredicates && a!=NULL ) gen("}\n");
+ --BlkLevel;
+ BLOCK_Tail();
+ q->visited = FALSE;
+ freeBlkFsets(q);
+ set_free(f);
+ tokensRefdInBlock = savetkref;
+/* MR21 */ if (MR_BlkErr) {
+/* MR21 */ set f, fArray[2];
+/* MR21 */ f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ );
+/* MR21 */ fArray[0]= empty;
+/* MR21 */ fArray[1]= set_dup(f);
+/* MR21 */ gen("if (");
+/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */
+/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n");
+/* MR21 */ tabs++;
+/* MR21 */ tab();
+/* MR21 */ _gen("/* nothing */ }\n");
+/* MR21 */ tab();
+/* MR21 */ makeErrorClause(q,f,1,1 /* use plus block bypass ? */ ); /* frees set */
+/* MR21 */ tabs--;
+/* MR21 */ };
+ if (q->end->p1 != NULL) TRANS(q->end->p1);
+/* MR10 */ if (MRhoisting) {
+/* MR10 */ predicate_free(a);
+/* MR10 */ };
+ return;
+ }
+ gen("do {\n");
+ tabs++;
+ f = genBlk(q, aPlusBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+/* MR6 */
+/* MR6 Sinan Karasu (sinan@tardis.ds.boeing.com) */
+/* MR6 Failed to turn off guess mode when leaving block */
+/* MR6 */
+/* MR6 */ if ( has_guess_block_as_last_item(q) ) {
+/* MR10 */ gen("/* MR10 ()+ */ else {\n");
+/* MR10 */ tabs++;
+/* MR10 */ need_right_curly++;
+/* MR10 */ gen("/* MR10 ()+ */ if ( !zzrv ) zzGUESS_DONE;\n");
+/* MR6 */ gen("/* MR10 ()+ */ if ( zzcnt > 1 ) break;\n");
+/* MR10 */ } else {
+/* MR10 */ gen("/* MR10 ()+ */ else {\n");
+/* MR10 */ tabs++;
+/* MR10 */ need_right_curly++;
+/* MR10 */ gen("if ( zzcnt > 1 ) break;\n");
+/* MR10 */ };
+
+/* MR21 */ if (MR_BlkErr && 1 >= max_k) {
+/* MR21 */ set f;
+/* MR21 */ f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ );
+/* MR21 */ tabs++;
+/* MR21 */ tab();
+/* MR21 */ makeErrorClause(q,f,1,0 /* use plus block bypass ? */ ); /* frees set */
+/* MR21 */ tabs--;
+/* MR21 */ }
+/* MR21 */ else {
+ tab();
+ makeErrorClause(q,f,max_k,1 /* use plus block bypass ? */);
+ /* MR21 I think this generates the wrong set ? */
+ /* MR21 because it includes the plus block bypass ? */
+ /* MR21 but I'm afraid to change it without additional checking */
+ }
+
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ freeBlkFsets(q);
+ gen("zzcnt++;");
+ if ( !GenCC ) _gen1(" zzLOOP(zztasp%d);", BlkLevel-1);
+ _gen("\n");
+ if ( DemandLookahead ) {
+ if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);}
+ else gen1("look(%d);\n", max_k);
+ }
+ --tabs;
+ if ( q->parm!=NULL && q->predparm ) {gen1("} while (%s);\n", q->parm);}
+ else gen("} while ( 1 );\n");
+ --BlkLevel;
+ BLOCK_Tail();
+ q->visited = FALSE;
+ tokensRefdInBlock = savetkref;
+/* MR21 */ if (MR_BlkErr) {
+/* MR21 */ set f, fArray[2];
+/* MR21 */ f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ );
+/* MR21 */ fArray[0]= empty;
+/* MR21 */ fArray[1]= set_dup(f);
+/* MR21 */ gen("if (");
+/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */
+/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n");
+/* MR21 */ tabs++;
+/* MR21 */ tab();
+/* MR21 */ _gen("/* nothing */ }\n");
+/* MR21 */ tab();
+/* MR21 */ makeErrorClause(q,f,1,1 /* use plus block bypass ? */ ); /* frees set */
+/* MR21 */ tabs--;
+/* MR21 */ };
+ if (q->end->p1 != NULL) TRANS(q->end->p1);
+}
+
+/*
+ * Generate code for a sub blk of alternatives of form:
+ *
+ * --o-G1--o--
+ * | ^
+ * v /|
+ * o-G2-o|
+ * | ^
+ * v |
+ * ..........
+ * | ^
+ * v /
+ * o-Gn-o
+ *
+ * q points to the 1st junction of blk (upper-left).
+ * q->end points to the last node (far right) in the blk.
+ * Note that q->end->jtype must be 'EndBlk'.
+ * The last node in every alt points to q->end.
+ *
+ * Generate code of the following form:
+ * if ( First(G1) ) {
+ * ...code for G1...
+ * }
+ * else if ( First(G2) ) {
+ * ...code for G2...
+ * }
+ * ...
+ * else {
+ * ...code for Gn...
+ * }
+ */
+
+void
+#ifdef __USE_PROTOS
+genSubBlk( Junction *q )
+#else
+genSubBlk( q )
+Junction *q;
+#endif
+{
+ int max_k;
+ set f;
+ int need_right_curly;
+ int lastAltEmpty; /* MR23 */
+ set savetkref;
+ savetkref = tokensRefdInBlock;
+ require(q->ntype == nJunction, "genSubBlk: not junction");
+ require(q->jtype == aSubBlk, "genSubBlk: not subblock");
+
+ OutLineInfo(output,q->line,FileStr[q->file]);
+ BLOCK_Preamble(q);
+ BlkLevel++;
+ BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */
+ f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+
+/* MR23
+ Bypass error clause generation when exceptions are used in a sub block
+ in which the last alternative is epsilon. Example: "(A | B | )".
+ See multi-line note in genBlk near call to isEmptyAlt.
+*/
+ if (FoundException && lastAltEmpty) {
+ gen("/* MR23 skip error clause for (...| epsilon) when exceptions in use */\n");
+ }
+ else {
+ if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );}
+ }
+
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ freeBlkFsets(q);
+ --BlkLevel;
+ BLOCK_Tail();
+
+ if ( q->guess )
+ {
+ gen("zzGUESS_DONE\n");
+ }
+
+ /* must duplicate if (alpha)?; one guesses (validates), the
+ * second pass matches */
+ if ( q->guess && analysis_point(q)==q )
+ {
+ OutLineInfo(output,q->line,FileStr[q->file]);
+ BLOCK_Preamble(q);
+ BlkLevel++;
+ f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+ if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */);}
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ freeBlkFsets(q);
+ --BlkLevel;
+ BLOCK_Tail();
+ }
+
+ tokensRefdInBlock = savetkref;
+ if (q->end->p1 != NULL) TRANS(q->end->p1);
+}
+
+static int TnodesAllocatedPrevRule=0;
+
+/*
+ * Generate code for a rule.
+ *
+ * rule--> o-->o-Alternatives-o-->o
+ * Or,
+ * rule--> o-->o-Alternative-o-->o
+ *
+ * The 1st junction is a RuleBlk. The second can be a SubBlk or just a junction
+ * (one alternative--no block), the last is EndRule.
+ * The second to last is EndBlk if more than one alternative exists in the rule.
+ *
+ * To get to the init-action for a rule, we must bypass the RuleBlk,
+ * and possible SubBlk.
+ * Mark any init-action as generated so genBlk() does not regenerate it.
+ */
+void
+#ifdef __USE_PROTOS
+genRule( Junction *q )
+#else
+genRule( q )
+Junction *q;
+#endif
+{
+
+ const char * returnValueInitializer;
+
+do { /* MR10 Change recursion into iteration */
+
+ int max_k;
+ set follow, rk, f;
+ ActionNode *a;
+ RuleEntry *r;
+ int lastAltEmpty; /* MR23 */
+ static int file = -1;
+ int need_right_curly;
+ require(q->ntype == nJunction, "genRule: not junction");
+ require(q->jtype == RuleBlk, "genRule: not rule");
+
+/* MR14 */ require (MR_BackTraceStack.count == 0,"-alpha MR_BackTraceStack.count != 0");
+/* MR14 */ MR_pointerStackReset(&MR_BackTraceStack);
+/* MR14 */ if (AlphaBetaTrace) MR_MaintainBackTrace=1;
+
+ CurRule=q->rname; /* MR11 */
+
+ r = (RuleEntry *) hash_get(Rname, q->rname);
+ if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief");
+ if ( q->file != file ) /* open new output file if need to */
+ {
+/* MR6 */
+/* MR6 Simpler to debug when output goes to stdout rather than a file */
+/* MR6 */
+/* MR6 */ if (UseStdout) {
+/* MR6 */ output = stdout;
+/* MR6 */ } else {
+/* MR6 */ if ( output != NULL) fclose( output );
+/* MR6 */ output = fopen(OutMetaName(outname(FileStr[q->file])), "w");
+/* MR6 */ };
+ require(output != NULL, "genRule: can't open output file");
+
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(outname(FileStr[q->file]))); /* MR1 */
+#endif
+ if ( file == -1 ) genHdr1(q->file);
+ else genHdr(q->file);
+ file = q->file;
+ }
+
+ if (InfoM) {
+ fprintf(stderr," rule %s\n",q->rname);
+ fflush(output);
+ };
+
+#if 0
+ if (strcmp(q->rname,"***debug***") == 0) {
+ fprintf(stderr,"***debug*** %s reached\n",q->rname);
+ MR_break();
+ };
+#endif
+
+ DumpFuncHeader(q,r);
+ tabs++;
+
+ /* MR23
+
+ If there is a single return value then it can be initialized in
+ the declaration using assignment syntax. If there are multiple
+ return values then antlr creates a struct and initialization takes
+ place element by element for each element of the struct. For
+ multiple elements the initialization is by assignment so we have
+ to wait until all declarations are done before emitting that code -
+ because of restrictions in C which don't exist in C++.
+
+ In the past (before MR23) the only kind of initialization was
+ the PURIFY macro which was just a memset() of 0. Now we allow
+ the user to specify an initial value. PURIFY is still used in C
+ mode because C does not have constructors. However, PURIFY is
+ not used in C++ mode because it might overwrite information created
+ by elements which have their own ctor.
+
+ */
+
+ if ( q->ret!=NULL )
+ {
+ if ( hasMultipleOperands(q->ret) ) /* MR23 */
+ {
+
+ /* Emit initialization code later. */
+
+ gen1("struct _rv%d _retv;\n",r->rulenum);
+ }
+ else
+ {
+ /* Emit initialization code now. */
+
+ tab();
+ DumpType(q->ret, output);
+ returnValueInitializer = getInitializer(q->ret);
+ if (returnValueInitializer == NULL) { /* MR23 */
+ gen(" _retv;\n"); /* MR1 MR3 */
+ } /* MR23 */
+ else { /* MR23 */
+ gen1(" _retv = %s;\n", returnValueInitializer); /* MR23 */
+ } /* MR23 */
+ }
+ }
+
+ OutLineInfo(output,q->line,FileStr[q->file]);
+
+ if (InfoM) {
+ fflush(output);
+ };
+
+ gen("zzRULE;\n");
+ if ( FoundException )
+ {
+ gen("int _sva=1;\n");
+ }
+ if ( GenCC && GenAST )
+ gen("ASTBase *_ast = NULL, *_sibling = NULL, *_tail = NULL;\n");
+ if ( GenCC ) genTokenPointers(q);
+ if ( GenCC&&GenAST ) genASTPointers(q);
+ if ( q->el_labels!=NULL ) genElementLabels(q->el_labels);
+ if ( FoundException ) gen("int _signal=NoSignal;\n");
+
+ if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel);
+
+/* MR10 */ /* move zzTRACEIN to before init action */
+
+/* MR10 */ if ( TraceGen ) {
+/* MR10 */ if ( GenCC ) {gen1("zzTRACEIN(\"%s\");\n", q->rname);}
+/* MR10 */ else gen1("zzTRACEIN((ANTLRChar *)\"%s\");\n", q->rname);
+/* MR10 */ }
+
+/* MR7 Moved PURIFY() to after all local variables have been declared */
+/* MR7 so that the generated code is valid C as well as C++ */
+/* MR7 Jan Mikkelsen 10-June-1997 */
+
+
+ /*
+ MR23 Do the PURIFY macro only for C mode.
+ C++ users should use constructors or initialization expressions.
+ */
+
+ if ( q->ret != NULL ) /* MR7 */
+ { /* MR7 */
+ if (hasMultipleOperands(q->ret)) { /* MR23 */
+ if (PURIFY == TRUE) {
+ gen1("PCCTS_PURIFY(_retv,sizeof(struct _rv%d))\n",r->rulenum); /* MR23 */
+ }
+ } /* MR7 */
+ else { /* MR7 */
+
+ /* MR23
+ If there were only one return value operand and
+ it had an initializer then it would have been
+ initialized in the declaration.
+ */
+
+ returnValueInitializer = getInitializer(q->ret); /* MR23 */
+ if (returnValueInitializer == NULL) { /* MR23 */
+ if (PURIFY == TRUE) {
+ gen("PCCTS_PURIFY(_retv,sizeof("); /* MR23 */
+ DumpType(q->ret, output); /* MR7 */
+ gen("))\n"); /* MR7 */
+ }
+ } /* MR23 */
+ } /* MR7 */
+
+ if (hasMultipleOperands(q->ret)) { /* MR23 */
+ DumpInitializers(output, r, q->ret); /* MR23 */
+ }
+
+ }
+ if ( !GenCC ) gen("zzMake0;\n");
+ if ( FoundException ) gen("*_retsignal = NoSignal;\n");
+
+ if ( !GenCC ) gen("{\n");
+
+ if ( has_guess_block_as_first_item((Junction *)q->p1) )
+ {
+ gen("zzGUESS_BLOCK\n");
+ }
+
+ /* L o o k F o r I n i t A c t i o n */
+ if ( ((Junction *)q->p1)->jtype == aSubBlk )
+ a = findImmedAction( ((Junction *)q->p1)->p1 );
+ else
+ a = findImmedAction( q->p1 ); /* only one alternative in rule */
+ if ( a!=NULL && !a->is_predicate)
+ {
+ /* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1);
+ a->done = 1; /* ignore action. We have already handled it */
+ }
+
+ BlkLevel++;
+ q->visited = TRUE; /* mark RULE as visited for FIRST/FOLLOW */
+ BlockPreambleOption((Junction *)q->p1, NULL); /* MR21 */
+ f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */);
+ if ( q->p1 != NULL )
+ if ( ((Junction *)q->p1)->p2 != NULL )
+ {tab(); makeErrorClause((Junction *)q->p1,f,max_k,0 /* use plus block bypass ? */);}
+ { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} }
+ freeBlkFsets((Junction *)q->p1);
+ q->visited = FALSE;
+ --BlkLevel;
+ if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel);
+
+ genTraceOut(q);
+
+ if ( q->ret!=NULL ) gen("return _retv;\n") else gen("return;\n");
+ /* E r r o r R e c o v e r y */
+ NewSet();
+ rk = empty;
+
+/* MR14 */ if (r->dontComputeErrorSet) {
+/* MR14 */ follow=empty;
+ } else {
+ MR_pointerStackReset(&MR_BackTraceStack); /* MR14 */
+ MR_ErrorSetComputationActive=1;
+ REACH(q->end, 1, &rk, follow);
+ MR_ErrorSetComputationActive=0;
+ require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");
+ }
+
+ FillSet( follow );
+ set_free( follow );
+
+ /* MR20 G. Hobbelt
+ Isn't it so that "fail:" is ONLY referenced when:
+
+ !FoundException || FoundGuessBlk ?
+
+ Therefore add the "if" around this piece of code generation...
+
+ Should guessing mode also use _handler label instead of "fail"
+ when exception handling is active? gen can automatically put
+ "if (guessing)" there so as to skip all kinds of user code.
+
+ */
+
+ if ( !FoundException || FoundGuessBlk ) /* MR20 G. Hobbelt */
+ { /* MR20 G. Hobbelt */
+ _gen("fail:\n");
+ if ( !GenCC ) gen("zzEXIT(zztasp1);\n");
+ if ( FoundGuessBlk ) {
+ if ( !GenCC ) {gen("if ( zzguessing ) zzGUESS_FAIL;\n");}
+ else gen("if ( guessing ) zzGUESS_FAIL;\n");
+ }
+ if ( q->erraction!=NULL )
+ dumpAction(q->erraction, output, tabs, q->file, q->line, 1);
+ if ( GenCC )
+ {
+ gen1("syn(zzBadTok, %s, zzMissSet, zzMissTok, zzErrk);\n",
+ r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup);
+ }
+ else
+ {
+ gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);\n",
+ r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup);
+ }
+ gen3("%sresynch(setwd%d, 0x%x);\n", GenCC?"":"zz", wordnum, 1<<setnum);
+
+ if ( q->ret!=NULL ) {
+ genTraceOut(q);
+ gen("return _retv;\n");
+ } else if ( q->exceptions!=NULL ) {
+ genTraceOut(q);
+ gen("return;\n");
+ } else if (!FoundException) { /* MR10 */
+ genTraceOut(q); /* MR10 */
+ };
+
+ } /* MR20 G. Hobbelt */
+
+ if ( !GenCC ) gen("}\n");
+
+ /* Gen code for exception handlers */
+ /* make sure each path out contains genTraceOut() */
+
+ if ( q->exceptions!=NULL )
+ {
+
+ gen("/* exception handlers */\n");
+
+ dumpExceptions(q->exceptions);
+
+ if ( !r->has_rule_exception )
+ {
+ _gen("_handler:\n");
+ gen("zzdflthandlers(_signal,_retsignal);\n");
+ }
+/* MR20 G. Gobbelt The label "adios" is never referenced */
+
+#if 0
+ _gen("_adios:\n");
+#endif
+ if ( q->ret!=NULL ) {
+ genTraceOut(q);
+ gen("return _retv;\n");
+ }
+ else {
+ genTraceOut(q);
+ gen("return;\n");
+ }
+ }
+ else if ( FoundException )
+ {
+ _gen("_handler:\n");
+ gen("zzdflthandlers(_signal,_retsignal);\n");
+
+/* MR1 */
+/* MR1 7-Apr-97 Fix suggested by: John Bair (jbair@iftime.com) */
+/* MR1 */
+
+ if ( q->ret != NULL) { /* MR1 */
+ genTraceOut(q); /* MR10 */
+ gen("return _retv;\n"); /* MR1 */
+ } else { /* MR1 */
+ genTraceOut(q); /* MR10 */
+ gen("return;\n") ; /* MR1 */
+ }; /* MR1 */
+ }
+
+ tabs--;
+ gen("}\n");
+
+/* MR10 Tired of looking at stacks that are as deep as the number of */
+/* MR10 rules. Changes recursion to iteration. */
+
+ MR_releaseResourcesUsedInRule( (Node *) q ); /* MR10 */
+
+ if (InfoT) {
+ fprintf(output,"\n/* tnodes created for rule %s: %d */\n",
+ q->rname, (TnodesAllocated-TnodesAllocatedPrevRule) );
+ };
+
+ TnodesAllocatedPrevRule=TnodesAllocated;
+
+ if (q->p2 == NULL) dumpAfterActions( output );
+ q=(Junction *)q->p2;
+ require(q==NULL || q->jtype==RuleBlk,"RuleBlk p2 does not point to another RuleBlk");
+
+} while (q != NULL);
+
+/**** The old code ****/
+/**** if ( q->p2 != NULL ) {TRANS(q->p2);} ****/ /* generate code for next rule too */
+/**** else dumpAfterActions( output ); ****/
+
+}
+
+
+/* This is for the function definition, not the declaration. */
+
+static void
+#ifdef __USE_PROTOS
+DumpFuncHeader( Junction *q, RuleEntry *r )
+#else
+DumpFuncHeader( q, r )
+Junction *q;
+RuleEntry *r;
+#endif
+{
+/* */
+/* MR1 10-Apr-97 MR1 Simplify insertion of commas in function header */
+/* */
+ int needComma; /* MR1 */
+
+
+ /* A N S I */
+ _gen("\n");
+ if ( q->ret!=NULL )
+ {
+ if ( hasMultipleOperands(q->ret) ) /* MR23 */
+ {
+ if (GenCC) gen2("%s::_rv%d\n", CurrentClassName, r->rulenum)
+ else gen1("struct _rv%d\n",r->rulenum);
+ }
+ else
+ {
+ DumpType(q->ret, output);
+ gen("\n");
+ }
+ }
+ else
+ {
+ _gen("void\n");
+ }
+/* MR1 */
+/* MR1 10-Apr-97 133MR1 Replace __STDC__ with __USE_PROTOS */
+/* MR1 */
+ if ( !GenCC ) _gen("#ifdef __USE_PROTOS\n"); /* MR1 */
+ if ( !GenCC ) gen2("%s%s(", RulePrefix, q->rname)
+ else gen3("%s::%s%s(", CurrentClassName, RulePrefix,q->rname);
+
+ /* If we generate C++ method names, we must hide default arguments */
+ /* which can appear in the parameter declaration list. */
+ /* NOTICE: this is done only here, for the method definition, but */
+ /* not for the method declaration inside the class */
+ /* definition. This is exactly the behaviour defined in */
+ /* C++ standard for default parameters. */
+
+ DumpANSIFunctionArgDef(output,q, 0 /* emit initializers ? */);
+ _gen("\n");
+
+ if ( GenCC ) {
+ gen("{\n");
+ return;
+ }
+
+ /* K & R */
+ gen("#else\n");
+ gen2("%s%s(", RulePrefix, q->rname);
+ needComma=0; /* MR1 */
+ if ( GenAST ) /* MR1 */
+ { /* MR1 */
+ _gen("_root"); /* MR1 */
+ needComma=1; /* MR1 */
+ } /* MR1 */
+ if ( FoundException ) /* MR1 */
+ { /* MR1 */
+ if (needComma) {_gen(",");needComma=0;}; /* MR1 */
+ _gen("_retsignal"); /* MR1 */
+ needComma=1; /* MR1 */
+ } /* MR1 */
+/* MR5 Change below by Jan Mikkelsen (janm@zeta.org.au) 26-May-97 MR5 */
+ DumpListOfParmNames( q->pdecl, output, needComma ); /* MR5 */
+ gen(")\n");
+ if ( GenAST ) gen("AST **_root;\n");
+ if ( FoundException ) gen("int *_retsignal;\n");
+ DumpOldStyleParms( q->pdecl, output );
+ gen("#endif\n");
+ gen("{\n");
+}
+
+void
+#ifdef __USE_PROTOS
+DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInitializer)
+#else
+DumpANSIFunctionArgDef(f,q,bInitializer)
+FILE *f;
+Junction *q;
+int bInitializer;
+#endif
+{
+ if ( GenAST )
+ {
+ if ( GenCC ) {fprintf(f,"ASTBase **_root");}
+ else fprintf(f,"AST**_root");
+ if ( !FoundException && q->pdecl!=NULL ) fprintf(f,",");
+ }
+ if ( FoundException )
+ {
+ if ( GenAST ) fprintf(f,",");
+ fprintf(f,"int *_retsignal");
+ if ( q->pdecl!=NULL ) {
+ fprintf(f,",");
+ }
+ }
+ if ( q->pdecl!=NULL ) {
+ DumpFormals(f, q->pdecl, bInitializer); /* MR23 */
+ }
+ else {
+ if ( !GenAST && !FoundException ) {
+ fprintf(f,"void");
+ }
+ }
+ fprintf(f,")");
+}
+
+void
+#ifdef __USE_PROTOS
+genJunction( Junction *q )
+#else
+genJunction( q )
+Junction *q;
+#endif
+{
+ require(q->ntype == nJunction, "genJunction: not junction");
+ require(q->jtype == Generic, "genJunction: not generic junction");
+
+ if ( q->p1 != NULL ) TRANS(q->p1);
+ if ( q->p2 != NULL ) TRANS(q->p2);
+}
+
+void
+#ifdef __USE_PROTOS
+genEndBlk( Junction *q )
+#else
+genEndBlk( q )
+Junction *q;
+#endif
+{
+}
+
+void
+#ifdef __USE_PROTOS
+genEndRule( Junction *q )
+#else
+genEndRule( q )
+Junction *q;
+#endif
+{
+}
+
+void
+#ifdef __USE_PROTOS
+genHdr( int file )
+#else
+genHdr( file )
+int file;
+#endif
+{
+ int i;
+
+ _gen("/*\n");
+ _gen(" * A n t l r T r a n s l a t i o n H e a d e r\n");
+ _gen(" *\n");
+ _gen(" * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
+ _gen(" * Purdue University Electrical Engineering\n");
+ _gen(" * With AHPCRC, University of Minnesota\n");
+ _gen1(" * ANTLR Version %s\n", Version);
+ _gen(" *\n");
+/* MR10 */ _gen(" * ");
+/* MR10 */ for (i=0 ; i < Save_argc ; i++) {
+/* MR10 */ _gen(" ");
+/* MR10 */ _gen1("%s", Save_argv[i]);
+/* MR10 */ };
+ _gen("\n");
+ _gen(" *\n");
+ _gen(" */\n\n");
+ if (FirstAction != NULL ) dumpAction( FirstAction, output, 0, -1, 0, 1); /* MR11 MR15b */
+ _gen1("#define ANTLR_VERSION %s\n", VersionDef);
+ _gen("#include \"pcctscfg.h\"\n");
+ _gen("#include \"pccts_stdio.h\"\n");
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ _gen2("#define %s %s\n", DefaultParserName, ParserName);
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ {_gen1("#include \"%s\"\n", RemapFileName);}
+ OutLineInfo(output,1,FileStr[file]);
+ if ( GenCC ) {
+ if ( UserTokenDefsFile != NULL )
+ fprintf(output, "#include %s\n", UserTokenDefsFile);
+ else
+ fprintf(output, "#include \"%s\"\n", DefFileName);
+ }
+
+ if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1);
+ if ( !GenCC && FoundGuessBlk )
+ {
+ _gen("#define ZZCAN_GUESS\n");
+ _gen("#include \"pccts_setjmp.h\"\n"); /* MR15 K.J. Cummings (cummings@peritus.com) */
+ }
+ if ( FoundException )
+ {
+ _gen("#define EXCEPTION_HANDLING\n");
+ _gen1("#define NUM_SIGNALS %d\n", NumSignals);
+ }
+ if ( !GenCC && OutputLL_k > 1 ) _gen1("#define LL_K %d\n", OutputLL_k);
+ if ( GenAST&&!GenCC ) _gen("#define GENAST\n\n");
+ if ( GenAST ) {
+ if ( GenCC ) {_gen1("#include \"%s\"\n\n", ASTBASE_H);}
+ else _gen("#include \"ast.h\"\n\n");
+ }
+ if ( !GenCC && DemandLookahead ) _gen("#define DEMAND_LOOK\n\n");
+#ifdef DUM
+ if ( !GenCC && LexGen ) {
+ _gen1("#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
+ }
+#endif
+ /* ###WARNING: This will have to change when SetWordSize changes */
+ if ( !GenCC ) _gen1("#define zzSET_SIZE %lu\n", NumWords(TokenNum-1)*sizeof(unsigned));
+ if (TraceGen) {
+ _gen("#ifndef zzTRACE_RULES\n"); /* MR20 */
+ _gen("#define zzTRACE_RULES\n"); /* MR20 */
+ _gen("#endif\n"); /* MR22 */
+ };
+ if ( !GenCC ) {_gen("#include \"antlr.h\"\n");}
+ else {
+ _gen1("#include \"%s\"\n", APARSER_H);
+ _gen1("#include \"%s.h\"\n", CurrentClassName);
+ }
+ if ( !GenCC ) {
+ if ( UserDefdTokens )
+ {_gen1("#include %s\n", UserTokenDefsFile);}
+ /* still need this one as it has the func prototypes */
+ _gen1("#include \"%s\"\n", DefFileName);
+ }
+ /* still need this one as it defines the DLG interface */
+ if ( !GenCC ) _gen("#include \"dlgdef.h\"\n");
+ if ( LexGen && GenCC ) _gen1("#include \"%s\"\n", DLEXERBASE_H);
+ if ( GenCC ) _gen1("#include \"%s\"\n", ATOKPTR_H);
+ if ( !GenCC && LexGen ) _gen1("#include \"%s\"\n", ModeFileName);
+
+/* MR10 Ofer Ben-Ami (gremlin@cs.huji.ac.il) */
+/* MR10 Finally, a definition of the Purify macro */
+
+ if (PURIFY == TRUE) { /* MR23 */
+ _gen("\n/* MR23 In order to remove calls to PURIFY use the antlr"); /* MR23 */
+ _gen(" -nopurify option */\n\n"); /* MR23 */
+ _gen("#ifndef PCCTS_PURIFY\n");
+ _gen("#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\\0',(s));\n");
+ _gen("#endif\n\n");
+ } /* MR23 */
+}
+
+void
+#ifdef __USE_PROTOS
+genHdr1( int file )
+#else
+genHdr1( file )
+int file;
+#endif
+{
+ ListNode *p;
+
+ genHdr(file);
+ if ( GenAST )
+ {
+ if ( !GenCC ) {
+ _gen("#include \"ast.c\"\n");
+ _gen("zzASTgvars\n\n");
+ }
+ }
+ if ( !GenCC ) _gen("ANTLR_INFO\n");
+ if ( BeforeActions != NULL )
+ {
+ for (p = BeforeActions->next; p!=NULL; p=p->next)
+ {
+ UserAction *ua = (UserAction *)p->elem;
+ dumpAction( ua->action, output, 0, ua->file, ua->line, 1);
+ }
+ }
+
+ if ( !FoundException ) return;
+
+ if ( GenCC )
+ {
+ _gen1("\nvoid %s::\n", CurrentClassName);
+ _gen("zzdflthandlers( int _signal, int *_retsignal )\n");
+ _gen("{\n");
+ }
+ else
+ {
+ _gen("\nvoid\n");
+/* MR1 */
+/* MR1 10-Apr-97 133MR1 Replace __STDC__ with __USE_PROTOS */
+/* MR1 */
+ _gen("#ifdef __USE_PROTOS\n"); /* MR1 */
+ _gen("zzdflthandlers( int _signal, int *_retsignal )\n");
+ _gen("#else\n");
+ _gen("zzdflthandlers( _signal, _retsignal )\n");
+ _gen("int _signal;\n");
+ _gen("int *_retsignal;\n");
+ _gen("#endif\n");
+ _gen("{\n");
+ }
+ tabs++;
+ if ( DefaultExGroup!=NULL )
+ {
+ dumpException(DefaultExGroup, 1);
+ if ( !hasDefaultException(DefaultExGroup) )
+ {
+ gen("default :\n");
+ tabs++;
+ gen("*_retsignal = _signal;\n");
+ tabs--;
+ gen("}\n");
+ }
+ }
+ else {
+ gen("*_retsignal = _signal;\n");
+ }
+
+ tabs--;
+ _gen("}\n\n");
+}
+
+void
+#ifdef __USE_PROTOS
+genStdPCCTSIncludeFile( FILE *f,char *gate ) /* MR10 */
+#else
+genStdPCCTSIncludeFile( f , gate) /* MR10 */
+FILE *f;
+char * gate; /* MR10 */
+#endif
+{
+/* MR10 Ramanathan Santhanam (ps@kumaran.com) */
+/* MR10 Same preprocessor symbol use to gate stdpccts.h */
+/* MR10 even when two grammars are in use. */
+/* MR10 Derive gate symbol from -fh filename */
+
+ if (gate == NULL) {
+ fprintf(f,"#ifndef STDPCCTS_H\n"); /* MR10 */
+ fprintf(f,"#define STDPCCTS_H\n"); /* MR10 */
+ } else {
+ fprintf(f,"#ifndef STDPCCTS_%s_H\n",gate); /* MR10 */
+ fprintf(f,"#define STDPCCTS_%s_H\n",gate); /* MR10 */
+ };
+ fprintf(f,"/*\n");
+ if (gate == NULL) {
+ fprintf(f," * %s -- P C C T S I n c l u d e\n", stdpccts);
+ } else {
+ fprintf(f," * Standard PCCTS include file with -fh %s -- P C C T S I n c l u d e\n", stdpccts);
+ }
+ fprintf(f," *\n");
+ fprintf(f," * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(f," * Purdue University Electrical Engineering\n");
+ fprintf(f," * With AHPCRC, University of Minnesota\n");
+ fprintf(f," * ANTLR Version %s\n", Version);
+ fprintf(f," */\n\n");
+
+ fprintf(f,"#ifndef ANTLR_VERSION\n");
+ fprintf(f,"#define ANTLR_VERSION %s\n", VersionDef);
+ fprintf(f,"#endif\n\n");
+
+ if (FirstAction != NULL ) dumpAction(FirstAction, f, 0, -1, 0, 1); /* MR11 */
+
+ fprintf(f,"#include \"pcctscfg.h\"\n");
+ fprintf(f,"#include \"pccts_stdio.h\"\n");
+ if ( GenCC )
+ {
+ if ( UserDefdTokens )
+ fprintf(f, "#include %s\n", UserTokenDefsFile);
+ else {
+ fprintf(f, "#include \"%s\"\n", DefFileName);
+ }
+
+ fprintf(f, "#include \"%s\"\n", ATOKEN_H);
+
+ if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);
+
+ fprintf(f, "#include \"%s\"\n", ATOKENBUFFER_H);
+
+ if ( OutputLL_k > 1 ) fprintf(f,"static const unsigned LL_K=%d;\n", OutputLL_k);
+ if ( GenAST ) {
+ fprintf(f, "#include \"%s\"\n", ASTBASE_H);
+ }
+
+ if (TraceGen) {
+ fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */
+ fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */
+ fprintf(f,"#endif\n"); /* MR22 */
+ };
+
+ fprintf(f,"#include \"%s\"\n", APARSER_H);
+ fprintf(f,"#include \"%s.h\"\n", CurrentClassName);
+ if ( LexGen ) fprintf(f,"#include \"%s\"\n", DLEXERBASE_H);
+ fprintf(f, "#endif\n");
+ return;
+ }
+
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ fprintf(f, "#define %s %s\n", DefaultParserName, ParserName);
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ fprintf(f, "#include \"%s\"\n", RemapFileName);
+ if ( UserTokenDefsFile != NULL )
+ fprintf(f, "#include %s\n", UserTokenDefsFile);
+ if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1);
+ if ( FoundGuessBlk )
+ {
+ fprintf(f,"#define ZZCAN_GUESS\n");
+ fprintf(f,"#include \"pccts_setjmp.h\"\n");
+ }
+ if (TraceGen) {
+ fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */
+ fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */
+ fprintf(f,"#endif\n"); /* MR22 */
+ };
+ if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %d\n", OutputLL_k);
+ if ( GenAST ) fprintf(f,"#define GENAST\n");
+ if ( FoundException )
+ {
+/* MR1 7-Apr-97 1.33MR1 */
+/* MR1 Fix suggested by: */
+/* MR1 Francois-Xavier Fontaine (fontaine_f@istvax.ist.lu) */
+
+ fprintf(f,"#define EXCEPTION_HANDLING\n"); /* MR1 */
+ fprintf(f,"#define NUM_SIGNALS %d\n", NumSignals); /* MR1 */
+ }
+ if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOK\n");
+#ifdef DUM
+ if ( LexGen ) fprintf(f, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken));
+#endif
+ /* ###WARNING: This will have to change when SetWordSize changes */
+ fprintf(f, "#define zzSET_SIZE %lu\n", NumWords(TokenNum-1)*sizeof(unsigned));
+ if (TraceGen) {
+ fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */
+ fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */
+ fprintf(f,"#endif\n"); /* MR22 */
+ };
+ fprintf(f,"#include \"antlr.h\"\n");
+ if ( GenAST ) fprintf(f,"#include \"ast.h\"\n");
+ if ( UserDefdTokens )
+ fprintf(f, "#include %s\n", UserTokenDefsFile);
+ /* still need this one as it has the func prototypes */
+ fprintf(f, "#include \"%s\"\n", DefFileName);
+ /* still need this one as it defines the DLG interface */
+ fprintf(f,"#include \"dlgdef.h\"\n");
+ /* don't need this one unless DLG is used */
+ if ( LexGen ) fprintf(f,"#include \"%s\"\n", ModeFileName);
+ fprintf(f,"#endif\n");
+}
+
+/* dump action 's' to file 'output' starting at "local" tab 'tabs'
+ Dump line information in front of action if GenLineInfo is set
+ If file == -1 then GenLineInfo is ignored.
+ The user may redefine the LineInfoFormatStr to his/her liking
+ most compilers will like the default, however.
+
+ June '93; changed so that empty lines are left alone so that
+ line information is correct for the compiler/debuggers.
+*/
+void
+#ifdef __USE_PROTOS
+dumpAction( char *s, FILE *output, int tabs, int file, int line,
+int final_newline )
+#else
+dumpAction( s, output, tabs, file, line, final_newline )
+char *s;
+FILE *output;
+int tabs;
+int file;
+int line;
+int final_newline;
+#endif
+{
+ int inDQuote, inSQuote;
+ require(s!=NULL, "dumpAction: NULL action");
+ require(output!=NULL, eMsg1("dumpAction: output FILE is NULL for %s",s));
+
+ if ( GenLineInfo && file != -1 )
+ {
+ OutLineInfo(output,line,FileStr[file]);
+ }
+ PastWhiteSpace( s );
+ /* don't print a tab if first non-white char is a # (preprocessor command) */
+ if ( *s!='#' ) {TAB;}
+ inDQuote = inSQuote = FALSE;
+ while ( *s != '\0' )
+ {
+ if ( *s == '\\' )
+ {
+ fputc( *s++, output ); /* Avoid '"' Case */
+ if ( *s == '\0' ) return;
+ if ( *s == '\'' ) fputc( *s++, output );
+ if ( *s == '\"' ) fputc( *s++, output );
+ }
+ if ( *s == '\'' )
+ {
+ if ( !inDQuote ) inSQuote = !inSQuote;
+ }
+ if ( *s == '"' )
+ {
+ if ( !inSQuote ) inDQuote = !inDQuote;
+ }
+ if ( *s == '\n' )
+ {
+ fputc('\n', output);
+ s++;
+ PastWhiteSpace( s );
+ if ( *s == '}' )
+ {
+ --tabs;
+ TAB;
+ fputc( *s++, output );
+ continue;
+ }
+ if ( *s == '\0' ) return;
+ if ( *s != '#' ) /* #define, #endif etc.. start at col 1 */
+ {
+ TAB;
+ }
+ }
+ if ( *s == '}' && !(inSQuote || inDQuote) )
+ {
+ --tabs; /* Indent one fewer */
+ }
+ if ( *s == '{' && !(inSQuote || inDQuote) )
+ {
+ tabs++; /* Indent one more */
+ }
+ fputc( *s, output );
+ s++;
+ }
+ if ( final_newline ) fputc('\n', output);
+}
+
+static void
+#ifdef __USE_PROTOS
+dumpAfterActions( FILE *output )
+#else
+dumpAfterActions( output )
+FILE *output;
+#endif
+{
+ ListNode *p;
+ require(output!=NULL, "dumpAfterActions: output file was NULL for some reason");
+ if ( AfterActions != NULL )
+ {
+ for (p = AfterActions->next; p!=NULL; p=p->next)
+ {
+ UserAction *ua = (UserAction *)p->elem;
+ dumpAction( ua->action, output, 0, ua->file, ua->line, 1);
+ }
+ }
+ fclose( output );
+}
+
+/*
+ * Find the next action in the stream of execution. Do not pass
+ * junctions with more than one path leaving them.
+ * Only pass generic junctions.
+ *
+ * Scan forward while (generic junction with p2==NULL)
+ * If we stop on an action, return ptr to the action
+ * else return NULL;
+ */
+static ActionNode *
+#ifdef __USE_PROTOS
+findImmedAction( Node *q )
+#else
+findImmedAction( q )
+Node *q;
+#endif
+{
+ Junction *j;
+ require(q!=NULL, "findImmedAction: NULL node");
+ require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node");
+
+ while ( q->ntype == nJunction )
+ {
+ j = (Junction *)q;
+ if ( j->jtype != Generic || j->p2 != NULL ) return NULL;
+ q = j->p1;
+ if ( q == NULL ) return NULL;
+ }
+ if ( q->ntype == nAction ) return (ActionNode *)q;
+ return NULL;
+}
+
+static void
+#ifdef __USE_PROTOS
+dumpRetValAssign( char *retval, char *ret_def, RuleRefNode * ruleRef /* MR30 */)
+#else
+dumpRetValAssign( retval, ret_def, ruleRef /* MR30 */)
+char *retval;
+char *ret_def;
+RuleRefNode *ruleRefNode;
+#endif
+{
+ char *q = ret_def;
+
+ tab();
+ while ( *retval != '\0' && *q != '\0')
+ {
+ while ( isspace((*retval)) ) retval++;
+ while ( *retval!=',' && *retval!='\0' ) fputc(*retval++, output);
+ fprintf(output, " = _trv.");
+
+ DumpNextNameInDef(&q, output);
+ while ( isspace(*q) ) q++;
+ fputc(';', output); fputc(' ', output);
+ if ( *retval == ',' ) retval++;
+ }
+ if (*retval == '\0' && *q != '\0') {
+/* MR30 */ errFL("Fewer output values than output formals for rule reference",
+/* MR30 */ FileStr[ruleRef->file],ruleRef->line);
+ }
+ if (*retval != '\0' && *q == '\0') {
+/* MR30 */ errFL("More output actuals than output formals for rule reference",
+/* MR30 */ FileStr[ruleRef->file],ruleRef->line);
+ }
+}
+
+/* This function computes the set of tokens that can possibly be seen k
+ * tokens in the future from point j
+ */
+
+static set
+#ifdef __USE_PROTOS
+ComputeErrorSet( Junction *j, int k, int usePlusBlockBypass)
+#else
+ComputeErrorSet( j, k, usePlusBlockBypass )
+Junction *j;
+int k;
+int usePlusBlockBypass;
+#endif
+{
+ Junction *alt1;
+ set a, rk, f;
+ require(j->ntype==nJunction, "ComputeErrorSet: non junction passed");
+
+ f = rk = empty;
+ for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2)
+ {
+ if (alt1->ignore && ! usePlusBlockBypass) continue; /* MR21 - Ignore aPlusBlk forward p2 */
+ REACH(alt1->p1, k, &rk, a);
+ require(set_nil(rk), "ComputeErrorSet: rk != nil");
+ set_free(rk);
+ set_orin(&f, a);
+ set_free(a);
+ }
+ return f;
+}
+
+static char *
+#ifdef __USE_PROTOS
+tokenFollowSet(TokNode *p)
+#else
+tokenFollowSet(p)
+TokNode *p;
+#endif
+{
+ static char buf[100];
+ set rk, a;
+ int n;
+ rk = empty;
+
+ REACH(p->next, 1, &rk, a);
+ require(set_nil(rk), "rk != nil");
+ set_free(rk);
+ n = DefErrSet( &a, 0, NULL );
+ set_free(a);
+ if ( GenCC )
+ sprintf(buf, "err%d", n);
+ else
+ sprintf(buf, "zzerr%d", n);
+ return buf;
+}
+
+static void
+#ifdef __USE_PROTOS
+makeErrorClause( Junction *q, set f, int max_k, int usePlusBlockBypass )
+#else
+makeErrorClause( q, f, max_k, usePlusBlockBypass )
+Junction *q;
+set f;
+int max_k;
+int usePlusBlockBypass;
+#endif
+{
+ char * handler_id=""; /* MR7 */
+ int nilf=0; /* MR13 */
+ RuleEntry *ruleEntry; /* MR14 */
+
+ if ( FoundException )
+ {
+ _gen("else {\n");
+ tabs++;
+ if ( FoundGuessBlk )
+ {
+ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");}
+ else gen("if ( zzguessing ) goto fail;\n");
+ }
+ gen("if (_sva) _signal=NoViableAlt;\n");
+ gen("else _signal=NoSemViableAlt;\n");
+ if (q->outerEG != NULL) {
+ handler_id=q->outerEG->altID;
+#if 0
+ } else {
+ printf("q->curAltNum=%d q->exception_label=%s\n",q->curAltNum,q->exception_label);
+ gen("*** DEBUG *** outerEG==NULL\n");
+#endif
+ };
+ gen1("goto %s_handler; /* MR7 */\n",handler_id); /* MR7 */
+ tabs--;
+ gen("}\n");
+ return;
+ }
+
+ if ( max_k == 1 )
+ {
+/* MR13 */ nilf=set_nil(f);
+ if ( GenCC ) {
+ _gen1("else {FAIL(1,err%d", DefErrSet1(1,&f,1,NULL));
+ } else {
+ _gen1("else {zzFAIL(1,zzerr%d", DefErrSet1(1,&f,1,NULL));
+ };
+ set_free(f);
+ }
+ else
+ {
+ int i;
+ set_free(f);
+ if ( GenCC ) {_gen1("else {FAIL(%d", max_k);}
+ else _gen1("else {zzFAIL(%d", max_k);
+
+ ruleEntry = (RuleEntry *) hash_get(Rname,q->rname);
+
+ for (i=1; i<=max_k; i++)
+ {
+/* MR14 */ if (ruleEntry->dontComputeErrorSet) {
+/* MR14 */ f=empty;
+ } else {
+ f = ComputeErrorSet(q, i, usePlusBlockBypass /* use plus block bypass ? */ );
+ }
+
+ if ( GenCC ) {_gen1(",err%d", DefErrSet( &f, 1, NULL ));}
+ else _gen1(",zzerr%d", DefErrSet( &f, 1, NULL ));
+
+ set_free(f);
+ }
+ }
+ _gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}\n");
+/* MR13 */ if (nilf) {
+/* MR13 */ errFL("empty error set for alt - probably because of undefined rule or infinite left recursion",
+/* MR13 */ FileStr[q->file],q->line);
+/* MR13 */ gen(" /* MR13 empty error set for this alt - undef rule ? infinite left recursion ? */");
+/* MR13 */ };
+}
+
+static /* MR7 */
+#ifdef __USE_PROTOS
+char * findOuterHandlerLabel(ExceptionGroup *eg) /* MR7 */
+#else
+char * findOuterHandlerLabel(eg) /* MR7 */
+ExceptionGroup *eg; /* MR7 */
+#endif
+{
+ char *label=NULL; /* MR7 */
+ ExceptionGroup *outerEG; /* MR7 */
+
+ if (eg->forRule == 0) { /* MR7 */
+ if (eg->labelEntry != NULL) { /* MR7 */
+ outerEG=eg->labelEntry->outerEG; /* MR7 */
+ if (outerEG != NULL) { /* MR7 */
+ label=outerEG->altID; /* MR7 */
+ outerEG->used=1; /* MR7 */
+ }; /* MR7 */
+ } else if (eg->outerEG != NULL) { /* MR7 */
+ outerEG=eg->outerEG; /* MR7 */
+ label=outerEG->altID; /* MR7 */
+ outerEG->used=1; /* MR7 */
+ }; /* MR7 */
+ }; /* MR7 */
+ return (label==NULL ? "" : label); /* MR7 */
+} /* MR7 */
+
+/*** debug ***/
+#if 0
+** static /* MR7 */
+** #ifdef __USE_PROTOS
+** char * findOuterAltHandlerLabel(Junction *startJ) /* MR7 */
+** #else
+** char * findOuterAltHandlerLabel(startJ) /* MR7 */
+** Junction *startJ; /* MR7 */
+** #endif
+** { /* MR7 */
+** char *label=NULL; /* MR7 */
+** Junction *alt; /* MR7 */
+** /* MR7 */
+** for (alt=startJ; alt != NULL; alt=alt->outerAltstart) { /* MR7 */
+** label=alt->exception_label; /* MR7 */
+** if (label != NULL) break; /* MR7 */
+** }; /* MR7 */
+** return (label==NULL ? "" : label); /* MR7 */
+** } /* MR7 */
+#endif
+
+#ifdef __USE_PROTOS
+static void OutLineInfo(FILE *file,int line,char *fileName)
+#else
+static void OutLineInfo(file,line,fileName)
+ FILE * file;
+ int line;
+ char * fileName;
+#endif
+{
+ static char * prevFileName=NULL;
+ static char * prevFileNameMS=NULL;
+
+ char * p;
+ char * q;
+
+ if (! GenLineInfo) return;
+
+ if (!GenLineInfoMS) {
+ fprintf(file, LineInfoFormatStr,line,fileName);
+ } else {
+ if (fileName == prevFileName) {
+ fprintf(file, LineInfoFormatStr,line,prevFileNameMS);
+ } else {
+ if (prevFileNameMS != NULL) free (prevFileNameMS);
+ prevFileNameMS=(char *)calloc(1,strlen(fileName)+1);
+ require(prevFileNameMS != NULL,"why not do this in calloc wrapper");
+ q=prevFileNameMS;
+ for (p=fileName; *p != 0; p++) {
+ *q=*p;
+ if (*q == '\\') *q='/';
+ q++;
+ }
+ }
+ prevFileName=fileName;
+ };
+}
+
+#if 0
+
+/* MR21 */
+
+#ifdef __USE_PROTOS
+void OutFirstSetSymbol(Junction *q, char * pSymbol)
+#else
+void OutFirstSetSymbol(q, pSymbol)
+ Junction* q;
+ char * pSymbol
+#endif
+{
+
+ set f;
+ if (pSymbol == NULL) return;
+ gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol);
+ f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */);
+ DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, "");
+ set_free(f);
+}
+#endif
+
+/* MR21 */
+
+#ifdef __USE_PROTOS
+void BlockPreambleOption(Junction *q, char * pSymbol)
+#else
+void BlockPreambleOption(q, pSymbol)
+ Junction* q;
+ char * pSymbol;
+#endif
+{
+ set f = empty;
+ if (pSymbol != NULL) {
+ f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */);
+ gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol);
+ DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, "");
+ }
+ set_free(f);
+}
+
+/* MR21 */
+
+void
+#ifdef __USE_PROTOS
+dumpActionPlus(ActionNode *a, char *s, FILE *output, int tabs, int file, int line,
+int final_newline )
+#else
+dumpActionPlus(a, s, output, tabs, file, line, final_newline )
+ActionNode *a;
+char *s;
+FILE *output;
+int tabs;
+int file;
+int line;
+int final_newline;
+#endif
+{
+ dumpAction(s,output,tabs,file,line,final_newline);
+}
+
+
+#if 0
+** #ifdef __USE_PROTOS
+** void MR_ErrorSets(Junction *q, int max_k, int usePlusBlockBypass)
+** #else
+** void MR_ErrorSets(q, max_k, usePlusBlockBypass)
+** Junction *q;
+** int max_k;
+** int usePlusBlockBypass;
+** #endif
+** {
+** int k;
+** set setResult;
+** Junction* alt1;
+** Junction* p;
+** set rk;
+**
+** require (max_k <= CLL_k, "k > CLL_k");
+**
+**
+** for (k = 1; k <= CLL_k; k++) {set_clr(q->fset[k]); }
+**
+** for (k = 1; k <= max_k; k++) {
+** for (alt1=q; alt1 != NULL; alt1 = (Junction *)alt1->p2)
+** {
+** if (alt1->ignore && ! usePlusBlockBypass) continue;
+** p = analysis_point((Junction *)alt1->p1);
+** REACH(p, k, &rk, setResult);
+** require(set_nil(rk), "rk != nil");
+** set_orin(&q->fset[k], setResult);
+** }
+** }
+** }
+#endif
+
+
+#ifdef __USE_PROTOS
+void DumpInitializers(FILE* output, RuleEntry *r, char * pReturn)
+#else
+void DumpInitializers(output, r, pReturn)
+FILE* output;
+RuleEntry *r;
+char * pReturn;
+#endif
+{
+ char *p = pReturn;
+ char *pDataType;
+ char *pSymbol;
+ char *pEqualSign;
+ char *pValue;
+ char *pSeparator;
+ int nest = 0;
+ char *q;
+
+ require(pReturn!=NULL, "DumpInitializer: invalid string");
+
+ while (*p != 0) {
+ p = endFormal(p,
+ &pDataType,
+ &pSymbol,
+ &pEqualSign,
+ &pValue,
+ &pSeparator,
+ &nest);
+ if (nest != 0) return;
+ if (pValue != NULL) {
+ tab();
+ q = strBetween(pSymbol, pEqualSign, pSeparator);
+ fprintf(output, "_retv.%s", q);
+ q = strBetween(pValue, NULL, pSeparator);
+ fprintf(output, " = %s;\n", q);
+ }
+ }
+}
+
+#ifdef __USE_PROTOS
+void DumpFormals(FILE* output, char * pReturn, int bInitializer)
+#else
+void DumpFormals(output, pReturn, bInitializer)
+FILE* output;
+char * pReturn;
+int bInitializer;
+#endif
+{
+ char *p = pReturn;
+ char *pDataType;
+ char *pSymbol;
+ char *pEqualSign;
+ char *pValue;
+ char *pSeparator;
+ int nest = 0;
+ char *q;
+ int count = 0;
+
+ require(pReturn!=NULL, "DumpFormals: invalid string");
+
+ while (*p != 0) {
+ p = endFormal(p,
+ &pDataType,
+ &pSymbol,
+ &pEqualSign,
+ &pValue,
+ &pSeparator,
+ &nest);
+ if (nest != 0) return;
+ if (count > 0) fprintf(output,",");
+ if (pDataType != NULL && pSymbol != NULL) {
+ q = strBetween(pDataType, pSymbol, pSeparator);
+ fprintf(output, "%s", q);
+ q = strBetween(pSymbol, pEqualSign, pSeparator);
+ fprintf(output," %s",q);
+ if (pValue != NULL) {
+ q = strBetween(pValue, NULL, pSeparator);
+ if (bInitializer != 0) {
+ fprintf(output, " = %s", q);
+ }
+ }
+ }
+ count++;
+ }
+}
+
+/* MR23 Check for empty alt in a more intelligent way.
+ Previously, an empty alt for genBlk had to point directly
+ to the endBlock. This did not work once I changed {...}
+ blocks to look like (...|...| epsilon) since there were
+ intervening generics. This fixes the problem for this
+ particular case. Things like actions or empty blocks of
+ various kinds will still cause problems, but I wasn't
+ prepared to handle pathological cases like (A|()*). It
+ does handle (A | ()), which is a recommended idiom for
+ epsilon.
+
+ Actually, this isn't quite correct since it doesn't handle
+ the case of the ignore bit in the plus block bypass, but
+ I'm too tired to figure out the correct fix, and will just
+ work around it.
+*/
+
+#ifdef __USE_PROTOS
+int isEmptyAlt(Node * alt, Node * endBlock)
+#else
+int isEmptyAlt(alt, endBlock)
+Node * alt;
+Node * endBlock;
+#endif
+{
+ Node * n = alt;
+ Junction * j;
+ while (n != endBlock) {
+ switch (n->ntype) {
+
+ case nRuleRef:
+ return 0;
+
+ case nToken:
+ return 0;
+
+ case nAction:
+ return 0;
+
+ case nJunction:
+ goto JUNCTION;
+
+ default:
+ fatal_internal("Invalid node type");
+ return 0;
+ }
+JUNCTION:
+ j = (Junction *) n;
+
+ switch (j->jtype) {
+ case Generic:
+ {
+ n = j->p1;
+ goto NEXT;
+ }
+
+ case aSubBlk:
+ {
+ n = j->p1; /* MR26 */
+ goto NEXT; /* MR26 */
+ }
+
+ case EndBlk:
+ return 0;
+
+ case EndRule:
+ return 1;
+
+ default:
+ return 0;
+ }
+NEXT: continue;
+ }
+ return 1;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/generic.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/generic.h
new file mode 100644
index 00000000..b4328c7b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/generic.h
@@ -0,0 +1,286 @@
+/*
+ * generic.h -- generic include stuff for new PCCTS ANTLR.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#define StrSame 0
+
+#define DefaultParserName "zzparser"
+
+/* MR9 JVincent@novell.com Allow user to override default ZZLEXBUFSIZE */
+/* MR11 thm Raise antlr's own default ZZLEXBUFSIZE to 8k */
+/* MR22 thm Raise antlr's own default ZZLEXBUFSIZE to 32k */
+
+#ifndef ZZLEXBUFSIZE
+#define ZZLEXBUFSIZE 32000
+#endif
+
+/* Tree/FIRST/FOLLOW defines -- valid only after all grammar has been read */
+#define ALT TokenNum+1
+#define SET TokenNum+2
+#define TREE_REF TokenNum+3
+
+ /* E r r o r M a c r o s */
+
+#define fatal(err) fatalFL(err, __FILE__, __LINE__)
+#define fatal_internal(err) fatal_intern(err, __FILE__, __LINE__)
+
+
+#define eMsg1(s,a) eMsg3(s,a,NULL,NULL)
+#define eMsg2(s,a,b) eMsg3(s,a,b,NULL)
+
+ /* S a n i t y C h e c k i n g */
+
+#ifndef require
+#define require(expr, err) {if ( !(expr) ) fatal_internal(err);}
+#endif
+
+ /* L i s t N o d e s */
+
+typedef struct _ListNode {
+ void *elem; /* pointer to any kind of element */
+ struct _ListNode *next;
+ } ListNode;
+
+/* Define a Cycle node which is used to track lists of cycles for later
+ * reconciliation by ResolveFoCycles().
+ */
+typedef struct _c {
+ int croot; /* cycle root */
+ set cyclicDep; /* cyclic dependents */
+ unsigned deg; /* degree of FOLLOW set of croot */
+ } Cycle;
+
+typedef struct _e {
+ int tok; /* error class name == TokenStr[tok] */
+ ListNode *elist; /* linked list of elements in error set */
+ set eset;
+ int setdeg; /* how big is the set */
+ int lexclass; /* which lex class is it in? */
+ } ECnode;
+
+typedef struct _TCnode {
+ int tok; /* token class name */
+ ListNode *tlist; /* linked list of elements in token set */
+ set tset;
+ int lexclass; /* which lex class is it in? */
+ unsigned char dumped; /* this def has been been dumped */
+ unsigned char dumpedComplement; /* this def has been been dumped */
+ unsigned setnum; /* which set number is this guy? (if dumped) */
+ unsigned setnumComplement; /* MR23 */
+ unsigned setnumErrSet; /* MR23 which set is this #tokclass error set (if dumped) */
+ unsigned setnumErrSetComplement; /* MR23 */
+ } TCnode;
+
+typedef struct _ft {
+ char *token; /* id of token type to remap */
+ int tnum; /* move token type to which token position */
+ } ForcedToken;
+
+typedef struct _ContextGuardPredicates { /* MR13 */
+ Predicate *pred; /* MR13 */
+ } ContextGuardPredicates; /* MR13 */
+
+#define newListNode (ListNode *) calloc(1, sizeof(ListNode));
+#define newCycle (Cycle *) calloc(1, sizeof(Cycle));
+#define newECnode (ECnode *) calloc(1, sizeof(ECnode));
+#define newTCnode (TCnode *) calloc(1, sizeof(TCnode));
+
+
+ /* H a s h T a b l e E n t r i e s */
+
+typedef struct _t { /* Token name or expression */
+ char *str;
+ struct _t *next;
+ int token; /* token number */
+ unsigned char classname; /* is it a err/tok class name or token */
+ TCnode *tclass; /* ptr to token class */
+ char *action;
+ char *akaString;
+ } TermEntry;
+
+typedef struct _r { /* Rule name and ptr to start of rule */
+ char *str;
+ struct _t *next;
+ int rulenum; /* RulePtr[rulenum]== ptr to RuleBlk junction */
+ unsigned char noAST;/* gen AST construction code? (def==gen code) */
+ char *egroup; /* which error group (err reporting stuff) */
+#if 0
+ /* MR27 This appears to never be used. Delete this code later. */
+
+ ListNode *el_labels;/* list of element labels ref in all of rule */
+#endif
+ ListNode *ast_labels_in_actions; /* MR27 */
+ unsigned char has_rule_exception;
+ char dontComputeErrorSet; /* MR14 - don't compute error set
+ special for rule in alpha part of
+ (alpha)? beta block */
+ } RuleEntry;
+
+typedef struct _f { /* cache Fi/Fo set */
+ char *str; /* key == (rulename, computation, k) */
+ struct _f *next;
+ set fset; /* First/Follow of rule */
+ set rk; /* set of k's remaining to be done after ruleref */
+ int incomplete; /* only w/FOLLOW sets. Use only if complete */
+ } CacheEntry;
+
+typedef struct _LabelEntry { /* element labels */
+ char *str;
+ struct _f *next;
+ Node *elem; /* which element does it point to? */
+ ExceptionGroup *ex_group;
+ /* Is there an exception attached to label? */
+ ExceptionGroup *outerEG; /* MR7 */
+ /* next EG if ex_group doesn't catch it MR7 */
+ struct _LabelEntry *pendingLink; /* MR7 */
+ /* too lazy to use ListNode ? MR7 */
+ int curAltNum; /* MR7 */
+ } LabelEntry;
+
+typedef struct _SignalEntry {
+ char *str;
+ struct _f *next;
+ int signum; /* unique signal number */
+ } SignalEntry;
+
+typedef struct _PredEntry { /* MR11 predicate name and ptr to string */
+ char *str;
+ struct _PredEntry *next;
+ int file;
+ int line;
+ Predicate *pred;
+ char *predLiteral;
+ } PredEntry;
+
+typedef struct _PointerStack { /* MR10 */
+ int count;
+ int size;
+ void **data;
+ } PointerStack;
+
+#define newTermEntry(s) (TermEntry *) newEntry(s, sizeof(TermEntry))
+#define newRuleEntry(s) (RuleEntry *) newEntry(s, sizeof(RuleEntry))
+#define newCacheEntry(s) (CacheEntry *) newEntry(s, sizeof(CacheEntry))
+#define newLabelEntry(s) (LabelEntry *) newEntry(s, sizeof(LabelEntry))
+#define newSignalEntry(s) (SignalEntry *) newEntry(s, sizeof(SignalEntry))
+#define newPredEntry(s) (PredEntry *) newEntry(s,sizeof(PredEntry))
+
+typedef struct _UserAction {
+ char *action;
+ int file, line;
+ } UserAction;
+
+
+ /* L e x i c a l C l a s s */
+
+/* to switch lex classes, switch ExprStr and Texpr (hash table) */
+typedef struct _lc {
+ char *classnum, **exprs;
+ Entry **htable;
+ } LClass;
+
+typedef struct _exprOrder {
+ char *expr;
+ int lclass;
+ } Expr;
+
+
+typedef Graph Attrib;
+
+ /* M a x i m u m s */
+
+/* MR20 Note G. Hobbelt These values are superseded by values in hash.h */
+
+#ifndef HashTableSize
+#define HashTableSize 253
+#endif
+#ifndef StrTableSize
+#define StrTableSize 15000 /* all tokens, nonterminals, rexprs stored here */
+#endif
+#define MaxLexClasses 50 /* how many automatons */
+/* TokenStart and EofToken are ignored if #tokdefs meta-op is used */
+#define TokenStart 2 /* MUST be in 1 + EofToken */
+#define EofToken 1 /* Always predefined to be 1 */
+
+#ifndef MaxNumFiles
+#define MaxNumFiles 99
+#endif
+
+/**** MR9 JVincent@novell.com Move to pcctscfg.h */
+/**** #define MaxFileName 300 ****/ /* MR9 Move to pcctscfg.h */ /* largest file name size */
+
+#define MaxRuleName 100 /* largest rule name size */
+#define TSChunk 100 /* how much to expand TokenStr/ExprStr each time */
+#define TIChunk TSChunk /* expand TokenInd by same as TokenStr to mirror them */
+#define FoStackSize 100 /* deepest FOLLOW recursion possible */
+
+#define MaxClassDeclStuff 256 /* MR10 */
+
+#define NumPredefinedSignals 3
+
+ /* S t a n d a r d S i g n a l s */
+
+#define sigNoSignal 0
+#define sigMismatchedToken 1
+#define sigNoViableAlt 2
+#define sigNoSemViableAlt 3
+
+
+
+/* AST token types */
+#define ASTexclude 0
+#define ASTchild 1
+#define ASTroot 2
+#define ASTinclude 3 /* include subtree made by rule ref */
+
+
+#define PredictionVariable "zzpr_expr"
+#define PredictionLexClassSuffix "_zzpred"
+
+#define WildCardString "WildCard"
+
+#if 0
+ /* Removed in version 1.33MR19
+ Don't understand why this never caused problems before
+ */
+
+ /*********************************************************
+ #ifndef ANTLRm
+ #define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE;\
+ zzmode(_m); \
+ zzenterANTLR(f); \
+ st; ++zzasp; \
+ zzleaveANTLR(f);
+ #endif
+ *********************************************************/
+#endif
+
+#include "proto.h"
+#include "pcctscfg.h" /* MR14 */
+#include <string.h>
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/globals.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/globals.c
new file mode 100644
index 00000000..3b7631f7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/globals.c
@@ -0,0 +1,484 @@
+/*
+ * globals.c -- File containing all variables/tables visible to all files.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+
+#include "pcctscfg.h"
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+char Version[] = "1.33MR33" ; /* PCCTS version number */ /* MRXXX */
+char VersionDef[] = "13333"; /* same (except int equiv for preproc symbol) */ /* MRXXX */
+
+char LexStartSymbol[] = "START";/* Name of starting lexical class/automaton */
+char *RemapFileName = "remap.h";
+char *DlgFileName = "parser.dlg";
+char *DefFileName = "tokens.h";
+char *ErrFileName = "err.c";
+char *ModeFileName = "mode.h";
+char *StdMsgName = NULL;
+
+char *ParserName = DefaultParserName;
+
+/* list of PCCTS supplied support symbols; these are renamed when more than
+ * one ANTLR-generated parsers are linked together to avoid name conflicts.
+ * Can't use '##' ANSIC preprocessor concat operator with K&R and:
+ * #define zzskip zzparser ## skip
+ * will not work for ANSI/C++ as 'zzparserskip' is created w/o zzparser
+ * being substituted--ack!!!
+ */
+char *StandardSymbols[] = {
+/* ANTLR stuff */
+ "zzStackOvfMsg",
+ "zzasp",
+ "zzaStack",
+ "inf_tokens",
+ "inf_text",
+ "inf_text_buffer",
+ "inf_text_buffer_ptr",
+ "inf_text_buffer_size",
+ "inf_labase",
+ "inf_last",
+ "inf_lap",
+ "zztokenLA",
+ "zztextLA",
+ "zzlap",
+ "zzlabase",
+ "zztoktext",
+ "zztoken",
+ "zzdirty",
+ "zzguessing",
+ "zzguess_start",
+ "zzresynch",
+ "zzinf_tokens",
+ "zzinf_text",
+ "zzinf_text_buffer",
+ "zzinf_labase",
+ "zzinf_last",
+ "zzfill_inf_look",
+ "zzFAIL",
+ "zzsave_antlr_state",
+ "zzrestore_antlr_state",
+ "zzsyn",
+ "zzset_el",
+ "zzset_deg",
+ "zzedecode",
+ "_zzsetmatch",
+ "_zzmatch",
+ "_inf_zzgettok",
+ "zzconsumeUntil",
+ "zzconsumeUntilToken",
+ "_zzmatch_wsig",
+ "_zzsetmatch_wsig",
+ "_zzmatch_wdfltsig",
+ "_zzsetmatch_wdfltsig",
+ "zzdflthandlers",
+/* DLG stuff */
+ "zzreal_line",
+ "zzcharfull",
+ "zzerr",
+ "zzlextext",
+ "zzbegexpr",
+ "zzendexpr",
+ "zzbufsize",
+ "zzbegcol",
+ "zzendcol",
+ "zzline",
+ "zzchar",
+ "zzbufovf",
+ "zzrdstream",
+ "zzrdfunc",
+ "zzrdstr",
+ "zzclose_stream",
+ "zzsave_dlg_state",
+ "zzrestore_dlg_state",
+ "zzmode",
+ "zzskip",
+ "zzmore",
+ "zzreplchar",
+ "zzreplstr",
+ "zzgettok",
+ "zzadvance",
+ "zzerrstd",
+ "zzerr_in",
+ "zzconstr_attr",
+ "zzempty_attr",
+ "zzerraction",
+ "zztokens", /* list of token regular expressions */
+ "dfa",
+ "accepts",
+ "actions",
+ "zzTraceOptionValue", /* MR10 */
+ "zzTraceGuessOptionValue", /* MR10 */
+ "zzTraceCurrentRuleName", /* MR10 */
+ "zzTraceDepth", /* MR10 */
+ "zzGuessSeq", /* MR10 */
+ "zzSyntaxErrCount", /* MR11 */
+ "zzLexErrCount", /* MR11 */
+ "zzTraceGuessDone", /* MR13 - BJS */
+ "zzTraceGuessFail", /* MR13 - BJS */
+ "zzTraceGuessOption", /* MR13 - BJS */
+ "zzTraceIn", /* MR13 - BJS */
+ "zzTraceOption", /* MR13 - BJS */
+ "zzTraceOut", /* MR13 - BJS */
+ "zzTraceReset", /* MR13 - BJS */
+ NULL /* must be present */
+};
+
+/* list of PCCTS supplied support functions; these are renamed when more than
+ * one ANTLR-generated parsers are linked together to avoid name conflicts.
+ */
+char *ASTSymbols[] = {
+ "AST",
+ "zzast_sp",
+ "zzastStack",
+ "zzlink",
+ "zzastnew",
+ "zzsubchild",
+ "zzsubroot",
+ "zzpre_ast",
+ "zzfree_ast",
+ "zztmake",
+ "zzdup_ast",
+ "zztfree",
+ "zzdouble_link",
+ NULL /* must be present */
+};
+
+/* Current ambiguity examination information */
+int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile;
+char *CurAmbigbtype;
+
+
+ /* M e t h o d T a b l e s */
+/*
+ * The following tables are used to fill syntax diagram nodes with the correct
+ * function pointers for computing FIRST sets and printing themselves.
+ */
+
+/* fpTraverse[node type] == pointer to function that calculates trees
+ * representing the FIRST sets for that node (maintains spatial info).
+ * We use 'struct _tree' not 'tree' due to a g++ 2.4.3 bug.
+ */
+#ifdef __cplusplus
+struct _tree *(*fpTraverse[NumNodeTypes+1])(... /* Node *, int, set * */) = {
+ NULL,
+ (struct _tree *(*)(...)) tJunc,
+ (struct _tree *(*)(...)) tRuleRef,
+ (struct _tree *(*)(...)) tToken,
+ (struct _tree *(*)(...)) tAction
+};
+#else
+Tree *(*fpTraverse[NumNodeTypes+1])() = {
+ NULL,
+ tJunc,
+ tRuleRef,
+ tToken,
+ tAction
+};
+#endif
+
+/* fpReach[node type] == pointer to function that calculates FIRST set for
+ * that node. (r stands for reach). We use 'struct _set' not 'set'
+ * due to a g++ 2.4.3 bug.
+ */
+#ifdef __cplusplus
+struct _set (*fpReach[NumNodeTypes+1])(... /* Node *, int, set * */) = {
+ NULL,
+ (struct _set (*)(...)) rJunc,
+ (struct _set (*)(...)) rRuleRef,
+ (struct _set (*)(...)) rToken,
+ (struct _set (*)(...)) rAction
+};
+#else
+set (*fpReach[NumNodeTypes+1])() = {
+ NULL,
+ rJunc,
+ rRuleRef,
+ rToken,
+ rAction
+};
+#endif
+
+/* fpPrint[node type] == pointer to function that knows how to print that node. */
+#ifdef __cplusplus
+void (*fpPrint[NumNodeTypes+1])(... /* Node * */) = {
+ NULL,
+ (void (*)(...)) pJunc,
+ (void (*)(...)) pRuleRef,
+ (void (*)(...)) pToken,
+ (void (*)(...)) pAction
+};
+#else
+void (*fpPrint[NumNodeTypes+1])() = {
+ NULL,
+ pJunc,
+ pRuleRef,
+ pToken,
+ pAction
+};
+#endif
+
+char *decodeJType[] = {
+ "invalid",
+ "aSubBlk",
+ "aOptBlk",
+ "aLoopBlk",
+ "EndBlk",
+ "RuleBlk",
+ "Generic",
+ "EndRule",
+ "aPlusBlk",
+ "aLoopBegin"
+};
+
+
+ /* H a s h T a b l e s */
+
+Entry **Tname, /* Table of all token names (maps name to tok num)*/
+ **Texpr, /* Table of all token expressions
+ (maps expr to tok num) */
+ **Rname, /* Table of all Rules (has ptr to start of rule) */
+ **Fcache, /* Cache of First/Follow Computations */
+ **Tcache; /* Tree cache; First/Follow for permute trees */
+Entry **Elabel; /* Table of all element label names */
+Entry **Sname; /* Signal names */
+Entry **Pname; /* symbolic predicate names MR11 */
+
+
+ /* V a r i a b l e s */
+
+int Save_argc; /* MR10 */
+char **Save_argv; /* MR10 */
+int EpToken=0; /* Imaginary Epsilon token number */
+int WildCardToken=0;
+int CurFile= -1; /* Index into FileStr table */
+char *CurPredName=NULL; /* MR11 */
+char *CurRule=NULL; /* Pointer to current rule name */
+int CurRuleDebug=0; /* MR13 debug flag */
+RuleEntry *CurRuleNode=NULL;/* Pointer to current rule node in syntax tree */
+char *CurRetDef=NULL; /* Pointer to current return type definition */
+char *CurParmDef=NULL; /* Pointer to current parameter definition */
+Junction *CurRuleBlk=NULL; /* Pointer to current block node for enclosing block */
+ListNode *CurExGroups=NULL; /* Current list of exception groups for rule/alts */
+ListNode *CurElementLabels=NULL;
+ListNode *CurAstLabelsInActions=NULL; /* MR27 */
+
+/* MR10 used by <<>>? to set "label_used_in_semantic_pred" */
+/* MR10 this will force LT(i) assignment even in guess mode */
+
+ListNode *CurActionLabels=NULL; /* MR10 Element Labels appearing in last action */
+int numericActionLabel=0 ; /* MR10 << ... $1 ... >> or << ... $1 ... >>? */
+ListNode *NumericPredLabels=NULL; /* MR10 << ... $1 ... >>? ONLY */
+ListNode *ContextGuardPredicateList=NULL; /* MR13 for re-evaluating predicates
+ after meta tokens are defined */
+
+int CurBlockID=0; /* Unique int for each block */
+int CurAltNum=0;
+Junction *CurAltStart = NULL; /* Junction node that starts the alt */
+Junction *OuterAltStart = NULL; /* For chaining exception groups MR7 */
+int NumRules=0; /* Rules are from 1 to n */
+FILE *output=NULL; /* current parser output file */
+FILE *input=NULL; /* current grammar input file */
+char *FileStr[MaxNumFiles];/* Ptr to array of file names on command-line */
+int NumFiles=0; /* current grammar file number */
+#ifdef __cplusplus
+void (**fpTrans)(...), /* array of ptrs to funcs that translate nodes */
+ (**fpJTrans)(...); /* ... that translate junctions */
+#else
+void (**fpTrans)(), /* array of ptrs to funcs that translate nodes */
+ (**fpJTrans)(); /* ... that translate junctions */
+#endif
+int **FoStack; /* Array of LL_k ptrs to stacks of rule numbers */
+int **FoTOS; /* FOLLOW stack top-of-stack pointers */
+Junction *SynDiag = NULL; /* Pointer to start of syntax diagram */
+int BlkLevel=1; /* Current block level. Set by antlr.g, used by
+ * scanner to translate $i.j attributes */
+set reserved_positions; /* set of token positions reserved by '#token T=i' cmds */
+set all_tokens; /* set of all token types */
+set imag_tokens; /* set of all imaginary token types (EpToken, errclasses...) */
+set tokclasses; /* set of all token class token types */
+ListNode *ForcedTokens = 0; /* list of token_id/token_num pairs to remap */
+ListNode *MetaTokenNodes=NULL; /* list of meta token refs such as token classes etc... */
+int *TokenInd=NULL; /* an indirection level between token num and position
+ * of that token def in TokenStr and ExprStr */
+int LastTokenCounted=0; /* ==TokenNum if no token renumbering (same as old TokenNum) */
+int TokenNum=TokenStart;
+char **TokenStr=NULL; /* map token # to token name */
+char **ExprStr=NULL; /* map token # to expr */
+Junction **RulePtr=NULL; /* map rule # to RuleBlk node of rule */
+ListNode *ExprOrder=NULL; /* list of exprs as they are found in grammar */
+ListNode *BeforeActions=NULL;/* list of grammar actions before rules */
+ListNode *AfterActions=NULL;/* list of grammar actions after rules */
+ListNode *LexActions=NULL; /* list of lexical actions */
+
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via #lexmember <<....>> */
+/* MR1 via #lexprefix <<....>> */
+/* MR1 */
+
+ListNode *LexMemberActions=NULL;/* list of lexical header member decl MR1 */
+ListNode *LexPrefixActions=NULL;/* list of lexical header #include decl MR1 */
+ListNode **Cycles=NULL; /* list of cycles (for each k) found when
+ doing FOLLOWs */
+ListNode *eclasses=NULL; /* list of error classes */
+ListNode *tclasses=NULL; /* list of token classes */
+LClass lclass[MaxLexClasses]; /* array of lex class definitions */
+int CurrentLexClass; /* index into lclass */
+int NumLexClasses=0; /* in range 1..MaxLexClasses (init 0) */
+
+char *HdrAction=NULL; /* action defined with #header */
+char *FirstAction=NULL; /* action defined with #first MR11 */
+FILE *ErrFile; /* sets and error recovery stuff */
+FILE *DefFile=NULL; /* list of tokens, return value structs, setwd defs */
+FILE *MRinfoFile=NULL; /* MR10 information file */
+int MRinfo=0; /* MR10 */
+int MRinfoSeq=0; /* MR10 */
+int InfoP=0; /* MR10 predicates */
+int InfoT=0; /* MR10 tnodes */
+int InfoF=0; /* MR10 first/follow sets */
+int InfoM=0; /* MR10 monitor progress */
+int InfoO=0; /* MR12 orphan rules */
+int TnodesInUse=0; /* MR10 */
+int TnodesPeak=0; /* MR10 */
+int TnodesAllocated=0; /* MR10 */
+int TnodesReportThreshold=0; /* MR11 */
+int PotentialSuppression=0; /* MR10 */
+int PotentialDummy=0; /* MR10 */
+int CannotContinue=FALSE;
+int OutputLL_k = 1; /* LL_k for parsing must be power of 2 */
+int action_file; /* used to track start of action */
+int action_line;
+int FoundGuessBlk=0; /* there is a (...)? block somewhere in grammar */
+int FoundException=0; /* there is an exception somewhere in grammar */
+/* MR6 Distinguish between @ operator and real exception */
+/* MR6 by keeping separate flags for @ operator and real exceptions */
+int FoundAtOperator=0; /* MR6 */
+int FoundExceptionGroup=0; /* MR6 */
+int pLevel=0; /* print Level */
+int pAlt1,pAlt2; /* print "==>" in front of these alts */
+
+/* C++ output stuff */
+FILE *Parser_h, /* where subclass of ANTLRParser goes */
+ *Parser_c; /* where code for subclass of ANTLRParser goes */
+char Parser_h_Name[MaxFileName+1] = "";
+char Parser_c_Name[MaxFileName+1] = "";
+char MRinfoFile_Name[MaxFileName+1] = ""; /* MR10 */
+char *ClassDeclStuff=NULL; /* MR10 */
+char *BaseClassName=NULL; /* MR22 */
+/* list of actions inside the #class {...} defs */
+ListNode *class_before_actions=NULL;
+ListNode *class_after_actions=NULL;
+
+char CurrentClassName[MaxRuleName]="";
+int no_classes_found=1;
+char *UserTokenDefsFile;
+int UserDefdTokens=0; /* found #tokdefs? */
+char *OutputDirectory=TopDirectory;
+ExceptionGroup *DefaultExGroup = NULL;
+int NumSignals = NumPredefinedSignals;
+int ContextGuardTRAV=0;
+
+char *MR_AmbAidRule=NULL; /* MR11 */
+int MR_AmbAidLine=0; /* MR11 */
+int MR_AmbAidDepth=0; /* MR11 */
+int MR_AmbAidMultiple=0; /* MR11 */
+int MR_skipped_e3_report=0; /* MR11 */
+int MR_usingPredNames=0; /* MR11 */
+int MR_BadExprSets=0; /* MR13 */
+int MR_Inhibit_Tokens_h_Gen=0; /* MR13 */
+int NewAST=0; /* MR13 */
+int tmakeInParser=0; /* MR23 */
+int AlphaBetaTrace=0; /* MR14 */
+int MR_BlkErr=0; /* MR21 */
+int MR_AlphaBetaMessageCount=0; /* MR14 */
+int MR_AlphaBetaWarning=0; /* MR14 */
+int MR_ErrorSetComputationActive=0; /* MR14 */
+int MR_MaintainBackTrace=0; /* MR14 */
+set MR_CompromisedRules; /* MR14 */
+
+Junction *MR_RuleBlkWithHalt; /* MR10 */
+
+ /* C m d - L i n e O p t i o n s */
+
+int LL_k=1; /* how many tokens of full lookahead */
+int CLL_k= -1; /* how many tokens of compressed lookahead */
+int PrintOut = FALSE; /* print out the grammar */
+int PrintAnnotate = FALSE;/* annotate printout with FIRST sets */
+int CodeGen=TRUE; /* Generate output code? */
+int LexGen=TRUE; /* Generate lexical files? (tokens.h, parser.dlg) */
+int GenAST=FALSE; /* Generate AST's? */
+int GenANSI=FALSE; /* Generate ANSI code where necessary */
+int GenExprSetsOpt=TRUE;/* use sets not (LA(1)==tok) expression lists */
+int GenCR=FALSE; /* Generate cross reference? */
+int GenLineInfo=FALSE; /* Generate # line "file" stuff? */
+int GenLineInfoMS=FALSE;/* Like -gl but replace "\" with "/" for MS C/C++ systems */
+int TraceGen=FALSE; /* Generate code to trace rule invocation */
+int elevel=1; /* error level for ambiguity messages */
+int GenEClasseForRules=0;/* don't generate eclass for each rule */
+int TreeResourceLimit= -1;/* don't limit tree resource */
+int DemandLookahead = 0;/* demand/delayed lookahead or not */
+char *RulePrefix = ""; /* prefix each generated rule with this */
+char *stdpccts = "stdpccts.h";/* where to generate std pccts include file */
+int GenStdPccts = 0; /* don't gen stdpccts.h? */
+int ParseWithPredicates = 1;
+int WarningLevel = 1;
+int UseStdout = 0; /* MR6 */
+int TabWidth = 2; /* MR6 */ /* MR27 */
+int HoistPredicateContext = 0;
+int MRhoisting = 0; /* MR9 */
+int MRhoistingk = 0; /* MR13 */
+int MR_debugGenRule=0; /* MR11 */
+
+int GenCC = 0; /* Generate C++ output */
+
+PointerStack MR_BackTraceStack={0,0,NULL}; /* MR10 */
+PointerStack MR_PredRuleRefStack={0,0,NULL}; /* MR10 */
+PointerStack MR_RuleBlkWithHaltStack={0,0,NULL}; /* MR10 */
+
+/* DontCopyTokens and Pragma_DupLabeledTokens were a bad idea. I've just
+ turned them off rather than backpatching the code. Who knows? We
+ may need them in the future.
+ */
+int DontCopyTokens = 1; /* in C++, don't copy ANTLRToken passed to ANTLR */
+
+/* Remember if LT(i), LA(i), or LATEXT(i) used in an action which is not
+ a predicate. If so, give a warning for novice users.
+*/
+
+int LTinTokenAction = 0; /* MR23 */
+int PURIFY = 1; /* MR23 */
+
+int CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */
+int CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.c
new file mode 100644
index 00000000..787cf65b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.c
@@ -0,0 +1,224 @@
+/*
+ * hash.c
+ *
+ * Manage hash tables.
+ *
+ * The following functions are visible:
+ *
+ * char *mystrdup(char *); Make space and copy string
+ * Entry **newHashTable(); Create and return initialized hash table
+ * Entry *hash_add(Entry **, char *, Entry *)
+ * Entry *hash_get(Entry **, char *)
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#ifdef VBOX
+# include <iprt/stdint.h> /* for intptr.h */
+#endif
+#include "pcctscfg.h"
+#include "hash.h"
+
+#ifdef __USE_PROTOS
+#include <stdlib.h>
+#else
+#ifdef VAXC
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#endif
+#include <string.h>
+
+#define StrSame 0
+
+#define fatal(err) \
+ {fprintf(stderr, "%s(%d):", __FILE__, __LINE__); \
+ fprintf(stderr, " %s\n", err); exit(PCCTS_EXIT_FAILURE);}
+#define require(expr, err) {if ( !(expr) ) fatal(err);}
+
+static unsigned size = HashTableSize;
+static char *strings = NULL;
+static char *strp;
+static unsigned strsize = StrTableSize;
+
+/* create the hash table and string table for terminals (string table only once) */
+Entry **
+#ifdef __USE_PROTOS
+newHashTable( void )
+#else
+newHashTable( )
+#endif
+{
+ Entry **table;
+
+ table = (Entry **) calloc(size, sizeof(Entry *));
+ require( table != NULL, "cannot allocate hash table");
+ if ( strings == NULL )
+ {
+ strings = (char *) calloc(strsize, sizeof(char));
+ require( strings != NULL, "cannot allocate string table");
+ strp = strings;
+ }
+ return table;
+}
+
+void
+#ifdef __USE_PROTOS
+killHashTable( Entry **table )
+#else
+killHashTable( table )
+Entry **table;
+#endif
+{
+ /* for now, just free table, forget entries */
+ free( (char *) table ); /* MR10 cast */
+}
+
+/* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */
+Entry *
+#ifdef __USE_PROTOS
+hash_add( Entry **table, char *key, Entry *rec )
+#else
+hash_add( table, key, rec )
+Entry **table;
+char *key;
+Entry *rec;
+#endif
+{
+ unsigned h=0;
+ char *p=key;
+ require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition");
+
+ Hash(p,h,size);
+ rec->next = table[h]; /* Add to singly-linked list */
+ table[h] = rec;
+ return rec;
+}
+
+/* Return ptr to 1st entry found in table under key (return NULL if none found) */
+Entry *
+#ifdef __USE_PROTOS
+hash_get( Entry **table, char *key )
+#else
+hash_get( table, key )
+Entry **table;
+char *key;
+#endif
+{
+ unsigned h=0;
+ char *p=key;
+ Entry *q;
+/* require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/
+ if ( !(table!=NULL && key!=NULL) ) *((char *)(/*vbox:*/ intptr_t) 34) = 3;
+
+ Hash(p,h,size);
+ for (q = table[h]; q != NULL; q = q->next)
+ {
+ if ( strcmp(key, q->str) == StrSame ) return( q );
+ }
+ return( NULL );
+}
+
+#ifdef DEBUG_HASH
+void
+#ifdef __USE_PROTOS
+hashStat( Entry **table )
+#else
+hashStat( table )
+Entry **table;
+#endif
+{
+ static unsigned short count[20];
+ int i,n=0,low=0, hi=0;
+ Entry **p;
+ float avg=0.0;
+
+ for (i=0; i<20; i++) count[i] = 0;
+ for (p=table; p<&(table[size]); p++)
+ {
+ Entry *q = *p;
+ int len;
+
+ if ( q != NULL && low==0 ) low = p-table;
+ len = 0;
+ if ( q != NULL ) fprintf(stderr, "[%d]", p-table);
+ while ( q != NULL )
+ {
+ len++;
+ n++;
+ fprintf(stderr, " %s", q->str);
+ q = q->next;
+ if ( q == NULL ) fprintf(stderr, "\n");
+ }
+ count[len]++;
+ if ( *p != NULL ) hi = p-table;
+ }
+
+ fprintf(stderr, "Storing %d recs used %d hash positions out of %d\n",
+ n, size-count[0], size);
+ fprintf(stderr, "%f %% utilization\n",
+ ((float)(size-count[0]))/((float)size));
+ for (i=0; i<20; i++)
+ {
+ if ( count[i] != 0 )
+ {
+ avg += (((float)(i*count[i]))/((float)n)) * i;
+ fprintf(stderr, "Bucket len %d == %d (%f %% of recs)\n",
+ i, count[i], ((float)(i*count[i]))/((float)n));
+ }
+ }
+ fprintf(stderr, "Avg bucket length %f\n", avg);
+ fprintf(stderr, "Range of hash function: %d..%d\n", low, hi);
+}
+#endif
+
+/* Add a string to the string table and return a pointer to it.
+ * Bump the pointer into the string table to next avail position.
+ */
+char *
+#ifdef __USE_PROTOS
+mystrdup( char *s )
+#else
+mystrdup( s )
+char *s;
+#endif
+{
+ char *start=strp;
+ require(s!=NULL, "mystrdup: NULL string");
+
+ while ( *s != '\0' )
+ {
+ require( strp <= &(strings[strsize-2]),
+ "string table overflow\nIncrease StrTableSize in hash.h and recompile hash.c\n");
+ *strp++ = *s++;
+ }
+ *strp++ = '\0';
+
+ return( start );
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.h
new file mode 100644
index 00000000..8295c2cd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/hash.h
@@ -0,0 +1,73 @@
+/*
+ * hash.h -- define hash table entries, sizes, hash function...
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+ /* H a s h T a b l e S t u f f */
+
+#ifndef HashTableSize
+#define HashTableSize 553
+#endif
+
+#ifndef StrTableSize
+#ifdef PC32
+#define StrTableSize 1000000
+#endif
+#endif
+
+#ifndef StrTableSize
+#ifdef PC
+#define StrTableSize 655200
+#endif
+#endif
+
+#ifndef StrTableSize
+#define StrTableSize 1000000
+#endif
+
+typedef struct _entry { /* Minimum hash table entry -- superclass */
+ char *str;
+ struct _entry *next;
+ } Entry;
+
+/* Hash 's' using 'size', place into h (s is modified) */
+#define Hash(s,h,size) \
+ {while ( *s != '\0' ) h = (h<<1) + *s++; \
+ h %= size;}
+
+#ifdef __USE_PROTOS
+Entry *hash_get(Entry **, char *),
+ **newHashTable(void),
+ *hash_add(Entry **, char *, Entry *);
+
+void killHashTable(Entry **);
+
+#else
+Entry *hash_get(), **newHashTable(), *hash_add();
+void killHashTable(); /* MR9 23-Sep-97 */
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/lex.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/lex.c
new file mode 100644
index 00000000..fbc91d1c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/lex.c
@@ -0,0 +1,878 @@
+/*
+ * lex.c -- Generate all of the lexical type files: parser.dlg tokens.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+/* MR1 */
+/* MR1 10-Apr-97 MR1 Replace use of __STDC__ with __USE_PROTOS */
+/* MR1 */
+#include "pcctscfg.h"
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+
+#define DLGErrorString "invalid token"
+
+/* Generate a complete lexical description of the lexemes found in the grammar */
+void
+#ifdef __USE_PROTOS
+genLexDescr( void )
+#else
+genLexDescr( )
+#endif
+{
+ ListNode *p;
+ FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");
+ require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(DlgFileName)); /* MR1 */
+#endif
+ fprintf(dlgFile, "<<\n");
+ fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName);
+ fprintf(dlgFile, " *\n");
+ fprintf(dlgFile, " * Generated from:");
+ {int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}
+ fprintf(dlgFile, "\n");
+ fprintf(dlgFile, " *\n");
+ fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(dlgFile, " * Purdue University Electrical Engineering\n");
+ fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");
+ fprintf(dlgFile, " * ANTLR Version %s\n", Version);
+ fprintf(dlgFile, " */\n\n");
+ if (FirstAction != NULL ) dumpAction( FirstAction, dlgFile, 0, -1, 0, 1 ); /* MR11 MR15b */
+ fprintf(dlgFile, "#define ANTLR_VERSION %s\n", VersionDef);
+ if ( GenCC )
+ {
+ if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
+ else fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
+ fprintf(dlgFile, "#include \"%s\"\n", ATOKEN_H);
+ if ( GenAST ) fprintf(dlgFile, "#include \"%s\"\n", ASTBASE_H);
+ if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
+ }
+ else
+ {
+ fprintf(dlgFile, "#include \"pcctscfg.h\"\n");
+ fprintf(dlgFile, "#include \"pccts_stdio.h\"\n");
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ fprintf(dlgFile, "#define %s %s\n", DefaultParserName, ParserName);
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ fprintf(dlgFile, "#include \"%s\"\n", RemapFileName);
+ if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
+ if ( FoundGuessBlk )
+ {
+ fprintf(dlgFile, "#define ZZCAN_GUESS\n");
+ fprintf(dlgFile, "#include \"pccts_setjmp.h\"\n");
+ }
+ if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);
+ if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");
+ if (TraceGen) {
+ fprintf(dlgFile,"#ifndef zzTRACE_RULES\n"); /* MR20 */
+ fprintf(dlgFile,"#define zzTRACE_RULES\n"); /* MR20 */
+ fprintf(dlgFile,"#endif\n"); /* MR22 */
+ };
+ fprintf(dlgFile, "#include \"antlr.h\"\n");
+ if ( GenAST ) {
+ fprintf(dlgFile, "#include \"ast.h\"\n");
+ }
+ if ( UserDefdTokens )
+ fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
+ /* still need this one as it has the func prototypes */
+ fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
+ fprintf(dlgFile, "#include \"dlgdef.h\"\n");
+ fprintf(dlgFile, "LOOKAHEAD\n");
+ fprintf(dlgFile, "\n");
+ fprintf(dlgFile, "void\n");
+ fprintf(dlgFile, "#ifdef __USE_PROTOS\n");
+ fprintf(dlgFile, "zzerraction(void)\n");
+ fprintf(dlgFile, "#else\n");
+ fprintf(dlgFile, "zzerraction()\n");
+ fprintf(dlgFile, "#endif\n");
+ fprintf(dlgFile, "{\n");
+ fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);
+ fprintf(dlgFile, "\tzzadvance();\n");
+ fprintf(dlgFile, "\tzzskip();\n");
+ fprintf(dlgFile, "}\n");
+ }
+ fprintf(dlgFile, ">>\n\n");
+
+ /* dump all actions */
+
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via <<%%lexmember ....>> & <<%%lexprefix ...>> */
+/* MR1 */
+ if (LexActions != NULL) {
+ for (p = LexActions->next; p!=NULL; p=p->next)
+ {
+/* MR1 */ fprintf(dlgFile, "<<%%%%lexaction\n");
+ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
+ fprintf(dlgFile, ">>\n\n");
+ }
+ };
+
+/* MR1 */ if (GenCC) {
+/* MR1 */ fprintf(dlgFile,"<<%%%%parserclass %s>>\n\n",CurrentClassName);
+/* MR1 */ };
+
+/* MR1 */ if (LexPrefixActions != NULL) {
+/* MR1 */ for (p = LexPrefixActions->next; p!=NULL; p=p->next)
+/* MR1 */ {
+/* MR1 */ fprintf(dlgFile, "<<%%%%lexprefix\n");
+/* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
+/* MR1 */ fprintf(dlgFile, ">>\n\n");
+/* MR1 */ }
+/* MR1 */ };
+
+/* MR1 */ if (LexMemberActions != NULL) {
+/* MR1 */ for (p = LexMemberActions->next; p!=NULL; p=p->next)
+/* MR1 */ {
+/* MR1 */ fprintf(dlgFile, "<<%%%%lexmember\n");
+/* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
+/* MR1 */ fprintf(dlgFile, ">>\n\n");
+/* MR1 */ }
+/* MR1 */ };
+
+ /* dump all regular expression rules/actions (skip sentinel node) */
+ if ( ExprOrder == NULL ) {
+ warnNoFL("no regular expressions found in grammar");
+ }
+ else dumpLexClasses(dlgFile);
+ fprintf(dlgFile, "%%%%\n");
+ fclose( dlgFile );
+}
+
+/* For each lexical class, scan ExprOrder looking for expressions
+ * in that lexical class. Print out only those that match.
+ * Each element of the ExprOrder list has both an expr and an lclass
+ * field.
+ */
+void
+#ifdef __USE_PROTOS
+dumpLexClasses( FILE *dlgFile )
+#else
+dumpLexClasses( dlgFile )
+FILE *dlgFile;
+#endif
+{
+ int i;
+ TermEntry *t;
+ ListNode *p;
+ Expr *q;
+
+ for (i=0; i<NumLexClasses; i++)
+ {
+ fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);
+ for (p=ExprOrder->next; p!=NULL; p=p->next)
+ {
+ q = (Expr *) p->elem;
+ if ( q->lclass != i ) continue;
+ lexmode(i);
+ t = (TermEntry *) hash_get(Texpr, q->expr);
+ require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
+ if ( t->token == EpToken ) continue;
+ fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));
+ /* replace " killed by StripQuotes() */
+ q->expr[ strlen(q->expr) ] = '"';
+ if ( !GenCC ) {
+ if ( TokenString(t->token) != NULL )
+ fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));
+ else
+ fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);
+ }
+ if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
+ if ( GenCC ) {
+ if ( TokenString(t->token) != NULL )
+ fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));
+ else
+ fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token);
+ }
+ fprintf(dlgFile, "\t>>\n\n");
+ }
+ }
+}
+
+/* Strip the leading path (if any) from a filename */
+char *
+#ifdef __USE_PROTOS
+StripPath( char *fileName )
+#else
+StripPath( fileName )
+char *fileName;
+#endif
+{
+ char *p;
+ static char dirSym[2] = DirectorySymbol;
+
+ if(NULL != (p = strrchr(fileName, dirSym[0])))
+ p++;
+ else
+ p = fileName;
+
+ return(p);
+}
+
+/* Generate a list of #defines && list of struct definitions for
+ * aggregate retv's */
+void
+#ifdef __USE_PROTOS
+genDefFile( void )
+#else
+genDefFile( )
+#endif
+{
+ int i;
+
+ /* If C++ mode and #tokdef used, then don't need anything in here since
+ * C++ puts all definitions in the class file name.
+ */
+ if ( GenCC && UserTokenDefsFile ) return;
+ if ( MR_Inhibit_Tokens_h_Gen) return;
+
+ DefFile = fopen(OutMetaName(DefFileName), "w");
+ require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(DefFileName)); /* MR1 */
+#endif
+ fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName)));
+ fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName)));
+
+ fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);
+ fprintf(DefFile, " *\n");
+ fprintf(DefFile, " * Generated from:");
+ for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
+ fprintf(DefFile, "\n");
+ fprintf(DefFile, " *\n");
+ fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(DefFile, " * Purdue University Electrical Engineering\n");
+ fprintf(DefFile, " * ANTLR Version %s\n", Version);
+ fprintf(DefFile, " */\n");
+
+ if ( !GenCC && LexGen ) {
+ fprintf(DefFile,"#define zzEOF_TOKEN %d\n",
+ TokenInd!=NULL?TokenInd[EofToken]:EofToken);
+ }
+
+ if ( !UserDefdTokens )
+ {
+ int first=1;
+
+ if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {\n");
+ for (i=1; i<TokenNum; i++)
+ {
+ /* Don't do EpToken or expr w/o labels */
+ if ( TokenString(i)!=NULL && i != EpToken )
+ {
+ TermEntry *p;
+
+ if ( WarningLevel>1 )
+ {
+ int j;
+ /* look in all lexclasses for the reg expr */
+
+/* MR10 Derek Pappas */
+/* MR10 A #tokclass doesn't have associated regular expressions */
+/* MR10 so don't warn user about it's omission */
+
+ p = (TermEntry *) hash_get(Tname, TokenString(i));
+
+ if (p != NULL && ! p->classname) {
+ for (j=0; j<NumLexClasses; j++)
+ {
+ lexmode(j);
+ if ( ExprString(i)!=NULL ) break;
+ }
+ if ( j>=NumLexClasses )
+ {
+ warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
+ }
+ };
+ }
+ require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
+ "token not in sym tab when it should be");
+ if ( !p->classname )
+ {
+ if ( GenCC ) {
+ if ( !first ) fprintf(DefFile, ",\n");
+ first = 0;
+ fprintf(DefFile, "\t%s=%d", TokenString(i), i);
+ }
+ else
+ fprintf(DefFile, "#define %s %d\n", TokenString(i), i);
+ }
+ }
+ }
+/* MR1 */
+/* MR1 10-Apr-97 133MR1 Prevent use of varying sizes of integer */
+/* MR1 for the enum ANTLRTokenType */
+/* MR1 */
+ if ( GenCC ) { /* MR1 */
+ if ( !first ) fprintf(DefFile, ",\n"); /* MR14 */
+ fprintf(DefFile, "\tDLGminToken=0"); /* MR1 */
+ fprintf(DefFile, ",\n\tDLGmaxToken=9999};\n"); /* MR1 */
+ }; /* MR1 */
+ }
+
+ if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
+
+ fprintf(DefFile, "\n#endif\n");
+}
+
+void
+#ifdef __USE_PROTOS
+GenRemapFile( void )
+#else
+GenRemapFile( )
+#endif
+{
+ if ( strcmp(ParserName, DefaultParserName)!=0 )
+ {
+ FILE *f;
+ int i;
+
+ f = fopen(OutMetaName(RemapFileName), "w");
+ require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(RemapFileName)); /* MR1 */
+#endif
+ fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);
+ fprintf(f, " *\n");
+ fprintf(f, " * Generated from:");
+ for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
+ fprintf(f, "\n");
+ fprintf(f, " *\n");
+ fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
+ fprintf(f, " * Purdue University Electrical Engineering\n");
+ fprintf(f, " * ANTLR Version %s\n", Version);
+ fprintf(f, " */\n");
+
+ GenRuleFuncRedefs(f, SynDiag);
+ GenPredefinedSymbolRedefs(f);
+ if ( GenAST ) GenASTSymbolRedefs(f);
+ GenSetRedefs(f);
+
+ fclose(f);
+ }
+}
+
+/* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
+void
+#ifdef __USE_PROTOS
+GenRuleFuncRedefs( FILE *f, Junction *p )
+#else
+GenRuleFuncRedefs( f, p )
+FILE *f;
+Junction *p;
+#endif
+{
+ fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");
+ while ( p!=NULL )
+ {
+ fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);
+ p = (Junction *)p->p2;
+ }
+}
+
+/* Generate a bunch of #defines that rename all standard symbols to be
+ * "ParserName_symbol". The list of standard symbols to change is in
+ * globals.c.
+ */
+void
+#ifdef __USE_PROTOS
+GenPredefinedSymbolRedefs( FILE *f )
+#else
+GenPredefinedSymbolRedefs( f )
+FILE *f;
+#endif
+{
+ char **p;
+
+ fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");
+ for (p = &StandardSymbols[0]; *p!=NULL; p++)
+ {
+ fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
+ }
+}
+
+/* Generate a bunch of #defines that rename all AST symbols to be
+ * "ParserName_symbol". The list of AST symbols to change is in
+ * globals.c.
+ */
+void
+#ifdef __USE_PROTOS
+GenASTSymbolRedefs( FILE *f )
+#else
+GenASTSymbolRedefs( f )
+FILE *f;
+#endif
+{
+ char **p;
+
+ fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");
+ for (p = &ASTSymbols[0]; *p!=NULL; p++)
+ {
+ fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
+ }
+}
+
+/* redefine all sets generated by ANTLR; WARNING: 'zzerr', 'setwd' must match
+ * use in bits.c (DumpSetWd() etc...)
+ */
+void
+#ifdef __USE_PROTOS
+GenSetRedefs( FILE *f )
+#else
+GenSetRedefs( f )
+FILE *f;
+#endif
+{
+ int i;
+
+ for (i=1; i<=wordnum; i++)
+ {
+ fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);
+ }
+ for (i=1; i<=esetnum; i++)
+ {
+ fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);
+ }
+}
+
+/* Find all return types/parameters that require structs and def
+ * all rules with ret types.
+ *
+ * This is for the declaration, not the definition.
+ */
+void
+#ifdef __USE_PROTOS
+GenRulePrototypes( FILE *f, Junction *p )
+#else
+GenRulePrototypes( f, p )
+FILE *f;
+Junction *p;
+#endif
+{
+ int i;
+
+ i = 1;
+ while ( p!=NULL )
+ {
+ if ( p->ret != NULL )
+ {
+/* MR23 */ if ( hasMultipleOperands(p->ret) )
+ {
+ DumpRetValStruct(f, p->ret, i);
+ }
+ fprintf(f, "\n#ifdef __USE_PROTOS\n");
+/* MR23 */ if ( hasMultipleOperands(p->ret) )
+ {
+ fprintf(f, "extern struct _rv%d", i);
+ }
+ else
+ {
+ fprintf(f, "extern ");
+ DumpType(p->ret, f);
+ }
+ fprintf(f, " %s%s(", RulePrefix, p->rname);
+ DumpANSIFunctionArgDef(f,p,1 /* emit initializers ? */);
+ fprintf(f, ";\n");
+ fprintf(f, "#else\n");
+/* MR23 */ if ( hasMultipleOperands(p->ret) )
+ {
+ fprintf(f, "extern struct _rv%d", i);
+ }
+ else
+ {
+ fprintf(f, "extern ");
+ DumpType(p->ret, f);
+ }
+ fprintf(f, " %s%s();\n", RulePrefix, p->rname);
+ fprintf(f, "#endif\n");
+ }
+ else
+ {
+ fprintf(f, "\n#ifdef __USE_PROTOS\n");
+ fprintf(f, "void %s%s(", RulePrefix, p->rname);
+ DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );
+ fprintf(f, ";\n");
+#ifdef OLD
+ if ( p->pdecl != NULL || GenAST )
+ {
+ if ( GenAST ) {
+ fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
+ }
+ if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+ }
+ else fprintf(f, "void");
+ fprintf(f, ");\n");
+#endif
+ fprintf(f, "#else\n");
+ fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);
+ fprintf(f, "#endif\n");
+ }
+ i++;
+ p = (Junction *)p->p2;
+ }
+}
+
+/* Define all rules in the class.h file; generate any required
+ * struct definitions first, however.
+ */
+void
+#ifdef __USE_PROTOS
+GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
+#else
+GenRuleMemberDeclarationsForCC( f, q )
+FILE *f;
+Junction *q;
+#endif
+{
+ Junction *p = q;
+ int i;
+
+ fprintf(f, "private:\n");
+
+ /* Dump dflt handler declaration */
+ fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");
+
+ fprintf(f, "public:\n");
+
+ /* Dump return value structs */
+ i = 1;
+ while ( p!=NULL )
+ {
+ if ( p->ret != NULL )
+ {
+/* MR23 */ if ( hasMultipleOperands(p->ret) )
+ {
+ DumpRetValStruct(f, p->ret, i);
+ }
+ }
+ i++;
+ p = (Junction *)p->p2;
+ }
+
+ /* Dump member func defs && CONSTRUCTOR */
+ fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);
+/*
+ fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n",
+ CurrentClassName);
+*/
+
+ i = 1;
+ p = q;
+ while ( p!=NULL )
+ {
+ if ( p->ret != NULL )
+ {
+/* MR23 */ if ( hasMultipleOperands(p->ret) )
+ {
+ fprintf(f, "\tstruct _rv%d", i);
+ }
+ else
+ {
+ fprintf(f, "\t");
+ DumpType(p->ret, f);
+ }
+ fprintf(f, " %s%s(",RulePrefix,p->rname);
+ DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );
+ fprintf(f, ";\n");
+#ifdef OLD
+ if ( p->pdecl != NULL || GenAST )
+ {
+ if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
+ if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+ }
+ fprintf(f, ");\n");
+#endif
+ }
+ else
+ {
+ fprintf(f, "\tvoid %s%s(",RulePrefix,p->rname);
+ DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */);
+ fprintf(f, ";\n");
+#ifdef OLD
+ if ( p->pdecl != NULL || GenAST )
+ {
+ if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
+ if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
+ }
+ fprintf(f, ");\n");
+#endif
+ }
+ i++;
+ p = (Junction *)p->p2;
+ }
+}
+
+/* Given a list of ANSI-style parameter declarations, print out a
+ * comma-separated list of the symbols (w/o types).
+ * Basically, we look for a comma, then work backwards until start of
+ * the symbol name. Then print it out until 1st non-alnum char. Now,
+ * move on to next parameter.
+ *
+ */
+
+/* MR5 Jan Mikkelsen 26-May-97 - added initialComma parameter */
+
+void
+#ifdef __USE_PROTOS
+DumpListOfParmNames(char *pdecl, FILE *output, int initialComma) /* MR5 */
+#else
+DumpListOfParmNames(pdecl, output, initialComma) /* MR5 */
+char *pdecl; /* MR5 */
+FILE *output; /* MR5 */
+int initialComma; /* MR5 */
+#endif
+{
+ int firstTime = 1, done = 0;
+ require(output!=NULL, "DumpListOfParmNames: NULL parm");
+
+ if ( pdecl == NULL ) return;
+ while ( !done )
+ {
+ if ( !firstTime || initialComma ) putc(',', output); /* MR5 */
+ done = DumpNextNameInDef(&pdecl, output);
+ firstTime = 0;
+ }
+}
+
+/* given a list of parameters or return values, dump the next
+ * name to output. Return 1 if last one just printed, 0 if more to go.
+ */
+
+/* MR23 Total rewrite */
+
+int
+#ifdef __USE_PROTOS
+DumpNextNameInDef( char **q, FILE *output )
+#else
+DumpNextNameInDef( q, output )
+char **q;
+FILE *output;
+#endif
+{
+ char *p;
+ char *t;
+ char *pDataType;
+ char *pSymbol;
+ char *pEqualSign;
+ char *pValue;
+ char *pSeparator;
+ int nest = 0;
+
+ p = endFormal(*q,
+ &pDataType,
+ &pSymbol,
+ &pEqualSign,
+ &pValue,
+ &pSeparator,
+ &nest);
+
+ /* MR26 Handle rule arguments such as: IIR_Bool (IIR_Decl::*constraint)()
+ For this we need to strip off anything which follows the symbol.
+ */
+
+/* MR26 */ t = pSymbol;
+/* MR26 */ if (t != NULL) {
+/* MR26 */ for (t = pSymbol; *t != 0; t++) {
+/* MR26 */ if (! (isalpha(*t) || isdigit(*t) || *t == '_' || *t == '$')) break;
+/* MR26 */ }
+/* MR26 */ }
+/* MR26 */ fprintf(output, "%s", strBetween(pSymbol, t, pSeparator));
+
+ *q = p;
+ return (*pSeparator == 0);
+}
+
+/* Given a list of ANSI-style parameter declarations, dump K&R-style
+ * declarations, one per line for each parameter. Basically, convert
+ * comma to semi-colon, newline.
+ */
+void
+#ifdef __USE_PROTOS
+DumpOldStyleParms( char *pdecl, FILE *output )
+#else
+DumpOldStyleParms( pdecl, output )
+char *pdecl;
+FILE *output;
+#endif
+{
+ require(output!=NULL, "DumpOldStyleParms: NULL parm");
+
+ if ( pdecl == NULL ) return;
+ while ( *pdecl != '\0' )
+ {
+ if ( *pdecl == ',' )
+ {
+ pdecl++;
+ putc(';', output); putc('\n', output);
+ while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
+ }
+ else {putc(*pdecl, output); pdecl++;}
+ }
+ putc(';', output);
+ putc('\n', output);
+}
+
+/* Take in a type definition (type + symbol) and print out type only */
+/* MR23 Total rewrite */
+
+void
+#ifdef __USE_PROTOS
+DumpType( char *s, FILE *f )
+#else
+DumpType( s, f )
+char *s;
+FILE *f;
+#endif
+{
+ char *p;
+ char *pDataType;
+ char *pSymbol;
+ char *pEqualSign;
+ char *pValue;
+ char *pSeparator;
+ int nest = 0;
+
+ require(s!=NULL, "DumpType: invalid type string");
+
+ p = endFormal(s,
+ &pDataType,
+ &pSymbol,
+ &pEqualSign,
+ &pValue,
+ &pSeparator,
+ &nest);
+ fprintf(f, "%s", strBetween(pDataType, pSymbol, pSeparator));
+}
+
+/* check to see if string e is a word in string s */
+int
+#ifdef __USE_PROTOS
+strmember( char *s, char *e )
+#else
+strmember( s, e )
+char *s;
+char *e;
+#endif
+{
+ register char *p;
+ require(s!=NULL&&e!=NULL, "strmember: NULL string");
+
+ if ( *e=='\0' ) return 1; /* empty string is always member */
+ do {
+ while ( *s!='\0' && !isalnum(*s) && *s!='_' )
+ ++s;
+ p = e;
+ while ( *p!='\0' && *p==*s ) {p++; s++;}
+ if ( *p=='\0' ) {
+ if ( *s=='\0' ) return 1;
+ if ( !isalnum (*s) && *s != '_' ) return 1;
+ }
+ while ( isalnum(*s) || *s == '_' )
+ ++s;
+ } while ( *s!='\0' );
+ return 0;
+}
+
+#if 0
+
+/* MR23 Replaced by hasMultipleOperands() */
+
+int
+#ifdef __USE_PROTOS
+HasComma( char *s )
+#else
+HasComma( s )
+char *s;
+#endif
+{
+ while (*s!='\0')
+ if ( *s++ == ',' ) return 1;
+ return 0;
+}
+#endif
+
+
+/* MR23 Total rewrite */
+
+void
+#ifdef __USE_PROTOS
+DumpRetValStruct( FILE *f, char *ret, int i )
+#else
+DumpRetValStruct( f, ret, i )
+FILE *f;
+char *ret;
+int i;
+#endif
+{
+ char *p = ret;
+ char *pDataType;
+ char *pSymbol;
+ char *pEqualSign;
+ char *pValue;
+ char *pSeparator;
+ int nest = 0;
+
+ fprintf(f, "\nstruct _rv%d {\n", i);
+ while (*p != 0 && nest == 0) {
+ p = endFormal(p,
+ &pDataType,
+ &pSymbol,
+ &pEqualSign,
+ &pValue,
+ &pSeparator,
+ &nest);
+ fprintf(f,"\t");
+ fprintf(f, "%s", strBetween(pDataType, pSymbol, pSeparator));
+ fprintf(f," ");
+ fprintf(f, "%s", strBetween(pSymbol, pEqualSign, pSeparator));
+ fprintf(f,";\n");
+ }
+ fprintf(f,"};\n");
+}
+
+/* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
+char *
+#ifdef __USE_PROTOS
+StripQuotes( char *s )
+#else
+StripQuotes( s )
+char *s;
+#endif
+{
+ if ( *s == '"' )
+ {
+ s[ strlen(s)-1 ] = '\0'; /* remove last quote */
+ return( s+1 ); /* return address past initial quote */
+ }
+ return( s );
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/main.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/main.c
new file mode 100644
index 00000000..bde0c831
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/main.c
@@ -0,0 +1,1747 @@
+/*
+ * main.c -- main program for PCCTS ANTLR.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+/* To set a breakpoint just before exit look for "cleanUp". */
+/* To set a breakpoint for fatal error look for "fatal_intern" */
+
+#include <stdio.h>
+
+#include "pcctscfg.h"
+#include "stdpccts.h"
+
+#define MAX_INT_STACK 50
+static int istack[MAX_INT_STACK]; /* Int stack */
+static int isp = MAX_INT_STACK;
+
+static int DontAcceptFiles = 0; /* if stdin, don't read files */
+static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */
+
+static int tnodes_used_in_guard_predicates_etc; /* MR10 */
+
+ /* C m d - L i n e O p t i o n S t r u c t & F u n c s */
+
+typedef struct _Opt {
+ char *option;
+ int arg;
+#ifdef __cplusplus
+ void (*process)(...);
+#else
+ void (*process)();
+#endif
+ char *descr;
+ } Opt;
+
+#ifdef __USE_PROTOS
+extern void ProcessArgs(int, char **, Opt *);
+#else
+extern void ProcessArgs();
+#endif
+
+#ifdef __USE_PROTOS
+int ci_strequ(char *a,char *b)
+#else
+int ci_strequ(a,b)
+ char *a;
+ char *b;
+#endif
+{
+ for ( ;*a != 0 && *b != 0; a++, b++) {
+ if (toupper(*a) != toupper(*b)) return 0;
+ }
+ return (*a == *b);
+}
+
+static void
+#ifdef __USE_PROTOS
+pStdin( void )
+#else
+pStdin( )
+#endif
+{
+ if ( DontAcceptStdin )
+ {
+ warnNoFL("'-' (stdin) ignored as files were specified first");
+ return;
+ }
+
+ require(NumFiles<MaxNumFiles,"exceeded max # of input files");
+ FileStr[NumFiles++] = "stdin";
+ DontAcceptFiles = 1;
+}
+
+static void
+#ifdef __USE_PROTOS
+pFile( char *s )
+#else
+pFile( s )
+char *s;
+#endif
+{
+ if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
+ if ( DontAcceptFiles )
+ {
+ warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
+ return;
+ }
+
+ require(NumFiles<MaxNumFiles,"exceeded max # of input files");
+ FileStr[NumFiles++] = s;
+ DontAcceptStdin = 1;
+}
+
+/* MR14
+ Allow input to be a file containing a list of files
+ Bernard Giroud (b_giroud@decus.ch)
+*/
+
+static void
+#ifdef __USE_PROTOS
+pFileList( char *s, char *t )
+#else
+pFileList( s, t )
+char *s;
+char *t;
+#endif
+{
+#define MaxFLArea 1024
+ FILE *fl;
+ static char Fn_in_Fl[MaxFLArea] = "";
+ char one_fn[MaxFileName];
+ char *flp = &Fn_in_Fl[0];
+ int fnl, left = MaxFLArea, i;
+
+ if ( *t=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",t) ); return; }
+ if ( DontAcceptFiles )
+ {
+ warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",t));
+ return;
+ }
+
+ if ((fl = fopen(t, "r")) == NULL)
+ {
+ warnNoFL(eMsg1("file '%s' can't be opened", t));
+ return;
+ }
+ for (;;)
+ {
+ if (fgets(one_fn, 128 - 1, fl) == NULL)
+ break;
+ fnl = strlen(one_fn);
+ require(fnl<=left, "no more room in File List Area");
+ /* drop the trailing LF */
+ if (one_fn[fnl - 1] == 0x0a) one_fn[fnl - 1] = ' ';
+ strcat(Fn_in_Fl, one_fn);
+ left = left - fnl;
+ require(NumFiles<MaxNumFiles,"exceeded max # of input files");
+ FileStr[NumFiles++] = flp;
+ flp = flp + fnl;
+ }
+ fclose(fl);
+ for (i=0;i < MaxFLArea;i++) if (Fn_in_Fl[i] == ' ') Fn_in_Fl[i] = '\0';
+ DontAcceptStdin = 1;
+}
+
+static void
+#ifdef __USE_PROTOS
+pLLK( char *s, char *t )
+#else
+pLLK( s, t )
+char *s;
+char *t;
+#endif
+{
+ LL_k = atoi(t);
+ if ( LL_k <= 0 ) {
+ warnNoFL("must have at least one token of lookahead (setting to 1)");
+ LL_k = 1;
+ }
+}
+
+static void
+#ifdef __USE_PROTOS
+pCk( char *s, char *t )
+#else
+pCk( s, t )
+char *s;
+char *t;
+#endif
+{
+ CLL_k = atoi(t);
+ if ( CLL_k <= 0 ) {
+ warnNoFL("must have at least one token of look-ahead (setting to 1)");
+ CLL_k = 1;
+ }
+}
+
+static void /* MR6 */
+#ifdef __USE_PROTOS
+pTab( char *s, char *t ) /* MR6 */
+#else
+pTab( s, t ) /* MR6 */
+char *s; /* MR6 */
+char *t; /* MR6 */
+#endif
+{ /* MR6 */
+ TabWidth = atoi(t); /* MR6 */
+ if ( TabWidth < 0 || TabWidth > 8 ) { /* MR6 */
+ warnNoFL("tab width must be between 1 and 8"); /* MR6 */
+ TabWidth=0; /* MR6 */
+ } /* MR6 */
+} /* MR6 */
+
+static int ambAidDepthSpecified=0; /* MR11 */
+
+static void /* MR11 */
+#ifdef __USE_PROTOS
+pAAd( char *s, char *t ) /* MR11 */
+#else
+pAAd( s, t ) /* MR11 */
+char *s; /* MR11 */
+char *t; /* MR11 */
+#endif
+{ /* MR11 */
+ ambAidDepthSpecified=1; /* MR11 */
+ MR_AmbAidDepth = atoi(t); /* MR11 */
+} /* MR11 */
+
+static void /* MR11 */
+#ifdef __USE_PROTOS
+pTreport( char *s, char *t ) /* MR11 */
+#else
+pTreport( s, t ) /* MR11 */
+ char *s; /* MR11 */
+ char *t; /* MR11 */
+#endif
+{ /* MR11 */
+ TnodesReportThreshold = atoi(t); /* MR11 */
+} /* MR11 */
+
+#ifdef __USE_PROTOS
+void chkGTFlag(void) /* 7-Apr-97 MR1 */
+#else
+void chkGTFlag() /* 7-Apr-97 MR1 */
+#endif
+{
+ if ( !GenAST )
+ warn("#-variable or other AST item referenced w/o -gt option");
+}
+
+
+#ifdef __USE_PROTOS
+static void pInfo(char *s, char *t) /* MR10 */
+#else
+static void pInfo(s,t) /* MR10 */
+ char *s;
+ char *t;
+#endif
+{
+ char *p;
+ int q;
+ for (p=t; *p != 0; p++) {
+ q=tolower(*p);
+ if (q=='t') {
+ InfoT=1;
+ } else if (q=='p') {
+ InfoP=1;
+ } else if (q=='m') {
+ InfoM=1;
+ } else if (q=='o') {
+ InfoO=1;
+ } else if (q=='0') {
+ ; /* nothing */
+ } else if (q=='f') {
+ InfoF=1;
+ } else {
+ warnNoFL(eMsgd("unrecognized -info option \"%c\"",(int)*p));
+ };
+ };
+}
+
+#ifdef __USE_PROTOS
+static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; }
+static void pLGen(void) { LexGen = FALSE; }
+static void pXTGen(void){ MR_Inhibit_Tokens_h_Gen = TRUE; }
+static void pTGen(void) { TraceGen = TRUE; }
+static void pSGen(void) { GenExprSetsOpt = FALSE; }
+static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); }
+static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
+static void pAst(void) { GenAST = TRUE; }
+static void pANSI(void) { GenANSI = TRUE; }
+static void pCr(void) { GenCR = TRUE; }
+static void pNOPURIFY(void) { PURIFY = FALSE; }
+/*static void pCt(void) { warnNoFL("-ct option is now the default"); }*/
+static void pLI(void) { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */
+static void pLIms(void) { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */
+static void pFr(char *s, char *t) {RemapFileName = t;}
+static void pFe(char *s, char *t) {ErrFileName = t;}
+static void pFl(char *s, char *t) {DlgFileName = t;}
+static void pFm(char *s, char *t) {ModeFileName = t;}
+static void pFt(char *s, char *t) {DefFileName = t;}
+
+static void pE1(void) { elevel = 1; }
+static void pE2(void) { elevel = 2; }
+static void pE3(void) { elevel = 3; }
+static void pEGen(void) { GenEClasseForRules = 1; }
+static void pDL(void)
+ {
+ DemandLookahead = 1;
+ if ( GenCC ) {
+ warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
+ DemandLookahead = 0;
+ }
+ }
+
+static void pAA(char *s,char *t) {MR_AmbAidRule = t;} /* MR11 */
+static void pAAm(char *s){MR_AmbAidMultiple = 1;} /* MR11 */
+static void pGHdr(void) { GenStdPccts = 1; }
+static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
+static void pW1(void) { WarningLevel = 1; }
+static void pNewAST(void) { NewAST = 1; } /* MR13 */
+static void ptmakeInParser(void) { tmakeInParser = 1; } /* MR23 */
+static void pAlpha(void) { AlphaBetaTrace = 1; } /* MR14 */
+static void pMR_BlkErr(void) { MR_BlkErr = 1; } /* MR21 */
+static void pStdout(void) {UseStdout = 1; } /* MR6 */
+static void pW2(void) { WarningLevel = 2; }
+static void pCC(void) { GenCC = TRUE; }
+#else
+static void pCGen() { CodeGen = FALSE; LexGen = FALSE; }
+static void pLGen() { LexGen = FALSE; }
+static void pXTGen(){ MR_Inhibit_Tokens_h_Gen = TRUE; } /* MR14 */
+static void pTGen() { TraceGen = TRUE; }
+static void pSGen() { GenExprSetsOpt = FALSE; }
+static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); }
+static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
+static void pAst() { GenAST = TRUE; }
+static void pANSI() { GenANSI = TRUE; }
+static void pCr() { GenCR = TRUE; }
+static void pNOPURIFY() { PURIFY = FALSE; }
+
+/*static void pCt() { warnNoFL("-ct option is now the default"); }*/
+static void pLI() { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */
+static void pLIms() { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */
+static void pFr(s,t) char *s, *t; {RemapFileName = t;}
+static void pFe(s,t) char *s, *t; {ErrFileName = t;}
+static void pFl(s,t) char *s, *t; {DlgFileName = t;}
+static void pFm(s,t) char *s, *t; {ModeFileName = t;}
+static void pFt(s,t) char *s, *t; {DefFileName = t;}
+
+static void pE1() { elevel = 1; }
+static void pE2() { elevel = 2; }
+static void pE3() { elevel = 3; }
+static void pEGen() { GenEClasseForRules = 1; }
+static void pDL()
+ {
+ DemandLookahead = 1;
+ if ( GenCC ) {
+ warnNoFL("-gk does not work currently in C++ mode; -gk turned off");
+ DemandLookahead = 0;
+ }
+ }
+
+static void pAA(s,t) char *s; char *t; {MR_AmbAidRule = t;} /* MR11 BJS 20-Mar-98 */
+static void pAAm(s) char *s; {MR_AmbAidMultiple = 1;} /* MR11 BJS 20-Mar-98 */
+static void pGHdr() { GenStdPccts = 1; }
+static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
+static void pW1() { WarningLevel = 1; }
+static void pNewAST() { NewAST = 1; } /* MR13 */
+static void ptmakeInParser() { tmakeInParser = 1; } /* MR23 */
+static void pAlpha() { AlphaBetaTrace = 1; } /* MR14 */
+static void pMR_BlkErr() { MR_BlkErr = 1; } /* MR21 */
+static void pStdout() {UseStdout = 1; } /* MR6 */
+static void pW2() { WarningLevel = 2; }
+static void pCC() { GenCC = TRUE; }
+#endif
+
+static void
+#ifdef __USE_PROTOS
+pPre( char *s, char *t )
+#else
+pPre( s, t )
+char *s;
+char *t;
+#endif
+{
+ RulePrefix = t;
+}
+
+static void
+#ifdef __USE_PROTOS
+pOut( char *s, char *t )
+#else
+pOut( s, t )
+char *s;
+char *t;
+#endif
+{
+ OutputDirectory = t;
+}
+
+static void
+#ifdef __USE_PROTOS
+pPred( void )
+#else
+pPred( )
+#endif
+{
+ warnNoFL("-pr is no longer used (predicates employed if present); see -prc, -mrhoist, -mrhoistk");
+/*
+** if ( DemandLookahead )
+** warnNoFL("-gk conflicts with -pr; -gk turned off");
+** DemandLookahead = 0;
+** HoistPredicateContext = 0;
+*/
+}
+
+static void
+#ifdef __USE_PROTOS
+pPredCtx( char *s, char *t )
+#else
+pPredCtx(s,t)
+char *s;
+char *t;
+#endif
+{
+ if ( ci_strequ(t,"on")) HoistPredicateContext = 1;
+ else if ( ci_strequ(t,"off")) HoistPredicateContext = 0;
+ if ( DemandLookahead )
+ {
+ warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
+ DemandLookahead = 0;
+ }
+}
+
+static void
+#ifdef __USE_PROTOS
+pMRhoist( char *s, char *t )
+#else
+pMRhoist(s,t)
+char *s;
+char *t;
+#endif
+{
+ if ( ci_strequ(t,"on")) MRhoisting = 1;
+ else if ( ci_strequ(t,"off")==0 ) MRhoisting = 0;
+ if (MRhoisting) {
+ fprintf(stderr,"Maintenance Release style hoisting enabled for predicates with lookahead depth = 1\n");
+ fprintf(stderr," No longer considered experimental\n");
+ fprintf(stderr," Can't consider suppression for predicates with lookahead depth > 1\n");
+ fprintf(stderr," Implies -prc on but does *not* imply -mrhoistk for k>1 predicates\n");
+ fprintf(stderr," This is a reminder, not a warning or error.\n");
+ };
+}
+
+static void
+#ifdef __USE_PROTOS
+pMRhoistk( char *s, char *t )
+#else
+pMRhoistk(s,t)
+char *s;
+char *t;
+#endif
+{
+ if ( ci_strequ(t,"on")) MRhoistingk = 1;
+ else if ( ci_strequ(t,"off")==0 ) MRhoistingk = 0;
+ if (MRhoistingk) {
+ fprintf(stderr,"EXPERIMENTAL Maintenance Release style hoisting enabled\n");
+ fprintf(stderr," Applies to predicates with lookahead depth > 1\n");
+ fprintf(stderr," Implies -prc on and -mrhoist on\n");
+ };
+}
+
+static void
+#ifdef __USE_PROTOS
+pTRes( char *s, char *t )
+#else
+pTRes( s, t )
+char *s;
+char *t;
+#endif
+{
+ TreeResourceLimit = atoi(t);
+ if ( TreeResourceLimit <= 0 )
+ {
+ warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
+ TreeResourceLimit = -1; /* set to no limit */
+ }
+}
+
+Opt options[] = {
+#ifdef __cplusplus
+ { "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"},
+ { "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"},
+ { "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"},
+ { "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"},
+ { "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"},
+ { "-e3", 0, (void (*)(...)) pE3,
+ "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},
+ { "-f", 1, (void (*)(...)) pFileList,"Read names of grammar files from specified file"}, /* MR14 */
+ { "-fe", 1, (void (*)(...)) pFe, "Rename err.c"},
+ { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"},
+ { "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"},
+ { "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"},
+ { "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"},
+ { "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"},
+ { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"},
+ { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"},
+ { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"},
+ { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
+ { "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
+ { "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches until needed"},
+ { "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in parser"},
+ { "-glms", 0, (void (*)(...)) pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"},
+ { "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"},
+ { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
+ { "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
+ { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
+ { "-gxt",0, (void (*)(...)) pXTGen, "Do not generate tokens.h (default=FALSE)"},
+ { "-k", 1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"},
+ { "-o", 1, (void (*)(...)) pOut, OutputDirectoryOption},
+ { "-p", 0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"},
+ { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
+ { "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"},
+ { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
+ { "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"},
+ { "-stdout",0, (void (*)(...)) pStdout,"Send grammar.c/grammar.cpp to stdout"}, /* MR6 */
+ { "-tab", 1, (void (*)(...)) pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */
+ { "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"},
+ { "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
+ { "-", 0, (void (*)(...)) pStdin, "Read grammar from stdin" },
+ { "-mrhoist",1, (void (*)(...)) pMRhoist, /* MR9 */
+ "Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */
+ { "-mrhoistk",1, (void (*)(...)) pMRhoistk, /* MR9 */
+ "Turn on/off EXPERIMENTAL k>1 Maintenance Release style hoisting"}, /* MR13 */
+ { "-aa" , 1, (void (*)(...)) pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */
+ { "-aam" , 0, (void (*)(...)) pAAm,
+ "Lookahead token may appear multiple times in -aa listing"}, /* MR11 */
+ { "-aad" , 1, (void (*)(...)) pAAd,
+ "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */
+ { "-info", 1, (void (*)(...)) pInfo,
+ "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR12 */
+ { "-treport",1,(void (*)(...)) pTreport,
+ "Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */
+ { "-newAST", 0, (void (*)(...)) pNewAST,
+ "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */
+ { "-tmake", 0, (void (*)(...)) ptmakeInParser,
+ "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */
+ { "-alpha",0,(void (*)(...)) pAlpha,
+ "Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */
+ { "-mrblkerr",0,(void (*)(...)) pMR_BlkErr, /* MR21 */
+ "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */
+ { "-nopurify",0,(void (*)(...)) pNOPURIFY,
+ "Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */
+ { "*", 0, (void (*)(...)) pFile, "" }, /* anything else is a file */
+#else
+ { "-CC", 0, pCC, "Generate C++ output (default=FALSE)"},
+ { "-cr", 0, pCr, "Generate cross reference (default=FALSE)"},
+ { "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"},
+ { "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"},
+ { "-e2", 0, pE2, "Ambiguities/errors shown in more detail"},
+ { "-e3", 0, pE3, "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"},
+ { "-f", 1, pFileList,"Read names of grammar files from specified file"}, /* MR14 */
+ { "-fe", 1, pFe, "Rename err.c"},
+ { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"},
+ { "-fl", 1, pFl, "Rename lexical output--parser.dlg"},
+ { "-fm", 1, pFm, "Rename mode.h"},
+ { "-fr", 1, pFr, "Rename remap.h"},
+ { "-ft", 1, pFt, "Rename tokens.h"},
+ { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"},
+ { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"},
+ { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"},
+ { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
+ { "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
+ { "-gk", 0, pDL, "Generate parsers that delay lookahead fetches until needed"},
+ { "-gl", 0, pLI, "Generate line info about grammar actions in C parser"},
+ { "-glms", 0, pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"},
+ { "-gp", 1, pPre, "Prefix all generated rule functions with a string"},
+ { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
+ { "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
+ { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
+ { "-gxt",0, pXTGen, "Do not generate tokens.h (default=FALSE)"},
+ { "-k", 1, pLLK, "Set full LL(k) lookahead depth (default==1)"},
+ { "-o", 1, pOut, OutputDirectoryOption},
+ { "-p", 0, pPrt, "Print out the grammar w/o actions (default=no)"},
+ { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
+ { "-pr",0, pPred, "no longer used; predicates employed if present"},
+ { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
+ { "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"},
+ { "-stdout",0, pStdout, "Send grammar.c/grammar.cpp to stdout"}, /* MR6 */
+ { "-tab", 1, pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */
+ { "-w1", 0, pW1, "Set the warning level to 1 (default)"},
+ { "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
+ { "-mrhoist",1,pMRhoist, /* MR9 */
+ "Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */
+ { "-mrhoistk",1,pMRhoistk, /* MR13 */
+ "Turn on/off k>1 EXPERIMENTAL Maintenance Release style hoisting"}, /* MR13 */
+ { "-aa" ,1,pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */
+ { "-aam" ,0,pAAm,
+ "Lookahead token may appear multiple times in -aa listing"}, /* MR11 */
+ { "-aad" ,1,pAAd,
+ "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */
+ { "-info",1,pInfo,
+ "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR11 */
+ { "-treport",1,pTreport,
+ "Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */
+ { "-newAST", 0, pNewAST,
+ "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */
+ { "-tmake", 0, ptmakeInParser,
+ "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */
+ { "-alpha",0, pAlpha,
+ "Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */
+ { "-mrblkerr",0,pMR_BlkErr, /* MR21 */
+ "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */
+ { "-nopurify",0,pNOPURIFY,
+ "Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */
+ { "-", 0, pStdin, "Read grammar from stdin" },
+ { "*", 0, pFile, "" }, /* anything else is a file */
+#endif
+ { NULL, 0, NULL }
+ };
+
+void readDescr();
+void cleanUp();
+
+#ifdef __USE_PROTOS
+static void buildRulePtr( void );
+static void help( void );
+static void init( void );
+static void CompleteTokenSetRefs( void );
+static void ensure_no_C_file_collisions(char *);
+static void CompleteContextGuards(void);
+#else
+static void buildRulePtr( );
+static void help( );
+static void init( );
+static void CompleteTokenSetRefs( );
+static void ensure_no_C_file_collisions();
+static void CompleteContextGuards();
+#endif
+
+static void
+#ifdef __USE_PROTOS /* <BJS> */
+report_numericPredLabels(ActionNode *a)
+#else
+report_numericPredLabels(a)
+ActionNode *a;
+#endif
+{ /* MR10 */
+ warnFL("numeric references to attributes (e.g. $i or $i.j) in semantic pred will be null during guess mode", /* MR10 */
+ FileStr[a->file],a->line); /* MR10 */
+} /* MR10 */
+
+ /* M a i n */
+
+int
+#ifdef __USE_PROTOS
+main( int argc, char *argv[] )
+#else
+main( argc, argv )
+int argc;
+char *argv[];
+#endif
+{
+ int i;
+ static char EPSTR[] = "[Ep]";
+
+ Save_argc=argc; /* MR10 */
+ Save_argv=argv; /* MR10 */
+
+/* malloc_debug(8);*/
+
+#ifdef SPECIAL_INITS
+ special_inits(); /* MR1 */
+#endif
+ fprintf(stderr, "Antlr parser generator Version %s 1989-2001\n", Version);
+ if ( argc == 1 ) { help(); zzDIE; }
+ ProcessArgs(argc-1, &(argv[1]), options);
+
+/* MR14 */ if (MR_AmbAidRule && AlphaBetaTrace) {
+/* MR14 */ fatal("Can't specify both -aa (ambiguity aid) and -alpha (\"(alpha)? beta\" aid)");
+/* MR14 */ }
+
+ if (MRhoistingk) { /* MR13 */
+ HoistPredicateContext=1; /* MR13 */
+ MRhoisting=1; /* MR13 */
+ }; /* MR13 */
+ if (MRhoisting && ! HoistPredicateContext) {
+/*** warnNoFL("Using \"-mrhoist\" forces \"-prc on\""); ***/
+ HoistPredicateContext=1;
+ };
+ if (HoistPredicateContext && ! MRhoisting) {
+ warnNoFL("When using predicate context (-prc on) -mrhoist on is recommended");
+ }
+ /* Fix lookahead depth */
+ /* Compressed lookahead must always be larger than or equal to full lookahead */
+ if ( CLL_k < LL_k && CLL_k>0 )
+ {
+ warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
+ CLL_k = LL_k;
+ }
+ if ( CLL_k == -1 ) CLL_k = LL_k;
+ OutputLL_k = CLL_k;
+ if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
+ int n;
+ for(n=1; n<CLL_k; n<<=1) {;}
+ OutputLL_k = n;
+ };
+
+ if (MR_BlkErr) {
+ warnNoFL("The -mrblkerr option is EXPERIMENTAL");
+ if (LL_k > 1) {
+ warnNoFL("The -mrblkerr option is designed only for k=1 ck=1 grammars");
+ }
+ };
+
+ if ( ! ambAidDepthSpecified) {
+ MR_AmbAidDepth=1;
+ } else {
+ if (MR_AmbAidDepth > CLL_k || MR_AmbAidDepth <= 0) {
+ warnNoFL(eMsgd(
+ "Ambiguity aid depth (\"-aad ...\") must be a number between 1 and max(k,ck)=%d",CLL_k));
+ MR_AmbAidDepth=1;
+ };
+ if (MR_AmbAidDepth == 0) {
+ MR_AmbAidDepth=2;
+ };
+ };
+
+ if (MR_AmbAidRule != NULL) MR_AmbAidLine=atoi(MR_AmbAidRule);
+
+ fpTrans = &(C_Trans[0]); /* Translate to C Language */
+ fpJTrans = &(C_JTrans[0]);
+ init();
+ lexclass(LexStartSymbol);
+
+ readDescr();
+ LastTokenCounted = TokenNum;
+ RemapForcedTokens();
+ if ( CannotContinue ) {cleanUp(); zzDIE;}
+ if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
+ if ( WarningLevel>1 && HdrAction == NULL )
+ warnNoFL("no #header action was found");
+ if ( FoundAtOperator && ! FoundExceptionGroup) {
+ warnNoFL("found the exception operator '@' - but no exception group was found");
+ };
+ EpToken = addTname(EPSTR); /* add imaginary token epsilon */
+ set_orel(EpToken, &imag_tokens);
+
+ /* this won't work for hand-built scanners since EofToken is not
+ * known. Forces EOF to be token type 1.
+ */
+ set_orel(EofToken, &imag_tokens);
+
+ set_size(NumWords(TokenNum-1));
+
+ /* compute the set of all known token types
+ * It represents the set of tokens from 1 to last_token_num + the
+ * reserved positions above that (if any). Don't include the set of
+ * imaginary tokens such as the token/error classes or EOF.
+ */
+ {
+ set a;
+ a = set_dup(reserved_positions);
+ for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
+ all_tokens = set_dif(a, imag_tokens);
+ set_free(a);
+ }
+
+ ComputeTokSets(); /* Compute #tokclass sets */
+ CompleteTokenSetRefs(); /* Change complex nodes in syn diag */
+ CompleteContextGuards(); /* MR13 */
+
+ if ( CodeGen ) genDefFile(); /* create tokens.h */
+ if ( LexGen ) genLexDescr(); /* create parser.dlg */
+
+ if ( GenStdPccts )
+ {
+ FILE *f = fopen(OutMetaName(stdpccts), "w");
+ if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
+ else
+ {
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(stdpccts)); /* MR1 */
+#endif
+ if (strcmp(stdpccts,"stdpccts.h") == 0) { /* MR10 */
+ genStdPCCTSIncludeFile(f,NULL); /* MR10 */
+ } else { /* MR10 */
+ genStdPCCTSIncludeFile(f,pcctsBaseName(stdpccts)); /* MR32 */
+ };
+ fclose(f);
+ }
+ }
+
+ buildRulePtr(); /* create mapping from rule # to RuleBlk junction */
+ ComputeErrorSets();
+ FoLink( (Node *)SynDiag ); /* add follow links to end of all rules */
+
+ if ( GenCR ) GenCrossRef( SynDiag );
+
+ if ( CodeGen )
+ {
+ if ( SynDiag == NULL )
+ {
+ warnNoFL("no grammar description recognized");
+ cleanUp();
+ zzDIE;
+ }
+ else if ( !GenCC ) {
+ ErrFile = fopen(OutMetaName(ErrFileName), "w");
+ require(ErrFile != NULL, "main: can't open err file");
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(ErrFileName)); /* MR1 */
+#endif
+ NewSetWd();
+ GenErrHdr();
+ TRANS(SynDiag); /* Translate to the target language */
+ DumpSetWd();
+ DumpRemainingTokSets();
+ fclose( ErrFile );
+ }
+ else {
+ strcpy(Parser_h_Name, CurrentClassName);
+ strcat(Parser_h_Name, ".h");
+ strcpy(Parser_c_Name, CurrentClassName);
+ strcat(Parser_c_Name, CPP_FILE_SUFFIX);
+ ensure_no_C_file_collisions(Parser_c_Name);
+ Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
+ require(Parser_h != NULL, "main: can't open class Parserx.h file");
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(Parser_h_Name)); /* MR1 */
+#endif
+ Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
+ require(Parser_c != NULL, "main: can't open class Parserx.c file");
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(Parser_c_Name)); /* MR1 */
+#endif
+ GenParser_h_Hdr();
+ if ( class_before_actions != NULL )
+ {
+ ListNode *p;
+ for (p = class_before_actions->next; p!=NULL; p=p->next)
+ {
+ UserAction *ua = (UserAction *)p->elem;
+ dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
+ }
+ }
+ GenParser_c_Hdr();
+ fprintf(Parser_h, "protected:\n"); /* MR20 */
+ NewSetWd();
+ TRANS(SynDiag); /* Translate to the target language */
+ DumpSetWd();
+ GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
+ if ( class_after_actions != NULL )
+ {
+ ListNode *p;
+ for (p = class_after_actions->next; p!=NULL; p=p->next)
+ {
+ UserAction *ua = (UserAction *)p->elem;
+ dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
+ }
+ }
+ DumpRemainingTokSets();
+ fprintf(Parser_h, "};\n");
+ fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName);
+ fclose( Parser_h );
+ fclose( Parser_c );
+ }
+ }
+
+ MR_orphanRules(stderr);
+ if (LTinTokenAction && WarningLevel >= 2) {
+ if (GenCC) {
+ warnNoFL("At least one <<action>> following a token match contains a reference to LT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates.");
+ }
+ warnNoFL("At least one <<action>> following a token match contains a reference to LA(...) or LATEXT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates.");
+ }
+
+ if ( PrintOut )
+ {
+ if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
+ else PRINT(SynDiag);
+ }
+
+#ifdef DBG_LL1
+#endif
+ GenRemapFile(); /* create remap.h */
+/* MR10 */ if (FoundGuessBlk) {
+#ifdef __cplusplus__
+/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);
+#else
+#ifdef __USE_PROTOS
+/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels);
+#else
+/* MR10 */ list_apply(NumericPredLabels,report_numericPredLabels);
+#endif
+#endif
+/* MR10 */ };
+
+ if (InfoT && TnodesAllocated > 0) {
+ if (TnodesPeak > 10000) {
+ fprintf(stdout,"\nTree Nodes: peak %dk created %dk lost %d\n",
+ (TnodesPeak/1000),
+ (TnodesAllocated/1000),
+ TnodesInUse-tnodes_used_in_guard_predicates_etc);
+ } else {
+ fprintf(stdout,"\nTree Nodes: peak %d created %d lost %d\n",
+ TnodesPeak,
+ TnodesAllocated,
+ TnodesInUse-tnodes_used_in_guard_predicates_etc);
+ };
+ };
+ if (InfoF) {
+ DumpFcache();
+ };
+ if (MR_skipped_e3_report) {
+ fprintf(stderr,"note: use -e3 to get exact information on ambiguous tuples\n");
+ };
+ if (MR_BadExprSets != 0) {
+ fprintf(stderr,"note: Unreachable C or C++ code was generated for empty expression sets,\n");
+ fprintf(stderr," probably due to undefined rules or infinite left recursion.\n");
+ fprintf(stderr," To locate: search the generated code for \"empty set expression\"\n");
+ };
+ if (MR_AmbAidRule != NULL && MR_matched_AmbAidRule==0) {
+ RuleEntry *q = (RuleEntry *) hash_get(Rname,MR_AmbAidRule);
+ if (MR_AmbAidLine == 0 && q == NULL) {
+ warnNoFL(eMsg2("there is no rule \"%s\" so \"-aa %s\" will never match",
+ MR_AmbAidRule,MR_AmbAidRule));
+ } else {
+ warnNoFL(eMsg1("there was no ambiguity that matched \"-aa %s\"",MR_AmbAidRule));
+ };
+ };
+ if (AlphaBetaTrace) {
+
+ if (MR_AlphaBetaMessageCount == 0) {
+ fprintf(stderr,"note: there were no messages about \"(alpha)? beta\" blocks added to the generated code\n");
+ } else {
+ fprintf(stderr,"note: there were %d messages about \"(alpha)? beta\" blocks added to the generated code\n",
+ MR_AlphaBetaMessageCount);
+ }
+
+ if (set_null(MR_CompromisedRules)) {
+ fprintf(stderr,"note: the list of rules with compromised follow sets is empty\n");
+ } else {
+ fprintf(stderr,"note: the following is a list of rules which *may* have incorrect\n");
+ fprintf(stderr," follow sets computed as a result of an \"(alpha)? beta\" block\n");
+ fprintf(stderr,"\n");
+ MR_dumpRuleSet(MR_CompromisedRules);
+ fprintf(stderr,"\n");
+ }
+ }
+ cleanUp();
+ exit(PCCTS_EXIT_SUCCESS);
+ return 0; /* MR11 make compilers happy */
+}
+
+static void
+#ifdef __USE_PROTOS
+init( void )
+#else
+init( )
+#endif
+{
+ SignalEntry *q;
+
+ Tname = newHashTable();
+ Rname = newHashTable();
+ Fcache = newHashTable();
+ Tcache = newHashTable();
+ Sname = newHashTable();
+ Pname = newHashTable(); /* MR11 */
+
+ /* Add default signal names */
+ q = (SignalEntry *)hash_add(Sname,
+ "NoViableAlt",
+ (Entry *)newSignalEntry("NoViableAlt"));
+ require(q!=NULL, "cannot alloc signal entry");
+ q->signum = sigNoViableAlt;
+ q = (SignalEntry *)hash_add(Sname,
+ "MismatchedToken",
+ (Entry *)newSignalEntry("MismatchedToken"));
+ require(q!=NULL, "cannot alloc signal entry");
+ q->signum = sigMismatchedToken;
+ q = (SignalEntry *)hash_add(Sname,
+ "NoSemViableAlt",
+ (Entry *)newSignalEntry("NoSemViableAlt"));
+ require(q!=NULL, "cannot alloc signal entry");
+ q->signum = sigNoSemViableAlt;
+
+ reserved_positions = empty;
+ all_tokens = empty;
+ imag_tokens = empty;
+ tokclasses = empty;
+ TokenStr = (char **) calloc(TSChunk, sizeof(char *));
+ require(TokenStr!=NULL, "main: cannot allocate TokenStr");
+ FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
+ require(FoStack!=NULL, "main: cannot allocate FoStack");
+ FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
+ require(FoTOS!=NULL, "main: cannot allocate FoTOS");
+ Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
+ require(Cycles!=NULL, "main: cannot allocate Cycles List");
+ MR_CompromisedRules=empty; /* MR14 */
+}
+
+static void
+#ifdef __USE_PROTOS
+help( void )
+#else
+help( )
+#endif
+{
+ Opt *p = options;
+ fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
+ while ( *(p->option) != '*' )
+ {
+ fprintf(stderr, " %-9s%s %s\n",
+ p->option,
+ (p->arg)?"___":" ",
+ p->descr);
+ p++;
+ }
+}
+
+/* The RulePtr array is filled in here. RulePtr exists primarily
+ * so that sets of rules can be maintained for the FOLLOW caching
+ * mechanism found in rJunc(). RulePtr maps a rule num from 1 to n
+ * to a pointer to its RuleBlk junction where n is the number of rules.
+ */
+static void
+#ifdef __USE_PROTOS
+buildRulePtr( void )
+#else
+buildRulePtr( )
+#endif
+{
+ int r=1;
+ Junction *p = SynDiag;
+ RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
+ require(RulePtr!=NULL, "cannot allocate RulePtr array");
+
+ while ( p!=NULL )
+ {
+ require(r<=NumRules, "too many rules???");
+ RulePtr[r++] = p;
+ p = (Junction *)p->p2;
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+dlgerror(const char *s)
+#else
+dlgerror(s)
+char *s;
+#endif
+{
+ fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+ fprintf(stderr, " lexical error: %s (text was '%s')\n",
+ ((s == NULL) ? "Lexical error" : s), zzlextext);
+}
+
+void
+#ifdef __USE_PROTOS
+readDescr( void )
+#else
+readDescr( )
+#endif
+{
+ zzerr = dlgerror;
+ input = NextFile();
+ if ( input==NULL ) fatal("No grammar description found (exiting...)");
+ ANTLR(grammar(), input);
+ tnodes_used_in_guard_predicates_etc=TnodesInUse; /* MR10 */
+}
+
+FILE *
+#ifdef __USE_PROTOS
+NextFile( void )
+#else
+NextFile( )
+#endif
+{
+ FILE *f;
+
+ for (;;)
+ {
+ CurFile++;
+ if ( CurFile >= NumFiles ) return(NULL);
+ if ( ci_strequ(FileStr[CurFile],"stdin")) return stdin;
+ f = fopen(FileStr[CurFile], "r");
+ if ( f == NULL )
+ {
+ warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
+ }
+ else
+ {
+ return(f);
+ }
+ }
+}
+
+/*
+ * Return a string corresponding to the output file name associated
+ * with the input file name passed in.
+ *
+ * Observe the following rules:
+ *
+ * f.e --> f".c"
+ * f --> f".c"
+ * f. --> f".c"
+ * f.e.g --> f.e".c"
+ *
+ * Where f,e,g are arbitrarily long sequences of characters in a file
+ * name.
+ *
+ * In other words, if a ".x" appears on the end of a file name, make it
+ * ".c". If no ".x" appears, append ".c" to the end of the file name.
+ *
+ * C++ mode using .cpp not .c.
+ *
+ * Use malloc() for new string.
+ */
+
+char *
+#ifdef __USE_PROTOS
+outname( char *fs )
+#else
+outname( fs )
+char *fs;
+#endif
+{
+ if ( GenCC) {
+ return outnameX(fs,CPP_FILE_SUFFIX);
+ } else {
+ return outnameX(fs,".c");
+ };
+}
+
+char *
+#ifdef __USE_PROTOS
+outnameX( char *fs ,char *suffix)
+#else
+outnameX( fs , suffix )
+char *fs;
+char *suffix;
+#endif
+{
+ static char buf[MaxFileName+1];
+ char *p;
+ require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
+
+ p = buf;
+ strcpy(buf, fs);
+ while ( *p != '\0' ) {p++;} /* Stop on '\0' */
+ while ( *p != '.' && p != buf ) {--p;} /* Find '.' */
+ if ( p != buf ) *p = '\0'; /* Found '.' */
+ require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");
+ strcat(buf,suffix);
+ return( buf );
+}
+
+void
+#ifdef __USE_PROTOS
+fatalFL( char *err_, char *f, int l )
+#else
+fatalFL( err_, f, l )
+char *err_;
+char *f;
+int l;
+#endif
+{
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " %s\n", err_);
+ cleanUp();
+ exit(PCCTS_EXIT_FAILURE);
+}
+
+void
+#ifdef __USE_PROTOS
+fatal_intern( char *err_, char *f, int l )
+#else
+fatal_intern( err_, f, l )
+char *err_;
+char *f;
+int l;
+#endif
+{
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " #$%%*&@# internal error: %s\n", err_);
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " [complain to nearest government official\n");
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " or send hate-mail to parrt@parr-research.com;\n");
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " please pray to the ``bug'' gods that there is a trival fix.]\n");
+ cleanUp();
+ exit(PCCTS_EXIT_FAILURE);
+}
+
+void
+#ifdef __USE_PROTOS
+cleanUp( void )
+#else
+cleanUp( )
+#endif
+{
+ if ( DefFile != NULL) fclose( DefFile );
+}
+
+/* sprintf up to 3 strings */
+char *
+#ifdef __USE_PROTOS
+eMsg3( char *s, char *a1, char *a2, char *a3 )
+#else
+eMsg3( s, a1, a2, a3 )
+char *s;
+char *a1;
+char *a2;
+char *a3;
+#endif
+{
+ static char buf[250]; /* DANGEROUS as hell !!!!!! */
+
+ sprintf(buf, s, a1, a2, a3);
+ return( buf );
+}
+
+/* sprintf a decimal */
+char *
+#ifdef __USE_PROTOS
+eMsgd( char *s, int d )
+#else
+eMsgd( s, d )
+char *s;
+int d;
+#endif
+{
+ static char buf[250]; /* DANGEROUS as hell !!!!!! */
+
+ sprintf(buf, s, d);
+ return( buf );
+}
+
+char *
+#ifdef __USE_PROTOS
+eMsgd2( char *s, int d1,int d2)
+#else
+eMsgd2( s, d1, d2 )
+char *s;
+int d1;
+int d2;
+#endif
+{
+ static char buf[250]; /* DANGEROUS as hell !!!!!! */
+
+ sprintf(buf, s, d1, d2);
+ return( buf );
+}
+
+void
+#ifdef __USE_PROTOS
+s_fprT( FILE *f, set e )
+#else
+s_fprT( f, e )
+FILE *f;
+set e;
+#endif
+{
+ register unsigned *p;
+ unsigned *q;
+
+ if ( set_nil(e) ) return;
+ if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
+ fprintf(f, "{");
+ while ( *p != nil )
+ {
+ fprintf(f, " %s", TerminalString(*p));
+ p++;
+ }
+ fprintf(f, " }");
+ free((char *)q);
+}
+
+/* Return the token name or regular expression for a token number. */
+char *
+#ifdef __USE_PROTOS
+TerminalString( int token )
+#else
+TerminalString( token )
+int token;
+#endif
+{
+ int j;
+ static char imag_name[20];
+
+ /* look in all lexclasses for the token */
+ if ( TokenString(token) != NULL ) return TokenString(token);
+ for (j=0; j<NumLexClasses; j++)
+ {
+ lexmode(j);
+ if ( ExprString(token) != NULL ) return ExprString(token);
+ }
+
+ if (1) {
+ sprintf(imag_name,"UnknownToken#%d",token); /* MR13 */
+ return imag_name; /* MR13 */
+ }
+
+ require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
+ return "invalid";
+}
+
+ /* S i m p l e I n t S t a c k */
+
+void
+#ifdef __USE_PROTOS
+pushint( int i )
+#else
+pushint( i )
+int i;
+#endif
+{
+ require(isp>0, "pushint: stack overflow");
+ istack[--isp] = i;
+}
+
+int
+#ifdef __USE_PROTOS
+popint( void )
+#else
+popint( )
+#endif
+{
+ require(isp<MAX_INT_STACK, "popint: stack underflow");
+ return istack[isp++];
+}
+
+int
+#ifdef __USE_PROTOS
+istacksize( void )
+#else
+istacksize( )
+#endif
+{
+ return MAX_INT_STACK-isp;
+}
+
+void
+#ifdef __USE_PROTOS
+istackreset( void )
+#else
+istackreset( )
+#endif
+{
+ isp = MAX_INT_STACK;
+}
+
+int
+#ifdef __USE_PROTOS
+istackempty( void )
+#else
+istackempty( )
+#endif
+{
+ return isp==MAX_INT_STACK;
+}
+
+int
+#ifdef __USE_PROTOS
+topint( void )
+#else
+topint( )
+#endif
+{
+ require(isp<MAX_INT_STACK, "topint: stack underflow");
+ return istack[isp];
+}
+
+void
+#ifdef __USE_PROTOS
+ProcessArgs( int argc, char **argv, Opt *options )
+#else
+ProcessArgs( argc, argv, options )
+int argc;
+char **argv;
+Opt *options;
+#endif
+{
+ Opt *p;
+ require(argv!=NULL, "ProcessArgs: command line NULL");
+
+ while ( argc-- > 0 )
+ {
+ p = options;
+ while ( p->option != NULL )
+ {
+ if ( strcmp(p->option, "*") == 0 ||
+ ci_strequ(p->option, *argv) == 1 )
+ {
+ if ( p->arg )
+ {
+/* MR9 26-Sep-97 Check for argv valid */
+ if (argc-- > 0) {
+ (*p->process)( *argv, *(argv+1) );
+ argv++;
+ } else {
+fprintf(stderr,"error: required argument for option %s omitted\n",*argv);
+exit(PCCTS_EXIT_FAILURE);
+ };
+ }
+ else
+ (*p->process)( *argv );
+ break;
+ }
+ p++;
+ }
+ argv++;
+ }
+}
+
+static void
+#ifdef __USE_PROTOS
+CompleteContextGuards(void)
+#else
+CompleteContextGuards()
+#endif
+{
+ ListNode * p;
+ Predicate * pred;
+
+ if (ContextGuardPredicateList == NULL) return;
+
+ for (p=ContextGuardPredicateList->next; p != NULL; p=p->next) {
+ pred=(Predicate *)p->elem;
+ recomputeContextGuard(pred);
+ }
+}
+
+/* Go back into the syntax diagram and compute all meta tokens; i.e.
+ * turn all '.', ranges, token class refs etc... into actual token sets
+ */
+static void
+#ifdef __USE_PROTOS
+CompleteTokenSetRefs(void)
+#else
+CompleteTokenSetRefs()
+#endif
+{
+ ListNode *p;
+
+ if ( MetaTokenNodes==NULL ) return;
+ for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
+ {
+ set a,b;
+
+ TokNode *q = (TokNode *)p->elem;
+ if ( q->wild_card )
+ {
+ q->tset = all_tokens;
+ }
+ else if ( q->tclass!=NULL )
+ {
+ if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
+ else q->tset = q->tclass->tset;
+ }
+ else if ( q->upper_range!=0 )
+ {
+ /* we have a range on our hands: make a set from q->token .. q->upper_range */
+ int i;
+ a = empty;
+ for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); } /* MR13 */
+
+/* MR13 */ if (q->complement) {
+/* MR13 */ q->tset = set_dif(all_tokens, a);
+/* MR13 */ set_free(a);
+/* MR13 */ } else {
+/* MR13 */ q->tset = a;
+/* MR13 */ }
+
+ }
+
+ /* at this point, it can only be a complemented single token */
+ else if ( q->complement )
+ {
+ a = set_of(q->token);
+ b = set_dif(all_tokens, a);
+ set_free(a);
+ q->tset=b;
+ }
+ else fatal("invalid meta token");
+ }
+}
+
+/* MR10: Jeff Vincent
+ MR10: Changed to remove directory information from n only if
+ MR10: if OutputDirectory was changed by user (-o option)
+*/
+
+char *
+#ifdef __USE_PROTOS
+OutMetaName(char *n)
+#else
+OutMetaName(n)
+char *n;
+#endif
+{
+ static char *dir_sym = DirectorySymbol;
+ static char newname[MaxFileName+1];
+ char *p;
+
+ /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */
+ if (strcmp(OutputDirectory, TopDirectory) == 0) /* TopDirectory is "." on Unix. */
+ return n;
+
+ /* p will point to filename without path information */
+ if ((p = strrchr(n, *dir_sym)) != NULL) /* Directory symbol is "/" on Unix. */
+ p++;
+ else
+ p = n;
+
+ /* Copy new output directory into newname[] */
+ strcpy(newname, OutputDirectory);
+
+ /* if new output directory does not have trailing dir_sym, add it! */
+ if (newname[strlen(newname)-1] != *dir_sym) {
+ strcat(newname, dir_sym);
+ }
+ strcat(newname, p);
+ return newname;
+}
+
+char *
+#ifdef __USE_PROTOS
+pcctsBaseName(char *n) /* MR32 */
+#else
+pcctsBaseName(n)
+char *n;
+#endif
+{
+ static char newname[MaxFileName+1];
+ static char* dir_sym = DirectorySymbol;
+ int count = 0;
+ char *p;
+
+ p = n;
+
+ while ( *p != '\0' ) {p++;} /* go to end of string */
+ while ( (*p != *dir_sym) && (p != n) ) {--p;} /* Find last DirectorySymbol */
+ while ( *p == *dir_sym) p++; /* step forward if we're on a dir symbol */
+ while ( *p != '\0' && *p != '.')
+ {
+ newname[count++] = *p;
+ p++;
+ } /* create a new name */
+ newname[count] = '\0';
+ return newname;
+}
+
+static void
+#ifdef __USE_PROTOS
+ensure_no_C_file_collisions(char *class_c_file)
+#else
+ensure_no_C_file_collisions(class_c_file)
+char *class_c_file;
+#endif
+{
+ int i;
+
+ for (i=0; i<NumFiles; i++)
+ {
+
+#ifdef PCCTS_CASE_INSENSITIVE_FILE_NAME
+ /* assume that file names are case insensitive */
+ if ( STRICMP(outname(FileStr[i]), class_c_file)==0 )
+#else
+ if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
+#endif
+ {
+ fatal(eMsg1("class def output file conflicts with parser output file: %s",
+ outname(FileStr[i])));
+ }
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+warnNoFL(char *err)
+#else
+warnNoFL(err)
+char *err;
+#endif
+{
+ fprintf(stderr, "warning: %s\n", err);
+}
+
+void
+#ifdef __USE_PROTOS
+warnFL(char *err,char *f,int l)
+#else
+warnFL(err,f,l)
+char *f;
+int l;
+char *err;
+#endif
+{
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " warning: %s\n", err);
+}
+
+void
+#ifdef __USE_PROTOS
+warn(char *err)
+#else
+warn(err)
+char *err;
+#endif
+{
+ /* back up the file number if we hit an error at the end of the last file */
+ if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+ fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+ fprintf(stderr, " warning: %s\n", err);
+}
+
+void
+#ifdef __USE_PROTOS
+warnNoCR( char *err )
+#else
+warnNoCR( err )
+char *err;
+#endif
+{
+ /* back up the file number if we hit an error at the end of the last file */
+ if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+ fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+ fprintf(stderr, " warning: %s", err);
+}
+
+void
+#ifdef __USE_PROTOS
+errNoFL(char *err)
+#else
+errNoFL(err)
+char *err;
+#endif
+{
+ fprintf(stderr, "error: %s\n", err);
+}
+
+void
+#ifdef __USE_PROTOS
+errFL(char *err,char *f,int l)
+#else
+errFL(err,f,l)
+char *err;
+char *f;
+int l;
+#endif
+{
+ fprintf(stderr, ErrHdr, f, l);
+ fprintf(stderr, " error: %s\n", err);
+}
+
+void
+#ifdef __USE_PROTOS
+err(char *err)
+#else
+err(err)
+char *err;
+#endif
+{
+ /* back up the file number if we hit an error at the end of the last file */
+ if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+ fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+ fprintf(stderr, " error: %s\n", err);
+}
+
+void
+#ifdef __USE_PROTOS
+errNoCR( char *err )
+#else
+errNoCR( err )
+char *err;
+#endif
+{
+ /* back up the file number if we hit an error at the end of the last file */
+ if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
+ fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
+ fprintf(stderr, " error: %s", err);
+}
+
+UserAction *
+#ifdef __USE_PROTOS
+newUserAction(char *s)
+#else
+newUserAction(s)
+char *s;
+#endif
+{
+ UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
+ require(ua!=NULL, "cannot allocate UserAction");
+
+ ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
+ strcpy(ua->action, s);
+ return ua;
+}
+
+/* Added by TJP September 1994 */
+/* Take in file.h and return file_h; names w/o '.'s are left alone */
+char *
+#ifdef __USE_PROTOS
+gate_symbol(char *name)
+#else
+gate_symbol(name)
+char *name;
+#endif
+{
+ static char buf[100];
+ char *p;
+ sprintf(buf, "%s", name);
+
+ for (p=buf; *p!='\0'; p++)
+ {
+ if ( *p=='.' ) *p = '_';
+ }
+ return buf;
+}
+
+char *
+#ifdef __USE_PROTOS
+makeAltID(int blockid, int altnum)
+#else
+makeAltID(blockid, altnum)
+int blockid;
+int altnum;
+#endif
+{
+ static char buf[100];
+ char *p;
+ sprintf(buf, "_blk%d_alt%d", blockid, altnum);
+ p = (char *)malloc(strlen(buf)+1);
+ strcpy(p, buf);
+ return p;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile
new file mode 100644
index 00000000..b5b4eb40
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile
@@ -0,0 +1,225 @@
+#
+# Makefile for ANTLR 1.33
+#
+# SOFTWARE RIGHTS
+#
+# We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+# Set (PCCTS) -- PCCTS is in the public domain. An individual or
+# company may do whatever they wish with source code distributed with
+# PCCTS or the code generated by PCCTS, including the incorporation of
+# PCCTS, or its output, into commerical software.
+#
+# We encourage users to develop software with PCCTS. However, we do ask
+# that credit is given to us for developing PCCTS. By "credit",
+# we mean that if you incorporate our source code into one of your
+# programs (commercial product, research project, or otherwise) that you
+# acknowledge this fact somewhere in the documentation, research report,
+# etc... If you like PCCTS and have developed a nice tool with the
+# output, please mention that you developed it using PCCTS. In
+# addition, we ask that this header remain intact in our source code.
+# As long as these guidelines are kept, we expect to continue enhancing
+# this system and expect to make other tools available as they are
+# completed.
+#
+# ANTLR 1.33
+# Terence Parr
+# Parr Research Corporation
+# with Purdue University
+# and AHPCRC, University of Minnesota
+# 1989-1995
+#
+# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by
+# Ed Harfmann
+# Micro Data Base Systems
+# Lafayette, Indiana
+#
+SET=../support/set
+PCCTS_H=../h
+
+##
+## Uncomment the appropriate section to build
+## (both targets and 'make' variable definitions)
+## Note that UNIX is the default
+##
+
+#
+# OS/2 & DOS 16 bit using MSC 6.0
+#
+#CC=cl
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN
+#OUT_OBJ = -Fo
+#LIBS=/NOD:LLIBCE LLIBCEP
+#OBJ_EXT = obj
+#
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egamn.obj
+# link @<<
+#$** /NOI
+#$@ /STACK:14336
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# bind $@ c:\os2\doscalls.lib
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for DOS
+#
+#CC=bcc
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= emu mathl cl
+#OBJ_EXT = obj
+#
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj
+# tlink @&&|
+#C0L $**
+#$@ /Tde /c
+#
+#$(LIBS)
+#$(DEF_FILE) $(LFLAGS) ;
+#|
+# copy *.exe ..\bin
+#
+
+#
+# C-Set/2 for OS/2
+#
+#CC=icc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__
+#OUT_OBJ = -Fo
+#LIBS=
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT = obj
+#
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj
+# link386 @<<
+#$** /NOI
+#$@ /STACK:32768
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for OS/2
+#
+#CC=bcc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= c2 os2
+#
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT = obj
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj
+# tlink @&&|
+#c02 $** -c -v
+#antlr.exe
+#
+#C2 os2
+#
+#|
+# copy *.exe ..\bin
+#
+
+# *********** Target list of PC machines ***********
+#
+# Don't worry about the ambiguity messages coming from antlr
+# for making antlr.c etc... [should be 10 of them, I think]
+#
+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g
+# $(ANTLR) antlr.g
+#
+#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h
+#
+#scan.$(OBJ_EXT): scan.c mode.h tokens.h
+#
+#scan.c mode.h: parser.dlg
+# $(DLG) -C2 parser.dlg scan.c
+#
+#set.$(OBJ_EXT): $(SET)/set.c
+# $(BUILD_CC) $(BUILD_CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c
+
+
+
+#
+# UNIX (default)
+#
+ifeq ($(CXX), llvm)
+BUILD_CC?=$(CLANG_BIN)clang
+else
+BUILD_CC?=gcc
+endif
+COPT=-O
+ANTLR=${BIN_DIR}/antlr
+DLG=${BIN_DIR}/dlg
+OBJ_EXT=o
+OUT_OBJ = -o
+BUILD_CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536
+BUILD_CPPFLAGS=
+#
+# SGI Users, use this CFLAGS
+#
+#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262
+OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \
+ globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o
+
+$(BIN_DIR)/antlr : $(OBJ) $(SRC)
+ $(BUILD_CC) $(BUILD_CFLAGS) -o $(BIN_DIR)/antlr $(OBJ)
+
+# what files does PCCTS generate (both ANTLR and DLG)
+PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h
+
+SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \
+ hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c
+
+#
+# Don't worry about the ambiguity messages coming from antlr
+# for making antlr.c etc... [should be 10 of them, I think]
+#
+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g
+# $(ANTLR) -gh antlr.g
+
+antlr.o : antlr.c mode.h tokens.h
+
+scan.o : scan.c mode.h tokens.h
+
+#scan.c mode.h: parser.dlg
+# $(DLG) -C2 parser.dlg scan.c
+
+set.o : $(SET)/set.c
+ $(BUILD_CC) $(BUILD_CFLAGS) -c -o set.o $(SET)/set.c
+
+%.o : %.c
+ $(BUILD_CC) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $< -o $@
+
+#
+# ****** These next targets are common to UNIX and PC world ********
+#
+
+#clean up all the intermediate files
+clean:
+ rm -f $(BIN_DIR)/antlr *.$(OBJ_EXT) core
+
+#remove everything in clean plus the PCCTS files generated
+scrub:
+ rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile.cygwin b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile.cygwin
new file mode 100644
index 00000000..3e9cb5a9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile.cygwin
@@ -0,0 +1,219 @@
+#
+# Makefile for ANTLR 1.33
+#
+# SOFTWARE RIGHTS
+#
+# We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+# Set (PCCTS) -- PCCTS is in the public domain. An individual or
+# company may do whatever they wish with source code distributed with
+# PCCTS or the code generated by PCCTS, including the incorporation of
+# PCCTS, or its output, into commerical software.
+#
+# We encourage users to develop software with PCCTS. However, we do ask
+# that credit is given to us for developing PCCTS. By "credit",
+# we mean that if you incorporate our source code into one of your
+# programs (commercial product, research project, or otherwise) that you
+# acknowledge this fact somewhere in the documentation, research report,
+# etc... If you like PCCTS and have developed a nice tool with the
+# output, please mention that you developed it using PCCTS. In
+# addition, we ask that this header remain intact in our source code.
+# As long as these guidelines are kept, we expect to continue enhancing
+# this system and expect to make other tools available as they are
+# completed.
+#
+# ANTLR 1.33
+# Terence Parr
+# Parr Research Corporation
+# with Purdue University
+# and AHPCRC, University of Minnesota
+# 1989-1995
+#
+# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by
+# Ed Harfmann
+# Micro Data Base Systems
+# Lafayette, Indiana
+#
+SET=../support/set
+PCCTS_H=../h
+
+##
+## Uncomment the appropriate section to build
+## (both targets and 'make' variable definitions)
+## Note that UNIX is the default
+##
+
+#
+# OS/2 & DOS 16 bit using MSC 6.0
+#
+#CC=cl
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN
+#OUT_OBJ = -Fo
+#LIBS=/NOD:LLIBCE LLIBCEP
+#OBJ_EXT = obj
+#
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egamn.obj
+# link @<<
+#$** /NOI
+#$@ /STACK:14336
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# bind $@ c:\os2\doscalls.lib
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for DOS
+#
+#CC=bcc
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= emu mathl cl
+#OBJ_EXT = obj
+#
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj
+# tlink @&&|
+#C0L $**
+#$@ /Tde /c
+#
+#$(LIBS)
+#$(DEF_FILE) $(LFLAGS) ;
+#|
+# copy *.exe ..\bin
+#
+
+#
+# C-Set/2 for OS/2
+#
+#CC=icc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__
+#OUT_OBJ = -Fo
+#LIBS=
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT = obj
+#
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj
+# link386 @<<
+#$** /NOI
+#$@ /STACK:32768
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for OS/2
+#
+#CC=bcc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= c2 os2
+#
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT = obj
+#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \
+# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \
+# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj
+# tlink @&&|
+#c02 $** -c -v
+#antlr.exe
+#
+#C2 os2
+#
+#|
+# copy *.exe ..\bin
+#
+
+# *********** Target list of PC machines ***********
+#
+# Don't worry about the ambiguity messages coming from antlr
+# for making antlr.c etc... [should be 10 of them, I think]
+#
+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g
+# $(ANTLR) antlr.g
+#
+#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h
+#
+#scan.$(OBJ_EXT): scan.c mode.h tokens.h
+#
+#scan.c mode.h: parser.dlg
+# $(DLG) -C2 parser.dlg scan.c
+#
+#set.$(OBJ_EXT): $(SET)/set.c
+# $(CC) $(CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c
+
+
+
+#
+# UNIX (default)
+#
+BIN_DIR=../../../../bin
+CC=gcc
+COPT=-O
+ANTLR=$(BIN_DIR)/antlr.exe
+DLG=${BIN_DIR}/dlg.exe
+OBJ_EXT=o
+OUT_OBJ = -o
+CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536
+#
+# SGI Users, use this CFLAGS
+#
+#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262
+OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \
+ globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o
+
+antlr : $(OBJ) $(SRC)
+ $(CC) $(CFLAGS) -o $(BIN_DIR)/antlr.exe $(OBJ)
+
+# what files does PCCTS generate (both ANTLR and DLG)
+PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h
+
+SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \
+ hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c
+
+#
+# Don't worry about the ambiguity messages coming from antlr
+# for making antlr.c etc... [should be 10 of them, I think]
+#
+#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g
+# $(ANTLR) -gh antlr.g
+
+antlr.o : antlr.c mode.h tokens.h
+
+scan.o : scan.c mode.h tokens.h
+
+#scan.c mode.h: parser.dlg
+# $(DLG) -C2 parser.dlg scan.c
+
+set.o : $(SET)/set.c
+ $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c
+
+
+#
+# ****** These next targets are common to UNIX and PC world ********
+#
+
+#clean up all the intermediate files
+clean:
+ rm -f *.$(OBJ_EXT) core
+
+#remove everything in clean plus the PCCTS files generated
+scrub:
+ rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile1 b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile1
new file mode 100644
index 00000000..f17a6927
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/makefile1
@@ -0,0 +1,96 @@
+#
+# Makefile for ANTLR 1.33
+#
+# SOFTWARE RIGHTS
+#
+# We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+# Set (PCCTS) -- PCCTS is in the public domain. An individual or
+# company may do whatever they wish with source code distributed with
+# PCCTS or the code generated by PCCTS, including the incorporation of
+# PCCTS, or its output, into commerical software.
+#
+# We encourage users to develop software with PCCTS. However, we do ask
+# that credit is given to us for developing PCCTS. By "credit",
+# we mean that if you incorporate our source code into one of your
+# programs (commercial product, research project, or otherwise) that you
+# acknowledge this fact somewhere in the documentation, research report,
+# etc... If you like PCCTS and have developed a nice tool with the
+# output, please mention that you developed it using PCCTS. In
+# addition, we ask that this header remain intact in our source code.
+# As long as these guidelines are kept, we expect to continue enhancing
+# this system and expect to make other tools available as they are
+# completed.
+#
+# ANTLR 1.33
+# Terence Parr
+# Parr Research Corporation
+# with Purdue University
+# and AHPCRC, University of Minnesota
+# 1989-1995
+#
+# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by
+# Ed Harfmann
+# Micro Data Base Systems
+# Lafayette, Indiana
+#
+SET=../support/set
+PCCTS_H=../h
+
+#
+# UNIX (default)
+#
+CC=cc
+ANTLR=${WORKSPACE}/Tools/bin/antlr
+DLG=${WORKSPACE}/Tools/bin/dlg
+OBJ_EXT=o
+OUT_OBJ = -o
+ANSI=-ansi
+AOTHER=
+CFLAGS= -O0 -g -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) $(ANSI) -DZZLEXBUFSIZE=32000
+#
+# SGI Users, use this CFLAGS
+#
+#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262
+
+OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \
+ globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o $(OBJOTHER)
+
+antlr : $(OBJ) $(SRC)
+ $(CC) $(CFLAGS) -o antlr $(OBJ)
+ mv antlr ${WORKSPACE}/Tools/bin
+
+# what files does PCCTS generate (both ANTLR and DLG)
+PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h
+
+SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \
+ hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c
+
+#
+# Don't worry about the ambiguity messages coming from antlr
+# for making antlr.c etc... [should be 10 of them, I think]
+#
+antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g
+ $(ANTLR) -gh antlr.g $(AOTHER)
+
+antlr.o : antlr.c mode.h tokens.h
+
+scan.o : scan.c mode.h tokens.h
+
+scan.c mode.h: parser.dlg
+ $(DLG) -C2 parser.dlg scan.c
+
+set.o : $(SET)/set.c
+ $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c
+
+
+#
+# ****** These next targets are common to UNIX and PC world ********
+#
+
+#clean up all the intermediate files
+clean:
+ rm -f *.$(OBJ_EXT) core
+
+#remove everything in clean plus the PCCTS files generated
+scrub:
+ rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/misc.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/misc.c
new file mode 100644
index 00000000..eef73e64
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/misc.c
@@ -0,0 +1,1864 @@
+/*
+ * misc.c
+ *
+ * Manage tokens, regular expressions.
+ * Print methods for debugging
+ * Compute follow lists onto tail ends of rules.
+ *
+ * The following functions are visible:
+ *
+ * int addTname(char *); Add token name
+ * int addTexpr(char *); Add token expression
+ * int Tnum(char *); Get number of expr/token
+ * void Tklink(char *, char *); Link a name with an expression
+ * int hasAction(expr); Does expr already have action assigned?
+ * void setHasAction(expr); Indicate that expr now has an action
+ * Entry *newEntry(char *,int); Create new table entry with certain size
+ * void list_add(ListNode **list, char *e)
+ * void list_free(ListNode **list, int freeData); *** MR10 ***
+ * void list_apply(ListNode *list, void (*f)())
+ * void lexclass(char *m); switch to new/old lexical class
+ * void lexmode(int i); switch to old lexical class i
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "pcctscfg.h"
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+#include <ctype.h>
+
+static int tsize=TSChunk; /* size of token str arrays */
+
+static void
+#ifdef __USE_PROTOS
+RemapForcedTokensInSyntaxDiagram(Node *);
+#else
+RemapForcedTokensInSyntaxDiagram();
+#endif
+
+ /* T o k e n M a n i p u l a t i o n */
+
+/*
+ * add token 't' to the TokenStr/Expr array. Make more room if necessary.
+ * 't' is either an expression or a token name.
+ *
+ * There is only one TokenStr array, but multiple ExprStr's. Therefore,
+ * for each lex class (element of lclass) we must extend the ExprStr array.
+ * ExprStr's and TokenStr are always all the same size.
+ *
+ * Also, there is a Texpr hash table for each automaton.
+ */
+static void
+#ifdef __USE_PROTOS
+Ttrack( char *t )
+#else
+Ttrack( t )
+char *t;
+#endif
+{
+ if ( TokenNum >= tsize ) /* terminal table overflow? */
+ {
+ char **p;
+ int i, more, j;
+
+ more = TSChunk * (1 + ((TokenNum-tsize) / TSChunk));
+ tsize += more;
+ TokenStr = (char **) realloc((char *)TokenStr, tsize*sizeof(char *));
+ require(TokenStr != NULL, "Ttrack: can't extend TokenStr");
+ for (i=0; i<NumLexClasses; i++)
+ {
+ lclass[i].exprs = (char **)
+ realloc((char *)lclass[i].exprs, tsize*sizeof(char *));
+ require(lclass[i].exprs != NULL, "Ttrack: can't extend ExprStr");
+ for (p= &lclass[i].exprs[tsize-more],j=1; j<=more; j++) *p++ = NULL;
+ }
+ for (p= &TokenStr[tsize-more],i=1; i<=more; i++) *p++ = NULL;
+ lexmode( CurrentLexClass ); /* reset ExprStr in case table moved */
+ }
+ /* note: we use the actual ExprStr/TokenStr array
+ * here as TokenInd doesn't exist yet
+ */
+ if ( *t == '"' ) ExprStr[TokenNum] = t;
+ else TokenStr[TokenNum] = t;
+}
+
+static Expr *
+#ifdef __USE_PROTOS
+newExpr( char *e )
+#else
+newExpr( e )
+char *e;
+#endif
+{
+ Expr *p = (Expr *) calloc(1, sizeof(Expr));
+ require(p!=NULL, "newExpr: cannot alloc Expr node");
+
+ p->expr = e;
+ p->lclass = CurrentLexClass;
+ return p;
+}
+
+/* switch to lexical class/mode m. This amounts to creating a new
+ * lex mode if one does not already exist and making ExprStr point
+ * to the correct char string array. We must also switch Texpr tables.
+ *
+ * BTW, we need multiple ExprStr arrays because more than one automaton
+ * may have the same label for a token, but with different expressions.
+ * We need to track an expr for each automaton. If we disallowed this
+ * feature, only one ExprStr would be required.
+ */
+void
+#ifdef __USE_PROTOS
+lexclass( char *m )
+#else
+lexclass( m )
+char *m;
+#endif
+{
+ int i;
+ TermEntry *p;
+ static char EOFSTR[] = "\"@\"";
+
+ if ( hash_get(Tname, m) != NULL )
+ {
+ warn(eMsg1("lexclass name conflicts with token/errclass label '%s'",m));
+ }
+ /* does m already exist? */
+ i = LexClassIndex(m);
+ if ( i != -1 ) {lexmode(i); return;}
+ /* must make new one */
+ NumLexClasses++;
+ CurrentLexClass = NumLexClasses-1;
+ require(NumLexClasses<=MaxLexClasses, "number of allowable lexclasses exceeded\nIncrease MaxLexClasses in generic.h and recompile all C files");
+ lclass[CurrentLexClass].classnum = m;
+ lclass[CurrentLexClass].exprs = (char **) calloc(tsize, sizeof(char *));
+ require(lclass[CurrentLexClass].exprs!=NULL,
+ "lexclass: cannot allocate ExprStr");
+ lclass[CurrentLexClass].htable = newHashTable();
+ ExprStr = lclass[CurrentLexClass].exprs;
+ Texpr = lclass[CurrentLexClass].htable;
+ /* define EOF for each automaton */
+ p = newTermEntry( EOFSTR );
+ p->token = EofToken; /* couldn't have remapped tokens yet, use EofToken */
+ hash_add(Texpr, EOFSTR, (Entry *)p);
+ list_add(&ExprOrder, (void *)newExpr(EOFSTR));
+ /* note: we use the actual ExprStr array
+ * here as TokenInd doesn't exist yet
+ */
+ ExprStr[EofToken] = EOFSTR;
+}
+
+void
+#ifdef __USE_PROTOS
+lexmode( int i )
+#else
+lexmode( i )
+int i;
+#endif
+{
+ require(i<NumLexClasses, "lexmode: invalid mode");
+ ExprStr = lclass[i].exprs;
+ Texpr = lclass[i].htable;
+ CurrentLexClass = i;
+}
+
+/* return index into lclass array of lexical class. return -1 if nonexistent */
+int
+#ifdef __USE_PROTOS
+LexClassIndex( char *cl )
+#else
+LexClassIndex( cl )
+char *cl;
+#endif
+{
+ int i;
+
+ for (i=0; i<NumLexClasses; i++)
+ {
+ if ( strcmp(lclass[i].classnum, cl) == 0 ) return i;
+ }
+ return -1;
+}
+
+int
+#ifdef __USE_PROTOS
+hasAction( char *expr )
+#else
+hasAction( expr )
+char *expr;
+#endif
+{
+ TermEntry *p;
+ require(expr!=NULL, "hasAction: invalid expr");
+
+ p = (TermEntry *) hash_get(Texpr, expr);
+ require(p!=NULL, eMsg1("hasAction: expr '%s' doesn't exist",expr));
+ return (p->action!=NULL);
+}
+
+void
+#ifdef __USE_PROTOS
+setHasAction( char *expr, char *action )
+#else
+setHasAction( expr, action )
+char *expr;
+char *action;
+#endif
+{
+ TermEntry *p;
+ require(expr!=NULL, "setHasAction: invalid expr");
+
+ p = (TermEntry *) hash_get(Texpr, expr);
+ require(p!=NULL, eMsg1("setHasAction: expr '%s' doesn't exist",expr));
+ p->action = action;
+}
+
+ForcedToken *
+#ifdef __USE_PROTOS
+newForcedToken(char *token, int tnum)
+#else
+newForcedToken(token, tnum)
+char *token;
+int tnum;
+#endif
+{
+ ForcedToken *ft = (ForcedToken *) calloc(1, sizeof(ForcedToken));
+ require(ft!=NULL, "out of memory");
+ ft->token = token;
+ ft->tnum = tnum;
+ return ft;
+}
+
+/*
+ * Make a token indirection array that remaps token numbers and then walk
+ * the appropriate symbol tables and SynDiag to change token numbers
+ */
+void
+#ifdef __USE_PROTOS
+RemapForcedTokens(void)
+#else
+RemapForcedTokens()
+#endif
+{
+ ListNode *p;
+ ForcedToken *q;
+ int max_token_number=0; /* MR9 23-Sep-97 Removed "unsigned" */
+ int i;
+
+ if ( ForcedTokens == NULL ) return;
+
+ /* find max token num */
+ for (p = ForcedTokens->next; p!=NULL; p=p->next)
+ {
+ q = (ForcedToken *) p->elem;
+ if ( q->tnum > max_token_number ) max_token_number = q->tnum;
+ }
+ fprintf(stderr, "max token number is %d\n", max_token_number);
+
+ /* make token indirection array */
+ TokenInd = (int *) calloc(max_token_number+1, sizeof(int));
+ LastTokenCounted = TokenNum;
+ TokenNum = max_token_number+1;
+ require(TokenInd!=NULL, "RemapForcedTokens: cannot allocate TokenInd");
+
+ /* fill token indirection array and change token id htable ; swap token indices */
+ for (i=1; i<TokenNum; i++) TokenInd[i] = i;
+ for (p = ForcedTokens->next; p!=NULL; p=p->next)
+ {
+ TermEntry *te;
+ int old_pos, t;
+
+ q = (ForcedToken *) p->elem;
+ fprintf(stderr, "%s forced to %d\n", q->token, q->tnum);
+ te = (TermEntry *) hash_get(Tname, q->token);
+ require(te!=NULL, "RemapForcedTokens: token not in hash table");
+ old_pos = te->token;
+ fprintf(stderr, "Before: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);
+ fprintf(stderr, "Before: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);
+ q = (ForcedToken *) p->elem;
+ t = TokenInd[old_pos];
+ TokenInd[old_pos] = q->tnum;
+ TokenInd[q->tnum] = t;
+ te->token = q->tnum; /* update token type id symbol table */
+ fprintf(stderr, "After: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]);
+ fprintf(stderr, "After: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]);
+
+ /* Change the token number in the sym tab entry for the exprs
+ * at the old position of the token id and the target position
+ */
+ /* update expr at target (if any) of forced token id */
+ if ( q->tnum < TokenNum ) /* is it a valid position? */
+ {
+ for (i=0; i<NumLexClasses; i++)
+ {
+ if ( lclass[i].exprs[q->tnum]!=NULL )
+ {
+ /* update the symbol table for this expr */
+ TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[q->tnum]);
+ require(e!=NULL, "RemapForcedTokens: expr not in hash table");
+ e->token = old_pos;
+ fprintf(stderr, "found expr '%s' at target %d in lclass[%d]; changed to %d\n",
+ lclass[i].exprs[q->tnum], q->tnum, i, old_pos);
+ }
+ }
+ }
+ /* update expr at old position (if any) of forced token id */
+ for (i=0; i<NumLexClasses; i++)
+ {
+ if ( lclass[i].exprs[old_pos]!=NULL )
+ {
+ /* update the symbol table for this expr */
+ TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[old_pos]);
+ require(e!=NULL, "RemapForcedTokens: expr not in hash table");
+ e->token = q->tnum;
+ fprintf(stderr, "found expr '%s' for id %s in lclass[%d]; changed to %d\n",
+ lclass[i].exprs[old_pos], q->token, i, q->tnum);
+ }
+ }
+ }
+
+ /* Update SynDiag */
+ RemapForcedTokensInSyntaxDiagram((Node *)SynDiag);
+}
+
+static void
+#ifdef __USE_PROTOS
+RemapForcedTokensInSyntaxDiagram(Node *p)
+#else
+RemapForcedTokensInSyntaxDiagram(p)
+Node *p;
+#endif
+{
+ Junction *j = (Junction *) p;
+ RuleRefNode *r = (RuleRefNode *) p;
+ TokNode *t = (TokNode *)p;
+
+ if ( p==NULL ) return;
+ require(p->ntype>=1 && p->ntype<=NumNodeTypes, "Remap...: invalid diagram node");
+ switch ( p->ntype )
+ {
+ case nJunction :
+ if ( j->visited ) return;
+ if ( j->jtype == EndRule ) return;
+ j->visited = TRUE;
+ RemapForcedTokensInSyntaxDiagram( j->p1 );
+ RemapForcedTokensInSyntaxDiagram( j->p2 );
+ j->visited = FALSE;
+ return;
+ case nRuleRef :
+ RemapForcedTokensInSyntaxDiagram( r->next );
+ return;
+ case nToken :
+ if ( t->remapped ) return; /* we've been here before */
+ t->remapped = 1;
+ fprintf(stderr, "remapping %d to %d\n", t->token, TokenInd[t->token]);
+ t->token = TokenInd[t->token];
+ RemapForcedTokensInSyntaxDiagram( t->next );
+ return;
+ case nAction :
+ RemapForcedTokensInSyntaxDiagram( ((ActionNode *)p)->next );
+ return;
+ default :
+ fatal_internal("invalid node type");
+ }
+}
+
+/*
+ * Add a token name. Return the token number associated with it. If it already
+ * exists, then return the token number assigned to it.
+ *
+ * Track the order in which tokens are found so that the DLG output maintains
+ * that order. It also lets us map token numbers to strings.
+ */
+int
+#ifdef __USE_PROTOS
+addTname( char *token )
+#else
+addTname( token )
+char *token;
+#endif
+{
+ TermEntry *p;
+ require(token!=NULL, "addTname: invalid token name");
+
+ if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;
+ p = newTermEntry( token );
+ Ttrack( p->str );
+ p->token = TokenNum++;
+ hash_add(Tname, token, (Entry *)p);
+ return p->token;
+}
+
+/* This is the same as addTname except we force the TokenNum to be tnum.
+ * We don't have to use the Forced token stuff as no tokens will have
+ * been defined with #tokens when this is called. This is only called
+ * when a #tokdefs meta-op is used.
+ */
+int
+#ifdef __USE_PROTOS
+addForcedTname( char *token, int tnum )
+#else
+addForcedTname( token, tnum )
+char *token;
+int tnum;
+#endif
+{
+ TermEntry *p;
+ require(token!=NULL, "addTname: invalid token name");
+
+ if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token;
+ p = newTermEntry( token );
+ Ttrack( p->str );
+ p->token = tnum;
+ hash_add(Tname, token, (Entry *)p);
+ return p->token;
+}
+
+/*
+ * Add a token expr. Return the token number associated with it. If it already
+ * exists, then return the token number assigned to it.
+ */
+int
+#ifdef __USE_PROTOS
+addTexpr( char *expr )
+#else
+addTexpr( expr )
+char *expr;
+#endif
+{
+ TermEntry *p;
+ require(expr!=NULL, "addTexpr: invalid regular expression");
+
+ if ( (p=(TermEntry *)hash_get(Texpr, expr)) != NULL ) return p->token;
+ p = newTermEntry( expr );
+ Ttrack( p->str );
+ /* track the order in which they occur */
+ list_add(&ExprOrder, (void *)newExpr(p->str));
+ p->token = TokenNum++;
+ hash_add(Texpr, expr, (Entry *)p);
+ return p->token;
+}
+
+/* return the token number of 'term'. Return 0 if no 'term' exists */
+int
+#ifdef __USE_PROTOS
+Tnum( char *term )
+#else
+Tnum( term )
+char *term;
+#endif
+{
+ TermEntry *p;
+ require(term!=NULL, "Tnum: invalid terminal");
+
+ if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term);
+ else p = (TermEntry *) hash_get(Tname, term);
+ if ( p == NULL ) return 0;
+ else return p->token;
+}
+
+/* associate a Name with an expr. If both have been already assigned
+ * token numbers, then an error is reported. Add the token or expr
+ * that has not been added if no error. This 'represents' the #token
+ * ANTLR pseudo-op. If both have not been defined, define them both
+ * linked to same token number.
+ */
+void
+#ifdef __USE_PROTOS
+Tklink( char *token, char *expr )
+#else
+Tklink( token, expr )
+char *token;
+char *expr;
+#endif
+{
+ TermEntry *p, *q;
+ require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr");
+
+ p = (TermEntry *) hash_get(Tname, token);
+ q = (TermEntry *) hash_get(Texpr, expr);
+ if ( p != NULL && q != NULL ) /* both defined */
+ {
+ warn( eMsg2("token name %s and rexpr %s already defined; ignored",
+ token, expr) );
+ return;
+ }
+ if ( p==NULL && q==NULL ) /* both not defined */
+ {
+ int t = addTname( token );
+ q = newTermEntry( expr );
+ hash_add(Texpr, expr, (Entry *)q);
+ q->token = t;
+ /* note: we use the actual ExprStr array
+ * here as TokenInd doesn't exist yet
+ */
+ ExprStr[t] = q->str;
+ /* track the order in which they occur */
+ list_add(&ExprOrder, (void *)newExpr(q->str));
+ return;
+ }
+ if ( p != NULL ) /* one is defined, one is not */
+ {
+ q = newTermEntry( expr );
+ hash_add(Texpr, expr, (Entry *)q);
+ q->token = p->token;
+ ExprStr[p->token] = q->str; /* both expr and token str defined now */
+ list_add(&ExprOrder, (void *)newExpr(q->str));
+ }
+ else /* trying to associate name with expr here*/
+ {
+ p = newTermEntry( token );
+ hash_add(Tname, token, (Entry *)p);
+ p->token = q->token;
+ TokenStr[p->token] = p->str;/* both expr and token str defined now */
+ }
+}
+
+/*
+ * Given a string, this function allocates and returns a pointer to a
+ * hash table record of size 'sz' whose "str" pointer is reset to a position
+ * in the string table.
+ */
+Entry *
+#ifdef __USE_PROTOS
+newEntry( char *text, int sz )
+#else
+newEntry( text, sz )
+char *text;
+int sz;
+#endif
+{
+ Entry *p;
+ require(text!=NULL, "new: NULL terminal");
+
+ if ( (p = (Entry *) calloc(1,sz)) == 0 )
+ {
+ fatal_internal("newEntry: out of memory for terminals\n");
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ p->str = mystrdup(text);
+
+ return(p);
+}
+
+/*
+ * add an element to a list.
+ *
+ * Any non-empty list has a sentinel node whose 'elem' pointer is really
+ * a pointer to the last element. (i.e. length(list) = #elemIn(list)+1).
+ * Elements are appended to the list.
+ */
+void
+#ifdef __USE_PROTOS
+list_add( ListNode **list, void *e )
+#else
+list_add( list, e )
+ListNode **list;
+void *e;
+#endif
+{
+ ListNode *p, *tail;
+ require(e!=NULL, "list_add: attempting to add NULL list element");
+
+ p = newListNode;
+ require(p!=NULL, "list_add: cannot alloc new list node");
+ p->elem = e;
+ if ( *list == NULL )
+ {
+ ListNode *sentinel = newListNode;
+ require(sentinel!=NULL, "list_add: cannot alloc sentinel node");
+ *list=sentinel;
+ sentinel->next = p;
+ sentinel->elem = (char *)p; /* set tail pointer */
+ }
+ else /* find end of list */
+ {
+ tail = (ListNode *) (*list)->elem; /* get tail pointer */
+ tail->next = p;
+ (*list)->elem = (char *) p; /* reset tail */
+ }
+}
+
+/* MR10 list_free() frees the ListNode elements in the list */
+/* MR10 if freeData then free the data elements of the list too */
+
+void
+#ifdef __USE_PROTOS
+list_free(ListNode **list,int freeData)
+#else
+list_free(list,freeData)
+ ListNode **list;
+ int freeData;
+#endif
+{
+ ListNode *p;
+ ListNode *next;
+
+ if (list == NULL) return;
+ if (*list == NULL) return;
+ for (p=*list; p != NULL; p=next) {
+ next=p->next;
+ if (freeData && p->elem != NULL) {
+ free( (char *) p->elem);
+ };
+ free( (char *) p);
+ };
+ *list=NULL;
+}
+
+void
+#ifdef __USE_PROTOS
+list_apply( ListNode *list, void (*f)(void *) )
+#else
+list_apply( list, f )
+ListNode *list;
+void (*f)();
+#endif
+{
+ ListNode *p;
+ require(f!=NULL, "list_apply: NULL function to apply");
+
+ if ( list == NULL ) return;
+ for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem );
+}
+
+/* MR27 */
+
+#ifdef __USE_PROTOS
+int list_search_cstring(ListNode *list, char * cstring)
+#else
+int list_search_cstring(list, cstring)
+ ListNode * list;
+ char * cstring;
+#endif
+{
+ ListNode *p;
+ if (list == NULL ) return 0;
+ for (p = list->next; p!=NULL; p=p->next) {
+ if (p->elem == NULL) continue;
+ if (0 == strcmp((char *) p->elem , cstring)) return 1;
+ }
+ return 0;
+}
+
+ /* F O L L O W C y c l e S t u f f */
+
+/* make a key based upon (rulename, computation, k value).
+ * Computation values are 'i'==FIRST, 'o'==FOLLOW.
+ */
+
+/* MR10 Make the key all characters so it can be read easily */
+/* MR10 by a simple dump program. Also, separates */
+/* MR10 'o' and 'i' from rule name */
+
+char *
+#ifdef __USE_PROTOS
+Fkey( char *rule, int computation, int k )
+#else
+Fkey( rule, computation, k )
+char *rule;
+int computation;
+int k;
+#endif
+{
+ static char key[MaxRuleName+2+2+1]; /* MR10 */
+ int i;
+
+ if ( k > 99 ) /* MR10 */
+ fatal("k>99 is too big for this implementation of ANTLR!\n"); /* MR10 */
+ if ( (i=strlen(rule)) > MaxRuleName ) /* MR10 */
+ fatal( eMsgd("rule name > max of %d\n", MaxRuleName) ); /* MR10 */
+ strcpy(key,rule);
+
+/* MR10 */ key[i]='*';
+/* MR10 */ key[i+1] = (char) computation; /* MR20 G. Hobbelt */
+/* MR10 */ if (k < 10) {
+/* MR10 */ key[i+2] = (char) ( '0' + k);
+/* MR10 */ key[i+3] = '\0';
+/* MR10 */ } else {
+/* MR10 */ key[i+2] = (char) ( '0' + k/10);
+/* MR10 */ key[i+3] = (char) ( '0' + k % 10);
+/* MR10 */ key[i+4] = '\0';
+/* MR10 */ };
+
+ return key;
+}
+
+/* Push a rule onto the kth FOLLOW stack */
+void
+#ifdef __USE_PROTOS
+FoPush( char *rule, int k )
+#else
+FoPush( rule, k )
+char *rule;
+int k;
+#endif
+{
+ RuleEntry *r;
+ require(rule!=NULL, "FoPush: tried to push NULL rule");
+ require(k<=CLL_k, "FoPush: tried to access non-existent stack");
+
+ /*fprintf(stderr, "FoPush(%s)\n", rule);*/
+ r = (RuleEntry *) hash_get(Rname, rule);
+ if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );}
+ if ( FoStack[k] == NULL ) /* Does the kth stack exist yet? */
+ {
+ /*fprintf(stderr, "allocating FoStack\n");*/
+ FoStack[k] = (int *) calloc(FoStackSize, sizeof(int));
+ require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n");
+ }
+ if ( FoTOS[k] == NULL )
+ {
+ FoTOS[k]=FoStack[k];
+ *(FoTOS[k]) = r->rulenum;
+ }
+ else
+ {
+#ifdef MEMCHK
+ require(valid(FoStack[k]), "FoPush: invalid FoStack");
+#endif
+ if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) )
+ fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n",
+ FoStackSize) );
+ require(FoTOS[k]>=FoStack[k],
+ eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox",
+ rule));
+ ++(FoTOS[k]);
+ *(FoTOS[k]) = r->rulenum;
+ }
+ {
+ /*
+**** int *p;
+**** fprintf(stderr, "FoStack[k=%d]:\n", k);
+**** for (p=FoStack[k]; p<=FoTOS[k]; p++)
+**** {
+**** fprintf(stderr, "\t%s\n", RulePtr[*p]->rname);
+**** }
+ */
+ }
+}
+
+/* Pop one rule off of the FOLLOW stack. TOS ptr is NULL if empty. */
+void
+#ifdef __USE_PROTOS
+FoPop( int k )
+#else
+FoPop( k )
+int k;
+#endif
+{
+ require(k<=CLL_k, "FoPop: tried to access non-existent stack");
+ /*fprintf(stderr, "FoPop\n");*/
+ require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),
+ "FoPop: FoStack stack-ptr is playing out of its sandbox");
+ if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL;
+ else (FoTOS[k])--;
+}
+
+/* Compute FOLLOW cycle.
+ * Mark all FOLLOW sets for rules in cycle as incomplete.
+ * Then, save cycle on the cycle list (Cycles) for later resolution.
+ * The Cycle is stored in the form:
+ * (head of cycle==croot, rest of rules in cycle==cyclicDep)
+ *
+ * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on)
+ *
+ * Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x)
+ * ^----Infinite recursion (cycle)
+ *
+ * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}). Fo(x) depends
+ * on the FOLLOW of a,b, and c. The root of a cycle is always complete after
+ * Fo(x) finishes. Fo(a,b,c) however are not. It turns out that all rules
+ * in a FOLLOW cycle have the same FOLLOW set.
+ */
+void
+#ifdef __USE_PROTOS
+RegisterCycle( char *rule, int k )
+#else
+RegisterCycle( rule, k )
+char *rule;
+int k;
+#endif
+{
+ CacheEntry *f;
+ Cycle *c;
+ int *p;
+ RuleEntry *r;
+ require(rule!=NULL, "RegisterCycle: tried to register NULL rule");
+ require(k<=CLL_k, "RegisterCycle: tried to access non-existent stack");
+
+ /*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/
+ /* Find cycle start */
+ r = (RuleEntry *) hash_get(Rname, rule);
+ require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule));
+ require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]),
+ eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox",
+ rule));
+/*** if ( FoTOS[k]<FoStack[k]||FoTOS[k]>&(FoStack[k][FoStackSize-1]) )
+**** {
+**** fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n",
+**** rule);
+**** fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n",
+**** FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1]));
+**** exit(PCCTS_EXIT_FAILURE);
+**** }
+****/
+
+#ifdef MEMCHK
+ require(valid(FoStack[k]), "RegisterCycle: invalid FoStack");
+#endif
+ for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;}
+ require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief");
+ if ( p == FoTOS[k] ) return; /* don't worry about cycles to oneself */
+
+ /* compute cyclic dependents (rules in cycle except head) */
+ c = newCycle;
+ require(c!=NULL, "RegisterCycle: couldn't alloc new cycle");
+ c->cyclicDep = empty;
+ c->croot = *p++; /* record root of cycle */
+ for (; p<=FoTOS[k]; p++)
+ {
+ /* Mark all dependent rules as incomplete */
+ f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k));
+ if ( f==NULL )
+ {
+ f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) );
+ hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f);
+ }
+ f->incomplete = TRUE;
+
+ set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */
+ }
+ list_add(&(Cycles[k]), (void *)c);
+}
+
+/* make all rules in cycle complete
+ *
+ * while ( some set has changed ) do
+ * for each cycle do
+ * if degree of FOLLOW set for croot > old degree then
+ * update all FOLLOW sets for rules in cyclic dependency
+ * change = TRUE
+ * endif
+ * endfor
+ * endwhile
+ */
+void
+#ifdef __USE_PROTOS
+ResolveFoCycles( int k )
+#else
+ResolveFoCycles( k )
+int k;
+#endif
+{
+ ListNode *p, *q;
+ Cycle *c;
+ int changed = 1;
+ CacheEntry *f,*g;
+ int r;
+/* int i; */ /* MR10 not useful */
+ unsigned d;
+
+ unsigned *cursor; /* MR10 */
+ unsigned *origin; /* MR10 */
+
+ /*fprintf(stderr, "Resolving following cycles for %d\n", k);*/
+ while ( changed )
+ {
+ changed = 0;
+/* MR10 i = 0; */
+ for (p = Cycles[k]->next; p!=NULL; p=p->next)
+ {
+ c = (Cycle *) p->elem;
+ /*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/
+ /*s_fprT(stderr, c->cyclicDep);*/
+ /*fprintf(stderr, "\n");*/
+ f = (CacheEntry *)
+ hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k));
+ require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) );
+ if ( (d=set_deg(f->fset)) > c->deg )
+ {
+ /*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/
+ changed = 1;
+ c->deg = d; /* update cycle FOLLOW set degree */
+
+/* MR10 */ origin=set_pdq(c->cyclicDep);
+/* MR10 */ for (cursor=origin; *cursor != nil; cursor++) {
+/* MR10 */ r=*cursor;
+
+/******** while ( !set_nil(c->cyclicDep) ) { *****/
+/******** r = set_int(c->cyclicDep); *****/
+/******** set_rm(r, c->cyclicDep); *****/
+
+ /*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/
+ g = (CacheEntry *)
+ hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k));
+ require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) );
+ set_orin(&(g->fset), f->fset);
+ g->incomplete = FALSE;
+ }
+/* MR10 */ free( (char *) origin);
+/* MR10 */ origin=NULL;
+ }
+ }
+/* MR10 - this if statement appears to be meaningless since i is always 0 */
+/* MR10 if ( i == 1 ) changed = 0; */ /* if only 1 cycle, no need to repeat */
+ }
+ /* kill Cycle list */
+ for (q = Cycles[k]->next; q != NULL; q=p)
+ {
+ p = q->next;
+ set_free( ((Cycle *)q->elem)->cyclicDep );
+ free((char *)q);
+ }
+ free( (char *)Cycles[k] );
+ Cycles[k] = NULL;
+}
+
+
+ /* P r i n t i n g S y n t a x D i a g r a m s */
+
+static void
+#ifdef __USE_PROTOS
+pBlk( Junction *q, int btype )
+#else
+pBlk( q, btype )
+Junction *q;
+int btype;
+#endif
+{
+ int k,a;
+ Junction *alt, *p;
+
+ q->end->pvisited = TRUE;
+ if ( btype == aLoopBegin )
+ {
+ require(q->p2!=NULL, "pBlk: invalid ()* block");
+ PRINT(q->p1);
+ alt = (Junction *)q->p2;
+ PRINT(alt->p1);
+ if ( PrintAnnotate )
+ {
+ printf(" /* Opt ");
+ k = 1;
+ while ( !set_nil(alt->fset[k]) )
+ {
+ s_fprT(stdout, alt->fset[k]);
+ if ( k++ == CLL_k ) break;
+ if ( !set_nil(alt->fset[k]) ) printf(", ");
+ }
+ printf(" */\n");
+ }
+ return;
+ }
+ for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++)
+ {
+ if ( alt->p1 != NULL ) PRINT(alt->p1);
+ if ( PrintAnnotate )
+ {
+ printf( " /* [%d] ", alt->altnum);
+ k = 1;
+ while ( !set_nil(alt->fset[k]) )
+ {
+ s_fprT(stdout, alt->fset[k]);
+ if ( k++ == CLL_k ) break;
+ if ( !set_nil(alt->fset[k]) ) printf(", ");
+ }
+ if ( alt->p2 == NULL && btype == aOptBlk )
+ printf( " (optional branch) */\n");
+ else printf( " */\n");
+ }
+
+ /* ignore implied empty alt of Plus blocks */
+ if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break;
+
+ if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) )
+ {
+ if ( pLevel == 1 )
+ {
+ printf("\n");
+ if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>");
+ printf("\t");
+ }
+ else printf(" ");
+ printf("|");
+ if ( pLevel == 1 )
+ {
+ p = (Junction *) ((Junction *)alt->p2)->p1;
+ while ( p!=NULL )
+ {
+ if ( p->ntype==nAction )
+ {
+ p=(Junction *)((ActionNode *)p)->next;
+ continue;
+ }
+ if ( p->ntype!=nJunction )
+ {
+ break;
+ }
+ if ( p->jtype==EndBlk || p->jtype==EndRule )
+ {
+ p = NULL;
+ break;
+ }
+ p = (Junction *)p->p1;
+ }
+ if ( p==NULL ) printf("\n\t"); /* Empty alt? */
+ }
+ }
+ }
+ q->end->pvisited = FALSE;
+}
+
+/* How to print out a junction */
+void
+#ifdef __USE_PROTOS
+pJunc( Junction *q )
+#else
+pJunc( q )
+Junction *q;
+#endif
+{
+ int dum_k;
+ int doing_rule;
+ require(q!=NULL, "pJunc: NULL node");
+ require(q->ntype==nJunction, "pJunc: not junction");
+
+ if ( q->pvisited == TRUE ) return;
+ q->pvisited = TRUE;
+ switch ( q->jtype )
+ {
+ case aSubBlk :
+ if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+ if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction &&
+ ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1;
+ else doing_rule = 0;
+ pLevel++;
+ if ( pLevel==1 )
+ {
+ if ( pAlt1==1 ) printf("=>");
+ printf("\t");
+ }
+ else printf(" ");
+ if ( doing_rule )
+ {
+ if ( pLevel==1 ) printf(" ");
+ pBlk(q,q->jtype);
+ }
+ else {
+ printf("(");
+ if ( pLevel==1 ) printf(" ");
+ pBlk(q,q->jtype);
+ if ( pLevel>1 ) printf(" ");
+ printf(")");
+ }
+ if ( q->guess ) printf("?");
+ pLevel--;
+ if ( PrintAnnotate ) freeBlkFsets(q);
+ if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+ break;
+ case aOptBlk :
+ if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+ pLevel++;
+ if ( pLevel==1 )
+ {
+ if ( pAlt1==1 ) printf("=>");
+ printf("\t");
+ }
+ else printf(" ");
+ printf("{");
+ if ( pLevel==1 ) printf(" ");
+ pBlk(q,q->jtype);
+ if ( pLevel>1 ) printf(" ");
+ else printf("\n\t");
+ printf("}");
+ pLevel--;
+ if ( PrintAnnotate ) freeBlkFsets(q);
+ if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+ break;
+ case aLoopBegin :
+ if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+ pLevel++;
+ if ( pLevel==1 )
+ {
+ if ( pAlt1==1 ) printf("=>");
+ printf("\t");
+ }
+ else printf(" ");
+ printf("(");
+ if ( pLevel==1 ) printf(" ");
+ pBlk(q,q->jtype);
+ if ( pLevel>1 ) printf(" ");
+ else printf("\n\t");
+ printf(")*");
+ pLevel--;
+ if ( PrintAnnotate ) freeBlkFsets(q);
+ if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+ break;
+ case aLoopBlk :
+ if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+ pBlk(q,q->jtype);
+ if ( PrintAnnotate ) freeBlkFsets(q);
+ break;
+ case aPlusBlk :
+ if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k);
+ pLevel++;
+ if ( pLevel==1 )
+ {
+ if ( pAlt1==1 ) printf("=>");
+ printf("\t");
+ }
+ else printf(" ");
+ printf("(");
+ if ( pLevel==1 ) printf(" ");
+ pBlk(q,q->jtype);
+ if ( pLevel>1 ) printf(" ");
+ printf(")+");
+ pLevel--;
+ if ( PrintAnnotate ) freeBlkFsets(q);
+ if ( q->end->p1 != NULL ) PRINT(q->end->p1);
+ break;
+ case EndBlk :
+ break;
+ case RuleBlk :
+ printf( "\n%s :\n", q->rname);
+ PRINT(q->p1);
+ if ( q->p2 != NULL ) PRINT(q->p2);
+ break;
+ case Generic :
+ if ( q->p1 != NULL ) PRINT(q->p1);
+ q->pvisited = FALSE;
+ if ( q->p2 != NULL ) PRINT(q->p2);
+ break;
+ case EndRule :
+ printf( "\n\t;\n");
+ break;
+ }
+ q->pvisited = FALSE;
+}
+
+/* How to print out a rule reference node */
+void
+#ifdef __USE_PROTOS
+pRuleRef( RuleRefNode *p )
+#else
+pRuleRef( p )
+RuleRefNode *p;
+#endif
+{
+ require(p!=NULL, "pRuleRef: NULL node");
+ require(p->ntype==nRuleRef, "pRuleRef: not rule ref node");
+
+ printf( " %s", p->text);
+ PRINT(p->next);
+}
+
+/* How to print out a terminal node */
+void
+#ifdef __USE_PROTOS
+pToken( TokNode *p )
+#else
+pToken( p )
+TokNode *p;
+#endif
+{
+ require(p!=NULL, "pToken: NULL node");
+ require(p->ntype==nToken, "pToken: not token node");
+
+ if ( p->wild_card ) printf(" .");
+ printf( " %s", TerminalString(p->token));
+ PRINT(p->next);
+}
+
+/* How to print out a terminal node */
+void
+#ifdef __USE_PROTOS
+pAction( ActionNode *p )
+#else
+pAction( p )
+ActionNode *p;
+#endif
+{
+ require(p!=NULL, "pAction: NULL node");
+ require(p->ntype==nAction, "pAction: not action node");
+
+ PRINT(p->next);
+}
+
+ /* F i l l F o l l o w L i s t s */
+
+/*
+ * Search all rules for all rule reference nodes, q to rule, r.
+ * Add q->next to follow list dangling off of rule r.
+ * i.e.
+ *
+ * r: -o-R-o-->o--> Ptr to node following rule r in another rule
+ * |
+ * o--> Ptr to node following another reference to r.
+ *
+ * This is the data structure employed to avoid FOLLOW set computation. We
+ * simply compute the FIRST (reach) of the EndRule Node which follows the
+ * list found at the end of all rules which are referenced elsewhere. Rules
+ * not invoked by other rules have no follow list (r->end->p1==NULL).
+ * Generally, only start symbols are not invoked by another rule.
+ *
+ * Note that this mechanism also gives a free cross-reference mechanism.
+ *
+ * The entire syntax diagram is layed out like this:
+ *
+ * SynDiag
+ * |
+ * v
+ * o-->R1--o
+ * |
+ * o-->R2--o
+ * |
+ * ...
+ * |
+ * o-->Rn--o
+ *
+ */
+void
+#ifdef __USE_PROTOS
+FoLink( Node *p )
+#else
+FoLink( p )
+Node *p;
+#endif
+{
+ RuleEntry *q;
+ Junction *j = (Junction *) p;
+ RuleRefNode *r = (RuleRefNode *) p;
+
+ if ( p==NULL ) return;
+ require(p->ntype>=1 && p->ntype<=NumNodeTypes,
+ eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype));
+ switch ( p->ntype )
+ {
+ case nJunction :
+ if ( j->fvisited ) return;
+ if ( j->jtype == EndRule ) return;
+ j->fvisited = TRUE;
+ FoLink( j->p1 );
+ FoLink( j->p2 );
+/* MR14 */
+/* MR14 */ /* Need to determine whether the guess block is an */
+/* MR14 */ /* of the form (alpha)? beta before follow sets are */
+/* MR14 */ /* computed. This is necessary to solve problem */
+/* MR14 */ /* of doing follow on the alpha of an (alpha)? beta block. */
+/* MR14 */
+/* MR14 */ /* This is performed by analysis_point as a side-effect. */
+/* MR14 */
+/* MR14 */
+/* MR14 */ if (j->jtype == aSubBlk && j->guess) {
+/* MR14 */ Junction *ignore;
+/* MR14 */ ignore=analysis_point(j);
+/* MR14 */ }
+/* MR14 */
+ return;
+ case nRuleRef :
+ if ( r->linked ) return;
+ q = (RuleEntry *) hash_get(Rname, r->text);
+ if ( q == NULL )
+ {
+ warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line );
+ }
+ else
+ {
+ if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL )
+ {
+ warnFL( eMsg1("rule %s accepts no parameter(s)", r->text),
+ FileStr[r->file], r->line );
+ }
+ if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL )
+ {
+ warnFL( eMsg1("rule %s requires parameter(s)", r->text),
+ FileStr[r->file], r->line );
+ }
+ if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL )
+ {
+ warnFL( eMsg1("rule %s yields no return value(s)", r->text),
+ FileStr[r->file], r->line );
+ }
+ if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL )
+ {
+ warnFL( eMsg1("rule %s returns a value(s)", r->text),
+ FileStr[r->file], r->line );
+ }
+ if ( !r->linked )
+ {
+ addFoLink( r->next, r->rname, RulePtr[q->rulenum] );
+ r->linked = TRUE;
+ }
+ }
+ FoLink( r->next );
+ return;
+ case nToken :
+ FoLink( ((TokNode *)p)->next );
+ return;
+ case nAction :
+ FoLink( ((ActionNode *)p)->next );
+ return;
+ default :
+ fatal_internal("invalid node type");
+ }
+}
+
+/*
+ * Add a reference to the end of a rule.
+ *
+ * 'r' points to the RuleBlk node in a rule. r->end points to the last node
+ * (EndRule jtype) in a rule.
+ *
+ * Initial:
+ * r->end --> o
+ *
+ * After:
+ * r->end --> o-->o--> Ptr to node following rule r in another rule
+ * |
+ * o--> Ptr to node following another reference to r.
+ *
+ * Note that the links are added to the head of the list so that r->end->p1
+ * always points to the most recently added follow-link. At the end, it should
+ * point to the last reference found in the grammar (starting from the 1st rule).
+ */
+void
+#ifdef __USE_PROTOS
+addFoLink( Node *p, char *rname, Junction *r )
+#else
+addFoLink( p, rname, r )
+Node *p;
+char *rname;
+Junction *r;
+#endif
+{
+ Junction *j;
+ require(r!=NULL, "addFoLink: incorrect rule graph");
+ require(r->end!=NULL, "addFoLink: incorrect rule graph");
+ require(r->end->jtype==EndRule, "addFoLink: incorrect rule graph");
+ require(p!=NULL, "addFoLink: NULL FOLLOW link");
+
+ j = newJunction();
+ j->rname = rname; /* rname on follow links point to target rule */
+ j->p1 = p; /* link to other rule */
+ j->p2 = (Node *) r->end->p1;/* point to head of list */
+ r->end->p1 = (Node *) j; /* reset head to point to new node */
+}
+
+void
+#ifdef __USE_PROTOS
+GenCrossRef( Junction *p )
+#else
+GenCrossRef( p )
+Junction *p;
+#endif
+{
+ set a;
+ Junction *j;
+ RuleEntry *q;
+ unsigned e;
+ require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?");
+
+ printf("Cross Reference:\n\n");
+ a = empty;
+ for (; p!=NULL; p = (Junction *)p->p2)
+ {
+ printf("Rule %20s referenced by {", p->rname);
+ /* make a set of rules for uniqueness */
+ for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2)
+ {
+ q = (RuleEntry *) hash_get(Rname, j->rname);
+ require(q!=NULL, "GenCrossRef: FoLinks are screwed up");
+ set_orel(q->rulenum, &a);
+ }
+ for (; !set_nil(a); set_rm(e, a))
+ {
+ e = set_int(a);
+ printf(" %s", RulePtr[e]->rname);
+ }
+ printf(" }\n");
+ }
+ set_free( a );
+}
+
+/*
+ The single argument is a pointer to the start of an element of a
+ C++ style function prototypet list. Given a pointer to the start of
+ an formal we must locate the comma (or the end of the string)
+ and locate the datatype, formal name, and initial value expression.
+
+ The function returns a pointer to the character following the comma
+ which terminates the formal declaration, or a pointer to the end of
+ the string if none was found.
+
+ I thought we were parsing specialists, how come I'm doing this by
+ hand written code ?
+
+ Examples of input:
+
+ Foo f,
+ Foo f = Foo(1),
+ Foo f = Foo(1,2),
+ Foo f = &farray[1,2],
+ Foo f = ",",
+ Foo f = ',',
+ TFoo<int,char> f = TFoo<int,char>(1,2),
+
+ A non-zero value for nesting indicates a problem matching '(' and ')',
+ '[' and ']', '<' and '>', '{' and '}', or improperly terminated string
+ or character literal.
+
+*/
+
+
+/*
+ * Don't care if it is a valid string literal or not, just find the end
+ * Start with pointer to leading "\""
+ */
+
+#ifdef __USE_PROTOS
+char * skipStringLiteral(char *pCurrent)
+#else
+char * skipStringLiteral(pCurrent)
+char *pCurrent;
+#endif
+{
+ char *p = pCurrent;
+ if (*p == 0) return p;
+ require (*p == '\"', "skipStringLiteral")
+ p++;
+ for (p = p; *p != 0; p++) {
+ if (*p == '\\') {
+ p++;
+ if (*p == 0) break;
+ p++;
+ }
+ if (*p == '\"') {
+ p++;
+ break;
+ }
+ }
+ return p;
+}
+
+/*
+ * Don't care if it is a valid character literal or not, just find the end
+ * Start with pointer to leading "'"
+ */
+
+#ifdef __USE_PROTOS
+char * skipCharLiteral(char *pStart)
+#else
+char * skipCharLiteral(pStart)
+ char *pStart;
+#endif
+{
+ char *p = pStart;
+ if (*p == 0) return p;
+ require (*p == '\'', "skipCharLiteral")
+ p++;
+ for (p = p; *p != 0; p++) {
+ if (*p == '\\') {
+ p++;
+ if (*p == 0) break;
+ p++;
+ }
+ if (*p == '\'') {
+ p++;
+ break;
+ }
+ }
+ return p;
+}
+
+#ifdef __USE_PROTOS
+char * skipSpaces(char *pStart)
+#else
+char * skipSpaces(pStart)
+char * pStart;
+#endif
+{
+ char *p = pStart;
+ while (*p != 0 && isspace(*p)) p++;
+ return p;
+}
+
+#ifdef __USE_PROTOS
+char * skipToSeparatorOrEqualSign(char *pStart, int *pNest)
+#else
+char * skipToSeparatorOrEqualSign(pStart, pNest)
+char *pStart;
+int *pNest;
+#endif
+{
+ char *p = pStart;
+
+ int nest = 0;
+
+ *pNest = (-1);
+
+ while (*p != 0) {
+ switch (*p) {
+
+ case '(' :
+ case '[' :
+ case '<' :
+ case '{' :
+ nest++;
+ p++;
+ break;
+
+ case ')' :
+ case ']' :
+ case '>' :
+ case '}' :
+ nest--;
+ p++;
+ break;
+
+ case '"' :
+ p = skipStringLiteral(p);
+ break;
+
+ case '\'' :
+ p = skipCharLiteral(p);
+ break;
+
+ case '\\':
+ p++;
+ if (*p == 0) goto EXIT;
+ p++;
+ break;
+
+ case ',':
+ case '=':
+ if (nest == 0) goto EXIT;
+ p++;
+ break;
+
+ default:
+ p++;
+ }
+ }
+EXIT:
+ *pNest = nest;
+ return p;
+}
+
+#ifdef __USE_PROTOS
+char * skipToSeparator(char *pStart, int *pNest)
+#else
+char * skipToSeparator(pStart, pNest)
+char *pStart;
+int *pNest;
+#endif
+{
+ char * p = pStart;
+ for ( ; ; ) {
+ p = skipToSeparatorOrEqualSign(p, pNest);
+ if (*pNest != 0) return p;
+ if (*p == ',') return p;
+ if (*p == 0) return p;
+ p++;
+ }
+}
+
+/* skip to just past the "=" separating the declaration from the initialization value */
+
+#ifdef __USE_PROTOS
+char * getInitializer(char *pStart)
+#else
+char * getInitializer(pStart)
+char * pStart;
+#endif
+{
+ char *p;
+ char *pDataType;
+ char *pSymbol;
+ char *pEqualSign;
+ char *pValue;
+ char *pSeparator;
+ int nest = 0;
+
+ require(pStart!=NULL, "getInitializer: invalid string");
+
+ p = endFormal(pStart,
+ &pDataType,
+ &pSymbol,
+ &pEqualSign,
+ &pValue,
+ &pSeparator,
+ &nest);
+ if (nest != 0) return NULL;
+ if (pEqualSign == NULL) return NULL;
+ if (pValue == NULL) return NULL;
+ return strBetween(pValue, NULL, pSeparator);
+}
+
+/*
+ Examines the string from pStart to pEnd-1.
+ If the string has 0 length or is entirely white space
+ returns 1. Otherwise 0.
+*/
+
+#ifdef __USE_PROTOS
+int isWhiteString(const char *pStart, const char *pEnd)
+#else
+int isWhiteString(pStart, pEnd)
+const char *pStart;
+const char *pEnd;
+#endif
+{
+ const char *p;
+ for (p = pStart; p < pEnd; p++) {
+ if (! isspace(*p)) return 0;
+ }
+ return 1;
+}
+
+/*
+ This replaces HasComma() which couldn't distinguish
+
+ foo ["a,b"]
+
+ from:
+
+ foo[a,b]
+
+*/
+
+#ifdef __USE_PROTOS
+int hasMultipleOperands(char *pStart)
+#else
+int hasMultipleOperands(pStart)
+char *pStart;
+#endif
+{
+ char *p = pStart;
+ int nest = 0;
+
+ p = skipSpaces(p);
+ if (*p == 0) return 0;
+ p = skipToSeparator(p, &nest);
+ if (nest == 0 && *p == ',') return 1;
+ return 0;
+}
+
+
+#define MAX_STR_BETWEEN_WORK_AREA 1000
+
+static char strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA];
+
+
+/*
+ strBetween(pStart, pNext, pStop)
+
+ Creates a null terminated string by copying the text between two pointers
+ to a work area. The start of the string is pStart. The end of the string
+ is the character before pNext, or if pNext is null then the character before
+ pStop. Trailing spaces are not included in the copy operation.
+
+ This is used when a string contains several parts. The pNext part may be
+ optional. The pStop will stop the scan when the optional part is not present
+ (is a null pointer).
+*/
+
+#ifdef __USE_PROTOS
+char *strBetween(char *pStart, char *pNext, char *pStop)
+#else
+char *strBetween(pStart, pNext, pStop)
+char *pStart;
+char *pNext;
+char *pStop;
+#endif
+{
+ char *p;
+ char *q = strBetweenWorkArea;
+ const char *pEnd;
+
+ pEnd = (pNext != NULL) ? pNext : pStop;
+
+ require (pEnd != NULL, "pEnd == NULL");
+ require (pEnd >= pStart, "pEnd < pStart");
+ for (pEnd--; pEnd >= pStart; pEnd--) { /* MR31 */
+ if (! isspace(*pEnd)) break;
+ }
+ for (p = pStart;
+ p <= pEnd && q < &strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA-2];
+ p++, q++) {
+ *q = *p;
+ }
+ *q = 0;
+ return strBetweenWorkArea;
+}
+
+/*
+ function Returns pointer to character following separator at
+ value which to continue search for next formal. If at the
+ end of the string a pointer to the null byte at the
+ end of the string is returned.
+
+ pStart Pointer to the starting position of the formal list
+
+ This may be the middle of a longer string, for example
+ when looking for the end of formal #3 starting from
+ the middle of the complete formal list.
+
+ ppDataType Returns a pointer to the start of the data type in the
+ formal. Example: pointer to "Foo".
+
+ ppSymbol Returns a pointer to the start of the formal symbol.
+ Example: pointer to "f".
+
+ ppEqualSign Returns a pointer to the equal sign separating the
+ formal symbol from the initial value. If there is
+ no "=" then this will be NULL.
+
+ ppValue Returns a pointer to the initial value part of the
+ formal declaration. Example: pointer to "&farray[1,2]"
+
+ ppSeparator Returns a pointer to the character which terminated the
+ scan. This should be a pointer to a comma or a null
+ byte which terminates the string.
+
+ pNest Returns the nesting level when a separator was found.
+ This is non-zero for any kind of error. This is zero
+ for a successful parse of this portion of the formal
+ list.
+
+*/
+
+#ifdef __USE_PROTOS
+char * endFormal(char *pStart,
+ char **ppDataType,
+ char **ppSymbol,
+ char **ppEqualSign,
+ char **ppValue,
+ char **ppSeparator,
+ int *pNest)
+#else
+char * endFormal(pStart,
+ ppDataType,
+ ppSymbol,
+ ppEqualSign,
+ ppValue,
+ ppSeparator,
+ pNest)
+char *pStart;
+char **ppDataType;
+char **ppSymbol;
+char **ppEqualSign;
+char **ppValue;
+char **ppSeparator;
+int *pNest;
+
+#endif
+{
+ char *p = pStart;
+ char *q;
+
+ *ppDataType = NULL;
+ *ppSymbol = NULL;
+ *ppEqualSign = NULL;
+ *ppValue = NULL;
+ *ppSeparator = NULL;
+
+ *pNest = 0;
+
+ /* The first non-blank is the start of the datatype */
+
+ p = skipSpaces(p);
+ if (*p == 0) goto EXIT;
+ *ppDataType = p;
+
+ /* We are not looking for the symbol, we are looking
+ for the separator that follows the symbol. Then
+ we'll back up.
+
+ Search for the ',' or '=" or null terminator.
+ */
+
+ p = skipToSeparatorOrEqualSign(p, pNest);
+
+ if (*pNest != 0) goto EXIT;
+
+ /*
+ Work backwards to find start of symbol
+ Skip spaces between the end of symbol and separator
+ Assume that there are no spaces in the formal, but
+ there is a space preceding the formal
+ */
+
+ for (q = &p[-1]; q >= *ppDataType; q--) {
+ if (! isspace(*q)) break;
+ }
+ if (q < *ppDataType) goto EXIT;
+
+ /*
+ MR26 Handle things like: IIR_Bool (IIR_Decl::*constraint)()
+ Backup until we hit the end of a symbol string, then find the
+ start of the symbol string. This wont' work for functions
+ with prototypes, but works for the most common cases. For
+ others, use typedef names.
+ */
+
+/* MR26 */ for (q = q; q >= *ppDataType; q--) {
+/* MR26 */ if (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$') break;
+/* MR26 */ }
+/* MR26 */ if (q < *ppDataType) goto EXIT;
+
+ for (q = q; q >= *ppDataType; q--) {
+ if ( ! (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$')) break;
+ }
+
+ *ppSymbol = &q[1];
+
+ if (*p == ',' || *p == 0) {
+ *ppSeparator = p;
+ goto EXIT;
+ }
+
+ *ppEqualSign = p;
+ p = skipSpaces(++p);
+ *ppValue = p;
+ if (*p == 0) goto EXIT;
+
+
+ while (*p != 0 && *pNest == 0 && *p != ',') {
+ p = skipToSeparator(p, pNest);
+ }
+ if (*pNest == 0) *ppSeparator = p;
+
+EXIT:
+ if (*p == ',') p++;
+ return p;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mode.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mode.h
new file mode 100644
index 00000000..592e811c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mode.h
@@ -0,0 +1,12 @@
+#define START 0
+#define STRINGS 1
+#define ACTION_STRINGS 2
+#define ACTION_CHARS 3
+#define ACTION_COMMENTS 4
+#define TOK_DEF_COMMENTS 5
+#define TOK_DEF_CPP_COMMENTS 6
+#define ACTION_CPP_COMMENTS 7
+#define CPP_COMMENTS 8
+#define COMMENTS 9
+#define ACTIONS 10
+#define PARSE_ENUM_FILE 11
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mrhoist.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mrhoist.c
new file mode 100644
index 00000000..275cfc43
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/mrhoist.c
@@ -0,0 +1,3030 @@
+/*
+ * mrhoist.c
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33MR10
+ *
+ */
+
+#include <stdio.h>
+
+#include "pcctscfg.h"
+
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+#include <ctype.h>
+
+#ifdef __USE_PROTOS
+void dumppred(Predicate *);
+#else
+void dumppred();
+#endif
+
+/*
+ Try to determine whether predicate "first" is true for
+ all cases where "second" is true. Comparison takes place
+ without regard to context.
+ Assumes that predicate symbols have been expanded.
+ Assumes that there are no NAND or NOR nodes
+
+*/
+
+#ifdef __USE_PROTOS
+int MR_secondPredicateUnreachable(Predicate *first,Predicate *second)
+#else
+int MR_secondPredicateUnreachable(first,second)
+ Predicate *first;
+ Predicate *second;
+#endif
+{
+ Predicate *f;
+ Predicate *s;
+
+ if (first == NULL) {
+ return 1;
+ } else if (second == NULL) {
+ return 0;
+ } else if (first->down == NULL && second->down == NULL) {
+ if (first->source == second->source &&
+ first->inverted == second->inverted) {
+ return 1; /* look identical - will never reach alt2 */
+ } else {
+ return 0; /* look different */
+ };
+ } else if (first->down == NULL && second->down != NULL) {
+
+ if (second->expr == PRED_AND_LIST) {
+
+ /* unreachable if first covers any child of second */
+
+ for (s=second->down; s != NULL; s=s->right) {
+ if (MR_secondPredicateUnreachable(first,s)) {
+ return 1;
+ };
+ };
+ return 0;
+ } else if (second->expr == PRED_OR_LIST) {
+
+ /* unreachable if first covers every child of second */
+
+ for (s=second->down; s != NULL; s=s->right) {
+ if (!MR_secondPredicateUnreachable(first,s)) {
+ return 0;
+ };
+ };
+ return 1;
+ } else {
+ require (0,"Illegal pred->expr");
+ return 0; /* MR20 Make compiler happy */
+ };
+ } else if (first->down != NULL && second->down == NULL) {
+ if (first->expr == PRED_AND_LIST) {
+
+ /* unreachable if every child of first covers second */
+
+ for (f=first->down; f != NULL; f=f->right) {
+ if (!MR_secondPredicateUnreachable(f,second)) {
+ return 0;
+ };
+ };
+ return 1;
+ } else if (first->expr == PRED_OR_LIST) {
+
+ /* unreachable if any child of first covers second */
+
+ for (f=first->down; f != NULL; f=f->right) {
+ if (MR_secondPredicateUnreachable(f,second)) {
+ return 1;
+ };
+ };
+ return 0;
+ } else {
+ require (0,"Illegal predicate->expr");
+ return 0; /* MR20 Make compiler happy */
+ };
+ } else {
+
+ if (first->expr == PRED_AND_LIST && second->expr == PRED_AND_LIST) {
+
+ /* unreachable if each child of first covers at least one child of second */
+
+ for (f=first->down; f != NULL ; f=f->right) {
+ for (s=second->down; s != NULL ; s=s->right) {
+ if (MR_secondPredicateUnreachable(f,s)) goto A_next_f;
+ };
+ return 0;
+A_next_f:
+ continue;
+ };
+ return 1;
+
+ } else if (first->expr == PRED_AND_LIST && second->expr == PRED_OR_LIST) {
+
+ /* unreachable if each child of first covers ALL of second's children */
+
+ for (f=first->down; f != NULL ; f=f->right) {
+ for (s=second->down; s != NULL ; s=s->right) {
+ if (!MR_secondPredicateUnreachable(f,s)) return 0;
+ };
+ };
+ return 1;
+
+ } else if (first->expr == PRED_OR_LIST && second->expr == PRED_AND_LIST) {
+
+ /* unreachable if any child of second is covered by any child of first */
+
+ for (f=first->down; f != NULL ; f=f->right) {
+ for (s=second->down; s != NULL ; s=s->right) {
+ if (MR_secondPredicateUnreachable(f,s)) return 1;
+ };
+ };
+ return 0;
+
+ } else if (first->expr == PRED_OR_LIST && second->expr == PRED_OR_LIST) {
+
+ /* unreachable if every child of second is covered by some child of first */
+
+ for (f=first->down; f != NULL ; f=f->right) {
+ for (s=second->down; s != NULL ; s=s->right) {
+ if (MR_secondPredicateUnreachable(f,s)) goto B_next_f;
+ };
+ return 0;
+B_next_f:
+ continue;
+ };
+ return 1;
+
+ } else {
+ require (0,"Illegal predicate->expr");
+ return 0; /* MR20 Make compiler happy */
+ };
+ };
+ return 0; /* MR20 MSVC 5.0 complains about missing return statement */
+}
+
+#ifdef __USE_PROTOS
+void MR_xxxIndent(FILE *f,int depth)
+#else
+void MR_xxxIndent(f,depth)
+ FILE *f;
+ int depth;
+#endif
+{
+ int i;
+
+ for (i=0; i<depth ; i++) {
+ fprintf(f," ");
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_stderrIndent(int depth)
+#else
+void MR_stderrIndent(depth)
+ int depth;
+#endif
+{
+ MR_xxxIndent(stderr,depth);
+}
+
+#ifdef __USE_PROTOS
+void MR_outputIndent(int depth)
+#else
+void MR_outputIndent(depth)
+ int depth;
+#endif
+{
+ MR_xxxIndent(output,depth);
+}
+
+#ifdef __USE_PROTOS
+void MR_set_reuse(set *s)
+#else
+void MR_set_reuse(s)
+ set *s;
+#endif
+{
+ set_free(*s);
+ *s=empty;
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpPredRuleRefStack(FILE *iounit,int indent)
+#else
+void MR_dumpPredRuleRefStack(iounit,indent)
+ FILE *iounit;
+ int indent;
+#endif
+{
+ int i;
+ int j;
+ int count=MR_PredRuleRefStack.count;
+ RuleRefNode *rrn=NULL;
+ Junction *lastOne;
+
+ if (count == 0) {
+ fprintf(iounit,"empty\n");
+ return;
+ };
+ for (i=0; i < count; i++) {
+ rrn=(RuleRefNode *) MR_PredRuleRefStack.data[i];
+ for (j=0; j<indent; j++) fprintf(iounit," ");
+ fprintf(iounit,"#%-2d in rule %s (line %d %s) to rule %s\n",
+ i,rrn->rname,rrn->line,FileStr[rrn->file],rrn->text);
+ };
+ lastOne=MR_ruleReferenced(rrn);
+ if (lastOne != NULL) {
+ for (j=0; j<indent; j++) fprintf(iounit," ");
+ fprintf(iounit,"#%-2d in rule %s (line %d %s)\n",
+ count,lastOne->rname,lastOne->line,FileStr[lastOne->file]);
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpTreeF(FILE *f,int depth,Tree *tree,int across)
+#else
+void MR_dumpTreeF(f,depth,tree,across)
+ FILE *f;
+ Tree *tree;
+ int depth;
+ int across;
+#endif
+{
+ int newAcross=across;
+
+ if (tree == NULL ) return;
+ if (tree->down != NULL ) {
+ fprintf(output,"\n");
+ MR_outputIndent(depth);
+ fprintf(output, "(root =");
+ };
+ if (tree->token == ALT ) {
+ fprintf(output," %-16s","Alt");
+ } else if (tree->token==EpToken ) {
+ fprintf(output,"(%d)%13s",tree->v.rk," ");
+ } else {
+ fprintf(output," %-16s",TerminalString(tree->token));
+ };
+ if (tree->down != NULL) {
+ fprintf(output,"\n");
+ MR_outputIndent(depth+1);
+ MR_dumpTreeF(f,depth+1,tree->down,1);
+ newAcross=0;
+ fprintf(output,"\n");
+ MR_outputIndent(depth);
+ fprintf(output,")");
+ };
+ if (newAcross > 3) {
+ fprintf(output,"\n");
+ MR_outputIndent(depth);
+ newAcross=0;
+ };
+ MR_dumpTreeF(f,depth,tree->right,newAcross+1);
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpTreeX(int depth,Tree *tree,int across)
+#else
+void MR_dumpTreeX(depth,tree,across)
+ Tree *tree;
+ int depth;
+ int across;
+#endif
+{
+ MR_dumpTreeF(output,depth,tree,across);
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpTokenSet(FILE *f,int depth,set s)
+#else
+void MR_dumpTokenSet(f,depth,s)
+ FILE *f;
+ int depth;
+ set s;
+#endif
+{
+ int i;
+ int j;
+
+ unsigned *pdq;
+
+ if (set_nil(s)) {
+ fprintf(f,"\n");
+ MR_xxxIndent(f,depth+1);
+ fprintf(f,"nil\n");
+ return;
+ };
+
+ pdq=set_pdq(s);
+ require(pdq != NULL,"set_pdq failed");
+ i=0;
+ for (i=0 ; ; i=i+4) {
+ fprintf(f,"\n");
+ MR_xxxIndent(f,depth+1);
+ for (j=0; j < 4 ; j++) {
+ if (pdq[i+j] == nil) break;
+ fprintf(f," %-16s",TerminalString(pdq[i+j]));
+ };
+ if (pdq[i+j] == nil) break;
+ };
+ fprintf(f,"\n");
+ free( (char *) pdq);
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpPred1(int depth,Predicate *p,int withContext)
+#else
+void MR_dumpPred1(depth,p,withContext)
+ int depth;
+ Predicate *p;
+ int withContext;
+#endif
+{
+ unsigned k;
+
+ if (p == NULL) {
+ MR_outputIndent(depth);
+ fprintf(output,"The predicate is empty (or always true)\n\n");
+ return;
+ };
+ if (p->down != NULL) {
+ MR_outputIndent(depth);
+ if (p->inverted) {
+
+ /* MR14a Left out print expression in fprintf
+ Reported by Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de)
+ */
+
+ if (p->expr == PRED_AND_LIST) fprintf(output,"%s NAND (not AND) expr\n\n",p->expr);
+ if (p->expr == PRED_OR_LIST) fprintf(output,"%s NOR (not OR) expr\n\n",p->expr);
+ } else {
+ fprintf(output,"%s expr\n\n",p->expr);
+ };
+ } else {
+ MR_outputIndent(depth);
+ fprintf(output,"pred %s <<%s>>?\n",
+ (p->inverted ? " *not*" : ""),
+ (p->expr == NULL ? "null expr" : p->expr));
+ MR_outputIndent(depth+1);
+ fprintf(output," ");
+ fprintf(output," depth=k=%d",p->k);
+ if (p->source != NULL && p->source->guardpred) {
+ fprintf(output," (\"=>\" guard)");
+ }
+ if (p->source != NULL && p->source->ampersandPred != NULL) {
+ fprintf(output," (\"&&\" guard)");
+ };
+ k=set_int(p->completionSet);
+ if (k != nil) {
+ fprintf(output," Incomplete Set at k=%d !",k);
+ };
+ k=set_int(p->completionTree);
+ if (k != nil) {
+ fprintf(output," Incomplete Tree at k=%d !",k);
+ };
+ if (p->source != NULL) {
+ fprintf(output," rule %s line %d %s",
+ p->source->rname,p->source->line,FileStr[p->source->file]);
+ };
+ fprintf(output,"\n");
+ if (withContext &&
+ (HoistPredicateContext ||
+ ! set_nil(p->scontext[1]) ||
+ p->tcontext != NULL)) {
+ if (p->k == 1) {
+ MR_outputIndent(depth+1);
+ fprintf(output,"set context: ");
+ MR_dumpTokenSet(output,depth+1,p->scontext[1]);
+ }
+ if (p->k != 1) {
+ MR_outputIndent(depth+1);
+ fprintf(output,"tree context:");
+ if (p->tcontext == NULL) {
+ fprintf(output," null");
+ } else {
+ MR_dumpTreeX(depth+2,p->tcontext,0);
+ };
+ fprintf(output,"\n");
+ };
+ };
+ fprintf(output,"\n");
+ };
+ if (p->down != NULL) {
+ MR_dumpPred1(depth+1,p->down,withContext);
+ };
+ if (p->right != NULL) {
+ MR_dumpPred1(depth,p->right,withContext);
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpPred(Predicate *p,int withContext)
+#else
+void MR_dumpPred(p,withContext)
+ Predicate *p;
+ int withContext;
+#endif
+{
+ MR_dumpPred1(0,p,withContext);
+}
+
+#ifdef __USE_PROTOS
+Tree * MR_make_tree_from_set(set s)
+#else
+Tree * MR_make_tree_from_set(s)
+ set s;
+#endif
+{
+ Tree *t=NULL;
+ Tree *node;
+ Tree **tp=&t;
+ int i;
+
+ unsigned *pdq=set_pdq(s);
+
+ if (pdq != NULL) {
+ for (i=0 ; pdq[i] != nil ; i++) {
+ node=tnode( (int) pdq[i]);
+ *tp=node;
+ tp=&(node->right);
+ };
+ *tp=NULL;
+ free ( (char *) pdq);
+ };
+ return t;
+}
+
+#ifdef __USE_PROTOS
+void MR_check_pred_too_long(Predicate *p,set completion)
+#else
+void MR_check_pred_too_long(p,completion)
+ Predicate *p;
+ set completion;
+#endif
+{
+ if (p != NULL &&
+ p->source != NULL &&
+ ! p->source->predTooLong) {
+ if ( !set_nil(completion)) {
+ p->source->predTooLong=1;
+warnFL("It is unusual (but ok) for a semantic predicate to test context past the end of its own rule",
+ FileStr[p->source->file],p->source->line);
+ };
+ };
+}
+
+#ifdef __USE_PROTOS
+int MR_predicate_context_completed(Predicate *p)
+#else
+int MR_predicate_context_completed(p)
+ Predicate *p;
+#endif
+{
+ if (p == NULL) return 1;
+ if (p->expr != PRED_AND_LIST &&
+ p->expr != PRED_OR_LIST) {
+ if ( ! set_nil(p->completionSet)) return 0;
+ if ( ! set_nil(p->completionTree)) return 0;
+ };
+ return MR_predicate_context_completed(p->down) &
+ MR_predicate_context_completed(p->right);
+}
+
+#ifdef __USE_PROTOS
+Node * MR_advance(Node *n)
+#else
+Node * MR_advance(n)
+ Node *n;
+#endif
+{
+ if (n == NULL) return NULL;
+ switch (n->ntype) {
+ case nJunction: return ((Junction *)n)->p1;
+ case nToken: return ((TokNode *)n)->next;
+ case nRuleRef: return ((RuleRefNode *)n)->next;
+ case nAction: return ((ActionNode *)n)->next;
+ default: return NULL;
+ };
+ return NULL; /* MSVC 5.0 complains about missing return statement */
+}
+
+#ifdef __USE_PROTOS
+Junction * MR_find_endRule(Node *n)
+#else
+Junction * MR_find_endRule(n)
+ Node *n;
+#endif
+{
+ Node *next;
+ if (n == NULL) return NULL;
+ for (next=n; next != NULL; next=MR_advance(next)) {
+ if (next->ntype == nJunction &&
+ ( (Junction *) next)->jtype == EndRule) {
+ break;
+ };
+ };
+ return (Junction *)next;
+}
+
+/*
+ Intersection: a branch which is shorter is chosen
+ over one which is longer: (A B C) intersect (A B) yields (A B).
+
+ AND: a branch which is longer is chosen over the one
+ which is shorter: (A B C) AND (A B) yields (A B C)
+
+*/
+
+#ifdef __USE_PROTOS
+Tree *MR_computeTreeIntersection(Tree *l,Tree *r)
+#else
+Tree *MR_computeTreeIntersection(l,r)
+ Tree *l;
+ Tree *r;
+#endif
+{
+ Tree *result=NULL;
+ Tree **tail;
+ Tree *p;
+ Tree *q;
+ Tree *match;
+
+ if (l == NULL || r == NULL) return NULL;
+ for (p=l; p != NULL; p=p->right) {
+ require(p->token != EpToken,"MR_computeTreeIntersection: p->EpToken unexpected\n");
+ require (p->token != ALT,"MR_computeTreeIntersection: p->ALT unexpected\n");
+ };
+ for (q=r; q != NULL; q=q->right) {
+ require(q->token != EpToken,"MR_computeTreeIntersection: q->EpToken unexpected\n");
+ require(q->token != ALT,"MR_computeTreeIntersection: q->ALT unexpected\n");
+ };
+
+ result=tnode(ALT);
+ tail=&(result->down);
+
+ for (p=l; p != NULL ; p=p->right) {
+ for (q=r; q != NULL ; q=q->right) {
+ if (p->token == q->token) {
+ match=tnode(p->token);
+ match->down=MR_computeTreeIntersection(p->down,q->down);
+ *tail=match;
+ tail=&(match->right);
+ };
+ };
+ };
+
+ *tail=NULL;
+ result=tshrink(result);
+ result=tflatten( result );
+ result=tleft_factor( result );
+ return result;
+}
+
+/* the predicates which are ANDed together have a common
+ context: they must all have common roots. Thus the
+ AND operation is more like an OR operation because
+ branches which are longer are grafted onto shorter
+ branches of the AND tree. For instance combining
+ (A B C) with (A B C D) gives (A B C D). There
+ should never be a case of (A B C) and (A B D) because
+ they have the same context.
+
+ Actually, this may not be true once one throws in
+ guard predicates which are defined by the user, not
+ the context.
+*/
+
+/* requires input trees to be in "canonical" format */
+
+#ifdef __USE_PROTOS
+Tree *MR_computeTreeAND(Tree *l,Tree *r)
+#else
+Tree *MR_computeTreeAND(l,r)
+ Tree *l;
+ Tree *r;
+#endif
+{
+ Tree *result=NULL;
+ Tree **tail;
+ Tree *p;
+ Tree *q;
+ Tree *match;
+
+ if (l == NULL) return tdup(r);
+ if (r == NULL) return tdup(l);
+
+ for (p=l; p != NULL; p=p->right) {
+/**** require(p->token != EpToken,"MR_computeTreeAND: p->EpToken unexpected\n"); ****/
+ require (p->token != ALT,"MR_computeTreeAND: p->ALT unexpected\n");
+ };
+ for (q=r; q != NULL; q=q->right) {
+/**** require(q->token != EpToken,"MR_computeTreeAND: q->EpToken unexpected\n"); ****/
+ require(q->token != ALT,"MR_computeTreeAND: q->ALT unexpected\n");
+ };
+
+ result=tnode(ALT);
+ tail=&(result->down);
+
+ for (p=l; p != NULL ; p=p->right) {
+ for (q=r; q != NULL ; q=q->right) {
+ if (p->token == q->token) {
+ match=tnode(p->token);
+ match->down=MR_computeTreeAND(p->down,q->down);
+ *tail=match;
+ tail=&(match->right);
+ };
+ };
+ };
+
+ *tail=NULL;
+ result=tshrink(result);
+ result=tflatten( result );
+ result=tleft_factor( result );
+ return result;
+}
+
+#ifdef __USE_PROTOS
+void MR_union_plain_sets1(Predicate *p,set *theUnion)
+#else
+void MR_union_plain_sets1(p,theUnion)
+ Predicate *p;
+ set *theUnion;
+#endif
+{
+ if (p == NULL) return;
+ MR_union_plain_sets1(p->down,theUnion);
+ MR_union_plain_sets1(p->right,theUnion);
+ set_orin(theUnion,p->plainSet);
+ return;
+}
+
+#ifdef __USE_PROTOS
+set MR_union_plain_sets(Predicate *p)
+#else
+set MR_union_plain_sets(p)
+ Predicate *p;
+#endif
+{
+ set theUnion;
+
+ theUnion=empty;
+
+ MR_union_plain_sets1(p,&theUnion);
+ return theUnion;
+}
+
+/* does NOT left factor: do not want to merge
+ (A B) with (A) to get (A B)
+ in fact the opposite: (A B) with (A) gives (A)
+*/
+
+#ifdef __USE_PROTOS
+Tree *MR_compute_pred_tree_ctxXX(Predicate *p)
+#else
+Tree *MR_compute_pred_tree_ctxXX(p)
+ Predicate *p;
+#endif
+{
+ Tree *result=NULL;
+ Predicate *q;
+ Tree *t;
+
+ if (p == NULL) return NULL;
+
+/* this appears strange: why do we OR the context
+ of and AND predicate ? It is because of the way
+ that predicates are evaluated: if the context is
+ wrong then it's the same as if the predicate was
+ true. That means that even when one leg of an
+ AND has unmatched context, if the other leg has
+ matched context and is true then the predicate
+ succeeds. It's only when all the legs have unmatched
+ context that this one can skip evaluation of the
+ predicates.
+*/
+ if (p->expr == PRED_OR_LIST ||
+ p->expr == PRED_AND_LIST) {
+ for (q=p->down; q != NULL ; q=q->right) {
+ t=MR_compute_pred_tree_ctxXX(q);
+ result=tappend(result,t);
+ t=NULL;
+ };
+
+ result=tshrink(result);
+ result=tflatten( result );
+
+/* does NOT left factor: do not want to merge
+ (A B) with (A) to get (A B)
+ in fact the opposite: (A B) with (A) gives (A)
+*/
+
+/**** result=tleft_factor( result ); ****/
+ return result;
+ };
+
+#if 0
+** if (p->expr == PRED_AND_LIST) {
+**
+** Predicate *l;
+** Predicate *r;
+** Tree *l1;
+** Tree *r1;
+** Tree *prevl1;
+**
+** l=p->down;
+** require (l->right != NULL,"MR_compute_pred_tree - AND has only one child");
+**
+**/* l1 and r1 should already be in "canonical" format */
+**
+** l1=MR_compute_pred_tree(l);
+** for (r=l->right; r != NULL; r=r->right) {
+** r1=MR_compute_pred_tree(r);
+** prevl1=l1;
+** l1=MR_computeTreeAND(l1,r1);
+** Tfree(r1);
+** Tfree(prevl1);
+** };
+**
+**/* result from computeTreeAND should be in "canonical" format */
+**
+** result=l1;
+**
+**/* result of MR_computeTreeAND should be in "canonical" format */
+**
+** return result;
+** };
+#endif
+
+ if (p->k == 1) {
+ result=MR_make_tree_from_set(p->scontext[1]);
+ } else {
+ result=tdup(p->tcontext);
+ result=MR_remove_epsilon_from_tree(result);
+ result=tshrink(result);
+ result=tflatten(result);
+ result=tleft_factor(result);
+ };
+ return result;
+}
+
+#ifdef __USE_PROTOS
+void MR_pred_depth(Predicate *p,int *maxDepth)
+#else
+void MR_pred_depth(p,maxDepth)
+ Predicate *p;
+ int *maxDepth;
+#endif
+{
+ if (p == NULL) return;
+ if (p->expr != PRED_OR_LIST &&
+ p->expr != PRED_AND_LIST) {
+ if (p->k > *maxDepth) *maxDepth=p->k;
+ };
+ MR_pred_depth(p->down,maxDepth);
+ MR_pred_depth(p->right,maxDepth);
+}
+
+/* this computes the OR of all the contexts */
+
+#ifdef __USE_PROTOS
+set MR_compute_pred_set(Predicate *p)
+#else
+set MR_compute_pred_set(p)
+ Predicate *p;
+#endif
+{
+ set result;
+ Predicate *q;
+
+ result=empty;
+
+ if (p == NULL) return empty;
+
+ if (p->expr == PRED_OR_LIST ||
+ p->expr == PRED_AND_LIST) { /* yes, I do mean PRED_AND_LIST ! */
+ /* remember: r1: (A)? => <<p>>? r2; */
+ /* r2: (B)? => <<q>>? r3; */
+ set t;
+
+ t=empty;
+ result=empty;
+
+ for (q=p->down; q != NULL; q=q->right) {
+ t=MR_compute_pred_set(q);
+ set_orin(&result,t);
+ set_free(t);
+ };
+ return result;
+ } else if (p->k > 1) {
+ return empty;
+ } else {
+ return set_dup(p->scontext[1]);
+ };
+}
+
+#ifdef __USE_PROTOS
+set MR_First(int ck,Junction *j,set *incomplete)
+#else
+set MR_First(ck,j,incomplete)
+ int ck;
+ Junction *j;
+ set *incomplete;
+#endif
+{
+ Junction *p;
+ set tokensUsed;
+
+ tokensUsed=empty;
+
+ require(j->ntype==nJunction, "MR_First: non junction passed");
+
+ p = analysis_point((Junction *)j->p1);
+
+ REACH(p,ck,incomplete,tokensUsed);
+
+ return tokensUsed;
+}
+
+#ifdef __USE_PROTOS
+void MR_cleanup_pred_trees(Predicate *p)
+#else
+void MR_cleanup_pred_trees(p)
+ Predicate *p;
+#endif
+{
+ Tree *t;
+
+ if (p == NULL) return;
+ if (p->expr != PRED_OR_LIST &&
+ p->expr != PRED_AND_LIST) {
+ t=p->tcontext;
+ t=tshrink(t);
+ t=tflatten(t);
+ t=tleft_factor(t);
+ p->tcontext=t;
+ };
+ MR_cleanup_pred_trees(p->down);
+ MR_cleanup_pred_trees(p->right);
+}
+
+/* does NOT return canonical tree */
+
+#ifdef __USE_PROTOS
+Tree * MR_remove_epsilon_from_tree(Tree *t)
+#else
+Tree * MR_remove_epsilon_from_tree(t)
+ Tree *t;
+#endif
+{
+ if (t == NULL) return NULL;
+
+ /* I think ALT can be ignored as a special case */
+
+ if (t->token != EpToken) {
+ t->down=MR_remove_epsilon_from_tree(t->down);
+ t->right=MR_remove_epsilon_from_tree(t->right);
+ return t;
+ } else {
+ Tree *u;
+ u=MR_remove_epsilon_from_tree(t->right);
+ t->right=NULL;
+ Tfree(t);
+ return u;
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_complete_set(int predDepth,set *tokensUsed,set *incomplete)
+#else
+void MR_complete_set(predDepth,tokensUsed,incomplete)
+ int predDepth;
+ set *tokensUsed;
+ set *incomplete;
+#endif
+{
+ int i;
+ RuleRefNode *ruleRef;
+ set rk2;
+ set b;
+ int k2;
+ Junction *save_MR_RuleBlkWithHalt;
+
+ if (set_int(*incomplete) > (unsigned) predDepth) {
+ return;
+ };
+
+ require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,
+ "RuleRefStack and RuleBlkWithHaltStack not same size");
+
+ require(MR_RuleBlkWithHalt == NULL ||
+ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
+ "RuleBlkWithHalt has no halt set");
+
+ save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
+
+ if (MR_RuleBlkWithHalt != NULL) {
+ MR_RuleBlkWithHalt->end->halt=FALSE;
+ };
+
+ for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {
+ ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];
+ if (ruleRef == NULL) continue;
+
+ MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];
+ if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;
+
+ rk2=empty;
+ b=empty;
+
+ while ( !set_nil(*incomplete) ) {
+ k2=set_int(*incomplete);
+ if (k2 > predDepth) break; /* <=== another exit from loop */
+ set_rm(k2,*incomplete);
+ REACH(ruleRef->next,k2,&rk2,b);
+ set_orin(tokensUsed,b);
+ set_free(b);
+ };
+
+ if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;
+
+ set_orin(incomplete,rk2); /* remember what we couldn't do */
+ set_free(rk2);
+ if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */
+ };
+
+ MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;
+ if (MR_RuleBlkWithHalt != NULL) {
+ MR_RuleBlkWithHalt->end->halt=TRUE;
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_complete_tree(int predDepth,Tree **t,set *incomplete)
+#else
+void MR_complete_tree(predDepth,t,incomplete)
+ int predDepth;
+ Tree **t;
+ set *incomplete;
+#endif
+{
+ int i;
+ RuleRefNode *ruleRef;
+ set rk2;
+ Tree *u;
+ unsigned k2;
+ Junction *save_MR_RuleBlkWithHalt;
+ int saveConstrainSearch;
+
+ if (set_int(*incomplete) > (unsigned) predDepth) {
+ return;
+ };
+
+ require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count,
+ "RuleRefStack and RuleBlkWithHaltStack not same size");
+
+ require(MR_RuleBlkWithHalt == NULL ||
+ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
+ "RuleBlkWithHalt has no halt set");
+
+ save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
+ saveConstrainSearch=ConstrainSearch;
+ ConstrainSearch=0;
+
+ if (MR_RuleBlkWithHalt != NULL) {
+ MR_RuleBlkWithHalt->end->halt=FALSE;
+ };
+
+ for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) {
+ ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i];
+ if (ruleRef == NULL) continue;
+
+ MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i];
+
+ if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE;
+
+ rk2=empty;
+
+ while ( !set_nil(*incomplete) ) {
+ k2 = set_int(*incomplete);
+ if (k2 > (unsigned) predDepth) break; /* <=== another exit from loop */
+ set_rm(k2,*incomplete);
+ u = NULL;
+
+ TRAV(ruleRef->next,k2,&rk2,u);
+
+ /* any subtrees missing k2 tokens, add u onto end */
+
+ *t=tlink(*t,u,k2);
+ Tfree(u);
+ }
+
+ set_orin(incomplete,rk2); /* remember what we couldn't do */
+ set_free(rk2);
+
+ if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE;
+
+ if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */
+ };
+
+ MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt;
+
+ if (MR_RuleBlkWithHalt != NULL) {
+ MR_RuleBlkWithHalt->end->halt=TRUE;
+ };
+ ConstrainSearch=saveConstrainSearch;
+}
+
+#ifdef __USE_PROTOS
+void MR_complete_predicates(int predDepth,Predicate *pred)
+#else
+void MR_complete_predicates(predDepth,pred)
+ int predDepth;
+ Predicate *pred;
+#endif
+{
+ if (pred == NULL) return;
+ if (pred->expr != PRED_AND_LIST &&
+ pred->expr != PRED_OR_LIST) {
+ MR_complete_set(predDepth,&(pred->scontext[1]),&(pred->completionSet));
+ MR_complete_tree(predDepth,&(pred->tcontext),&(pred->completionTree));
+ };
+ MR_complete_predicates(predDepth,pred->down);
+ MR_complete_predicates(predDepth,pred->right);
+}
+
+#ifdef __USE_PROTOS
+Junction * MR_junctionWithoutP2(Junction *j)
+#else
+Junction * MR_junctionWithoutP2(j)
+ Junction *j;
+#endif
+{
+ Junction *thisAlt;
+
+/* don't want to follow p2 to the next alternative of this rule */
+/* insert a generic node with null p2 if necessary */
+/* however FIRST requires a junction */
+
+ thisAlt=j;
+ if (thisAlt->p2 != NULL) {
+ if (thisAlt->p1->ntype == nJunction) {
+ thisAlt=(Junction *) thisAlt->p1;
+ } else {
+ thisAlt=newJunction();
+ thisAlt->p1=j->p1;
+ thisAlt->rname=j->rname;
+ thisAlt->file=j->file;
+ thisAlt->line=j->line;
+ j->p1=(Node *)thisAlt;
+ };
+ };
+ return thisAlt;
+}
+
+#ifdef __USE_PROTOS
+int MR_tree_equ(Tree *big, Tree *small) {
+#else
+int MR_tree_equ(big,small)
+ Tree *big;
+ Tree *small;
+{
+#endif
+
+ Tree *b;
+ Tree *s;
+ int bcount=0;
+ int scount=0;
+
+ if (small == NULL && big == NULL) return 1;
+ if (small == NULL) return 0;
+ if (big == NULL) return 0;
+
+ if (small->token == ALT) {
+ require(small->right == NULL,
+ "MR_tree_equ: small: ALT node has siblings");
+ return MR_tree_equ(big,small->down);
+ };
+ if (big->token == ALT) {
+ require(big->right == NULL,
+ "MR_tree_equ: big: ALT node has siblings");
+ return MR_tree_equ(big->down,small);
+ };
+ for (s=small; s != NULL; s=s->right) {
+ scount++;
+ require(s->token != EpToken,"MR_tree_equ: s->EpToken unexpected\n");
+ };
+ for (b=big; b != NULL; b=b->right) {
+ bcount++;
+ require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpected\n");
+ };
+
+ if (bcount != scount) return 0;
+
+ for (s=small; s != NULL; s=s->right) {
+ for (b=big; b!= NULL; b=b->right) {
+ if (s->token == b->token) {
+ if (MR_tree_equ(b->down,s->down)) goto next_s;
+ };
+ };
+ return 0;
+next_s:
+ continue;
+ };
+ return 1;
+}
+
+/* this does not compare sources - only contexts ! */
+
+#ifdef __USE_PROTOS
+int MR_identicalContext(Predicate *p,Predicate *q)
+#else
+int MR_identicalContext(p,q)
+ Predicate *p;
+ Predicate *q;
+#endif
+{
+ if (p->k != q->k) return 0;
+ require ( (p->tcontext == NULL) == (q->tcontext == NULL),
+ "tcontext inconsistent");
+ if (p->k == 1) {
+ return set_equ(p->scontext[1],q->scontext[1]);
+ } else {
+ return MR_tree_equ(p->tcontext,q->tcontext);
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_reportSetSuppression(int predDepth,
+ set predSet,set plainSet,Junction *jPred,Junction *jPlain,Predicate *p)
+#else
+void MR_reportSetSuppression(predDepth,predSet,plainSet,jPred,jPlain,p)
+ int predDepth;
+ set predSet;
+ set plainSet;
+ Junction *jPred;
+ Junction *jPlain;
+ Predicate *p;
+#endif
+{
+ if (InfoP) {
+ fprintf(output,"\n#if 0\n\n");
+ fprintf(output,"Hoisting of predicate suppressed by alternative without predicate.\n");
+ fprintf(output,"The alt without the predicate includes all cases where the predicate is false.\n\n");
+ fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]);
+ if (jPlain != NULL) {
+ fprintf(output," WITHOUT predicate: line %d %s\n",jPlain->line,FileStr[jPlain->file]);
+ } else {
+ fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)\n");
+ };
+ if (predDepth == 1) {
+ fprintf(output,"\nThe context set for the predicate:\n");
+ MR_dumpTokenSet(output,1,predSet);
+ };
+ fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n");
+ MR_dumpTokenSet(output,1,plainSet);
+ fprintf(output,"\nThe predicate:\n\n");
+ MR_dumpPred1(1,p,1);
+ fprintf(output,"Chain of referenced rules:\n\n");
+ MR_dumpPredRuleRefStack(output,4);
+ fprintf(output,"\n#endif\n");
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_reportSetRestriction(int predDepth,set predSet,set plainSet,
+ Junction *jPred,Junction *jPlain,Predicate *origPred,Predicate *newPred)
+#else
+void MR_reportSetRestriction(predDepth,predSet,plainSet,jPred,jPlain,origPred,newPred)
+ int predDepth;
+ set predSet;
+ set plainSet;
+ Junction *jPred;
+ Junction *jPlain;
+ Predicate *origPred;
+ Predicate *newPred;
+#endif
+{
+ set intersect;
+
+ intersect=empty;
+
+ if (! InfoP) return;
+ fprintf(output,"\n#if 0\n\n");
+ fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead set\n");
+ fprintf(output," between the alternative with the semantic predicate and one without\n");
+ fprintf(output,"Without this restriction the alternative without the predicate could not\n");
+ fprintf(output," be reached when input matched the context of the predicate and the predicate\n");
+ fprintf(output," was false.\n\n");
+
+ fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]);
+ if (jPlain != NULL) {
+ fprintf(output," WITHOUT predicate: line %d %s\n",jPlain->line,FileStr[jPlain->file]);
+ } else {
+ fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)\n");
+ };
+ if (predDepth == 1) {
+ fprintf(output,"\nThe original context set for the predicate:\n");
+ MR_dumpTokenSet(output,1,predSet);
+ };
+ fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n");
+ MR_dumpTokenSet(output,1,plainSet);
+ if (predDepth == 1) {
+ fprintf(output,"\nThe intersection of the two sets\n");
+ intersect=set_and(predSet,plainSet);
+ MR_dumpTokenSet(output,1,intersect);
+ set_free(intersect);
+ };
+ fprintf(output,"\nThe original predicate:\n\n");
+ MR_dumpPred1(1,origPred,1);
+ fprintf(output,"The new (modified) form of the predicate:\n\n");
+ MR_dumpPred1(1,newPred,1);
+ fprintf(output,"#endif\n");
+}
+
+/* don't use Pass3 by itself unless you know that inverted is not important */
+
+#ifdef __USE_PROTOS
+Predicate * MR_removeRedundantPredPass3(Predicate *p)
+#else
+Predicate * MR_removeRedundantPredPass3(p)
+ Predicate *p;
+#endif
+{
+ Predicate *q;
+
+ if (p == NULL) return NULL;
+ p->right=MR_removeRedundantPredPass3(p->right);
+ p->down=MR_removeRedundantPredPass3(p->down);
+ if (p->redundant) {
+ q=p->right;
+ p->right=NULL;
+ predicate_free(p);
+ return q;
+ };
+ if (p->expr == PRED_AND_LIST ||
+ p->expr == PRED_OR_LIST) {
+ if (p->down == NULL) {
+ q=p->right;
+ p->right=NULL;
+ predicate_free(p);
+ return q;
+ };
+ if (p->down != NULL && p->down->right == NULL) {
+ q=p->down;
+ q->right=p->right;
+ p->right=NULL;
+ p->down=NULL;
+ return q;
+ };
+ };
+ return p;
+}
+
+#ifdef __USE_PROTOS
+void MR_removeRedundantPredPass2(Predicate *p)
+#else
+void MR_removeRedundantPredPass2(p)
+ Predicate *p;
+#endif
+{
+ Predicate *q;
+
+ if (p == NULL) return;
+
+ if (p->expr == PRED_AND_LIST) {
+ for (q=p->down ; q != NULL ; q=q->right) {
+ MR_removeRedundantPredPass2(q);
+ if (q->isConst) {
+ if (q->constValue == 0) {
+ p->isConst=1;
+ p->constValue=0;
+ return;
+ } else {
+ q->redundant=1;
+ };
+ };
+ };
+ };
+
+ if (p->expr == PRED_OR_LIST) {
+ for (q=p->down ; q != NULL ; q=q->right) {
+ MR_removeRedundantPredPass2(q);
+ if (q->isConst) {
+ if (q->constValue == 0) {
+ q->redundant=1;
+ } else {
+ p->isConst=1;
+ p->constValue=1;
+ return;
+ };
+ };
+ };
+ };
+
+ return;
+}
+
+#if 0
+ this totally ignores the implications of guarded predicates
+ in which the part after the guard could possibly cover a predicate.
+ that would be much harder:
+
+ rule : (A)? => <<p>>? sub1; /* 1 */
+ | (B)? => <<r>>? sub2 /* 2 */
+ sub1 : (A)? => <<q>>? A B /* 3 */
+ | B /* 4 - suppresses line 2 */
+ ;
+#endif
+
+#ifdef __USE_PROTOS
+void MR_apply_restriction1(Predicate *pred,set *plainSet,int *changed)
+#else
+void MR_apply_restriction1(pred,plainSet,changed)
+ Predicate *pred;
+ set *plainSet;
+ int *changed;
+#endif
+{
+ if (pred == NULL) return;
+ MR_apply_restriction1(pred->right,plainSet,changed);
+ if (pred->down != NULL) {
+ MR_apply_restriction1(pred->down,plainSet,changed);
+ } else {
+ set t;
+ if (pred->k == 1) {
+ t=set_dif(pred->scontext[1],*plainSet);
+ if (*changed == 0 &&
+ !set_equ(t,pred->scontext[1])) {
+ *changed=1;
+ };
+ if (set_nil(t)) {
+ pred->redundant=1;
+ };
+ set_free(pred->scontext[1]);
+ pred->scontext[1]=t;
+ };
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_orin_plainSet(Predicate *p,set plainSet)
+#else
+void MR_orin_plainSet(p,plainSet)
+ Predicate *p;
+ set plainSet;
+#endif
+{
+ if (p == NULL) return;
+ MR_orin_plainSet(p->down,plainSet);
+ MR_orin_plainSet(p->right,plainSet);
+ set_orin(&p->plainSet,plainSet);
+}
+
+Predicate *PRED_SUPPRESS;
+
+#ifdef __USE_PROTOS
+Predicate * MR_find_in_aSubBlk(Junction *alt)
+#else
+Predicate * MR_find_in_aSubBlk(alt)
+ Junction *alt;
+#endif
+{
+ Predicate *root=NULL;
+ Predicate **tail=NULL;
+
+ Junction *p;
+
+ int nAlts=0;
+ Junction **jList;
+ Predicate **predList;
+ int *matchList;
+ set predSet;
+ int i;
+ int j;
+ int m;
+ int predDepth;
+ set incomplete;
+ set union_plainSet;
+ set setChange;
+ int changed;
+ Predicate *newPred;
+ set setDif;
+ Predicate *origPred;
+ int depth1=1; /* const int */
+ set *plainContext;
+ set plainSet;
+
+ predSet=empty;
+ incomplete=empty;
+ union_plainSet=empty;
+ setChange=empty;
+ setDif=empty;
+ plainSet=empty;
+
+ if (PRED_SUPPRESS == NULL) {
+ PRED_SUPPRESS=new_pred();
+ PRED_SUPPRESS->expr="Predicate Suppressed";
+ };
+
+ /* this section just counts the number of "interesting" alternatives */
+ /* in order to allocate arrays */
+
+ for (p=alt; p!=NULL; p=(Junction *)p->p2) {
+ /* ignore empty alts */
+ if ( p->p1->ntype != nJunction ||
+ ((Junction *)p->p1)->jtype != EndBlk ) {
+ nAlts++;
+ };
+ };
+
+ /* if this is a (...)+ block then don't count the last alt because
+ it can't be taken until at least one time through the block.
+ In other words it isn't a real choice until the (...)+ is entered
+ at which point the hoisting issue is moot.
+ Maybe look at "ignore" instead ?
+ */
+
+ if (alt->jtype == aPlusBlk) {
+ nAlts--;
+ };
+
+ jList=(Junction **)calloc(nAlts,sizeof(Junction *));
+ require(jList!=NULL,"cannot allocate MR_find_in_aSubBlk jList");
+
+ plainContext=(set *)calloc(nAlts,sizeof(set));
+ require(plainContext!=NULL,"cannot allocate MR_find_in_aSubBlk plainContext");
+ for (m=0; m < nAlts; m++) plainContext[m]=empty;
+
+ predList=(Predicate **)calloc(nAlts,sizeof(Predicate *));
+ require(predList!=NULL,"cannot allocate MR_find_in_aSubBlk predList");
+
+ matchList=(int *)calloc(nAlts,sizeof(int));
+ require(matchList!=NULL,"cannot allocate MR_find_in_aSubBlk matchList");
+
+ /* this section just fills in the arrays previously allocated */
+ /* the most interesting one is matchList[] */
+ /* */
+ /* bit 0 => this alt has a semantic pred which is "covered" */
+ /* by an alt without a semantic pred. Don't hoist. */
+
+ for (i=0,p=alt;
+ p!=NULL && i<nAlts;
+ i++,p=(Junction *)p->p2) {
+
+ /* ignore empty alts */
+
+ if ( p->p1->ntype != nJunction ||
+ ((Junction *)p->p1)->jtype != EndBlk ) {
+ jList[i]=MR_junctionWithoutP2(p);
+ predList[i]=find_predicates(p->p1); /* should be jList ????? */
+ if (predList[i] != NULL) {
+ MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */
+ plainContext[i]=MR_union_plain_sets(predList[i]);
+ } else {
+ MR_set_reuse(&plainSet);
+ MR_set_reuse(&incomplete);
+ plainSet=MR_First(depth1,jList[i],&incomplete);
+ MR_complete_set(depth1,&plainSet,&incomplete);
+ require(set_nil(incomplete),"couldn't complete k=1");
+ plainContext[i]=plainSet;
+ plainSet=empty;
+ };
+ set_orin(&union_plainSet,plainContext[i]);
+ };
+ };
+
+ if (nAlts == 1) {
+ goto EXIT_SIMPLE;
+ };
+
+/*
+ * Looking for cases where alt i has a semantic pred and alt j does not.
+ * Don't care about cases where lookahead for semantic predicates overlap
+ * because normal predicate hoisting does the correct thing automatically.
+ * Don't care about cases where lookahead for alts without semantic predicates
+ * overlap because normal prediction does the correct thing automatically.
+ *
+ * When we find such a case check for one of three subcases:
+ *
+ * 1. if lookahead for alt i is contained in the lookahead for any
+ * alt j then ignore semantic predicate of alt i
+ * 2. if lookahead for alt i is not contained in the lookahead for
+ * any alt j then add add predicate i to the OR list to be hoisted
+ * 3. if lookahead for alt i overlaps the lookahead for some alt j then
+ * add a dummy semantic predicate for alt j
+ *
+ * There is an implicit assumption that the context of all alternatives following
+ * the rule being processed here are identical (but may vary from hoist to
+ * hoist depending on the place where the rule was invoked that led to hoisting
+ * these predicates. In othere words in the fragment:
+ *
+ * ( <<a>>? a1 a2 a3 | <<b>>? b1 b2 b3 )
+ *
+ * both a3 and b3 have the same follow sets because they are both at the end of
+ * alternatives in the same block.
+ */
+
+ for (i=0; i < nAlts; i++) {
+ if (jList[i] == NULL) continue;
+ if (predList[i] == NULL) continue;
+
+ /* if the predicate depth turns out to be one token only */
+ /* then it is can be easily represented as a set and */
+ /* compared to the junction set create by MR_First() */
+
+ predDepth=0;
+ MR_pred_depth(predList[i],&predDepth);
+ require (predDepth >= 1,"MR_find_in_aSubBlk: pred depth < 1");
+ require (predDepth <= CLL_k,"MR_find_in_aSubBlk: predDepth > CLL_k");
+
+ /* complete predicates to predDepth
+ If completed to depth=1 then the context would be incomplete.
+ The context would be truncated and the predicate simplify routine
+ would have incomplete information. It would lead to
+ either false matches of failure to find true matches.
+ */
+
+ MR_complete_predicates(predDepth,predList[i]);
+
+ if (predList[i] != NULL) {
+ MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */
+ };
+
+ /* If the predicate depth is 1 then it is possible to suppress
+ a predicate completely using a single plain alt. Check for suppression
+ by a single plain alt first because it gives better messages. If that
+ fails try the union of all the plain alts.
+ */
+
+ if (predDepth == 1) {
+
+ MR_set_reuse(&predSet);
+ predSet=MR_compute_pred_set(predList[i]); /* ignores k>1 predicates */
+
+ for (j=0; j < nAlts; j++) {
+ if (jList[j] == NULL) continue;
+ if (j == i) continue;
+
+ MR_set_reuse(&setDif);
+ setDif=set_dif(predSet,plainContext[j]);
+ if (set_nil(setDif)) {
+ matchList[i] |= 1;
+ MR_reportSetSuppression(predDepth,predSet,plainContext[j],jList[i],jList[j],predList[i]);
+ predicate_free(predList[i]);
+ predList[i]=PRED_SUPPRESS;
+ goto next_i;
+ };
+
+ }; /* end loop on j */
+
+ changed=0;
+
+ /* predicate_dup is only to give good error messages */
+ /* remember to do a predicate_free() */
+
+ origPred=predicate_dup(predList[i]);
+ MR_apply_restriction1(predList[i],&union_plainSet,&changed);
+ if (changed) {
+
+ /* don't use Pass3 by itself unless you know that inverted is not important */
+
+ newPred=MR_removeRedundantPredPass3(predList[i]);
+ newPred=MR_predSimplifyALL(newPred);
+ if (newPred == NULL) {
+ matchList[i] |= 1;
+ MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],
+ NULL,origPred);
+ predList[i]=PRED_SUPPRESS;
+ } else {
+ MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],
+ NULL,origPred,newPred);
+ predList[i]=newPred;
+ };
+ };
+ predicate_free(origPred);
+ origPred=NULL;
+ };
+
+ /*
+ If the predicate depth is > 1 then it can't be suppressed completely
+ because the code doesn't support inspection of such things. They're
+ much messier than k=1 sets.
+ */
+
+ if (predDepth > 1 ) {
+
+ changed=0;
+
+ /* predicate_dup is only to give good error messages */
+ /* remember to do a predicate_free() */
+
+ origPred=predicate_dup(predList[i]);
+ MR_apply_restriction1(predList[i],&union_plainSet,&changed);
+ if (changed) {
+ newPred=MR_removeRedundantPredPass3(predList[i]);
+ newPred=MR_predSimplifyALL(newPred);
+ if (newPred == NULL) {
+ matchList[i] |= 1;
+ MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i],
+ NULL,origPred);
+ predList[i]=PRED_SUPPRESS;
+ } else {
+ MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i],
+ NULL,origPred,newPred);
+ predList[i]=newPred;
+ };
+ };
+ predicate_free(origPred);
+ origPred=NULL;
+ };
+next_i:
+ continue;
+ };
+
+EXIT_SIMPLE:
+
+ root = new_pred();
+ root->expr=PRED_OR_LIST;
+ tail = &(root->down);
+
+ for (i=0 ; i< nAlts ; i++) {
+ if (jList[i] == NULL) continue;
+
+ if (predList[i] == NULL) {
+ continue;
+ } else if ( (matchList[i] & 1) != 0) {
+ if (predList[i] != PRED_SUPPRESS) {
+ predicate_free(predList[i]);
+ };
+ continue;
+ };
+
+ /* make an OR list of predicates */
+
+ *tail=predList[i];
+ tail=&(predList[i]->right);
+ };
+
+ /* if just one pred, remove OR root */
+
+ if (root->down == NULL) {
+ predicate_free(root);
+ root=NULL;
+ } else if (root->down->right == NULL) {
+ Predicate *p=root->down;
+ root->down=NULL;
+ predicate_free(root);
+ root=p;
+ }
+
+ root=MR_predSimplifyALL(root);
+
+ MR_orin_plainSet(root,union_plainSet);
+
+ set_free(predSet);
+ set_free(union_plainSet);
+ set_free(incomplete);
+ set_free(setChange);
+ set_free(setDif);
+
+ for (m=0; m < nAlts; m++) set_free(plainContext[m]);
+
+ free ( (char *) jList);
+ free ( (char *) predList);
+ free ( (char *) matchList);
+ free ( (char *) plainContext);
+
+ return root;
+}
+
+#ifdef __USE_PROTOS
+void MR_predContextPresent(Predicate *p,int *allHaveContext,int *noneHaveContext)
+#else
+void MR_predContextPresent(p,allHaveContext,noneHaveContext)
+ Predicate *p;
+ int *allHaveContext;
+ int *noneHaveContext;
+#endif
+{
+ if (p == NULL) return;
+ MR_predContextPresent(p->right,allHaveContext,noneHaveContext);
+ if (p->expr != PRED_AND_LIST &&
+ p->expr != PRED_OR_LIST) {
+ if (set_nil(p->scontext[1]) == 0 ||
+ (p->tcontext != NULL)) {
+ *noneHaveContext=0;
+ } else {
+ *allHaveContext=0;
+ };
+ };
+ MR_predContextPresent(p->down,allHaveContext,noneHaveContext);
+}
+
+#ifdef __USE_PROTOS
+int MR_pointerStackPush(PointerStack *ps,void *dataPointer)
+#else
+int MR_pointerStackPush(ps,dataPointer)
+ PointerStack *ps;
+ void *dataPointer;
+#endif
+{
+ void **newStack;
+ int newSize;
+ int i;
+
+ if (ps->count == ps->size) {
+ newSize=20+ps->size*2;
+ newStack=(void **)calloc(newSize,sizeof(void *));
+ require (newStack != NULL,"cannot allocate PointerStack");
+ for (i=0; i < ps->size; i++) {
+ newStack[i]=ps->data[i];
+ };
+ if (ps->data != NULL) free( (char *) ps->data);
+ ps->data=newStack;
+ ps->size=newSize;
+ };
+ ps->data[ps->count]=dataPointer;
+ ps->count++;
+ return ps->count-1;
+}
+
+#ifdef __USE_PROTOS
+void * MR_pointerStackPop(PointerStack *ps)
+#else
+void * MR_pointerStackPop(ps)
+ PointerStack *ps;
+#endif
+{
+ void *dataPointer;
+
+ require(ps->count > 0,"MR_pointerStackPop underflow");
+
+ dataPointer=ps->data[ps->count-1];
+ ps->data[ps->count-1]=NULL;
+ (ps->count)--;
+ return dataPointer;
+}
+
+#ifdef __USE_PROTOS
+void * MR_pointerStackTop(PointerStack *ps)
+#else
+void * MR_pointerStackTop(ps)
+ PointerStack *ps;
+#endif
+{
+ require(ps->count > 0,"MR_pointerStackTop underflow");
+ return ps->data[ps->count-1];
+}
+
+#ifdef __USE_PROTOS
+void MR_pointerStackReset(PointerStack *ps)
+#else
+void MR_pointerStackReset(ps)
+ PointerStack *ps;
+#endif
+{
+ int i;
+ if (ps->data != NULL) {
+ for (i=0; i < ps->count ; i++) {
+ ps->data[i]=NULL;
+ };
+ };
+ ps->count=0;
+}
+
+#ifdef __USE_PROTOS
+Junction *MR_nameToRuleBlk(char *name)
+#else
+Junction *MR_nameToRuleBlk(name)
+ char *name;
+#endif
+{
+ RuleEntry *q;
+
+ require (RulePtr != NULL,"MR_nameToRule: RulePtr not initialized");
+
+ if (name == NULL) return NULL;
+
+ q = (RuleEntry *) hash_get(Rname,name);
+
+ if ( q == NULL ) {
+ return NULL;
+ } else {
+ return RulePtr[q->rulenum];
+ };
+}
+
+#ifdef __USE_PROTOS
+Junction * MR_ruleReferenced(RuleRefNode *rrn)
+#else
+Junction * MR_ruleReferenced(rrn)
+ RuleRefNode *rrn;
+#endif
+{
+ return MR_nameToRuleBlk(rrn->text);
+}
+
+#ifdef __USE_PROTOS
+void MR_comparePredLeaves(Predicate *me,Predicate *myParent,Predicate *him,Predicate *hisParent)
+#else
+void MR_comparePredLeaves(me,myParent,him,hisParent)
+ Predicate *me;
+ Predicate *myParent;
+ Predicate *him;
+ Predicate *hisParent;
+#endif
+{
+ if (me == NULL) return;
+ if (me == him) {
+ MR_comparePredLeaves(me->right,myParent,him,hisParent);
+ return;
+ } else if (me->expr == PRED_AND_LIST ||
+ me->expr == PRED_OR_LIST) {
+ MR_comparePredLeaves(me->down,me,him,hisParent);
+ MR_comparePredLeaves(me->right,myParent,him,hisParent);
+ return;
+ } else {
+ if (me->source != NULL) {
+
+ /* predicate->invert can be set only in the predEntry predicates */
+ /* thus they are only visible after the predEntry predicates have been "unfolded" */
+
+ int sameSource=(me->source == him->source);
+ int sameInvert=1 &
+ (1 + me->inverted + him->inverted + me->source->inverted + him->source->inverted);
+ int samePredEntry=(me->source->predEntry != NULL
+ && him->source->predEntry != NULL
+ && me->source->predEntry == him->source->predEntry);
+ if (sameInvert && (sameSource || samePredEntry)) {
+ if (MR_identicalContext(me,him)) {
+
+ /* identical predicates */
+
+ if (hisParent->expr == PRED_OR_LIST &&
+ myParent->expr == PRED_OR_LIST) {
+ me->redundant=1;
+ } else if (hisParent->expr == PRED_AND_LIST &&
+ myParent->expr == PRED_AND_LIST) {
+ me->redundant=1;
+ } else if ( (hisParent->expr == PRED_OR_LIST &&
+ myParent->expr == PRED_AND_LIST)
+ ||
+ (hisParent->expr == PRED_AND_LIST &&
+ myParent->expr == PRED_OR_LIST)
+ ) {
+ myParent->redundant=1;
+ } else {
+ require (0,"MR_comparePredLeaves: not both PRED_LIST");
+ };
+ };
+ }; /* end same source or same predEntrr with same invert sense */
+
+ /* same predEntry but opposite invert sense */
+
+ if (!sameInvert && (sameSource || samePredEntry)) {
+ if (MR_identicalContext(me,him)) {
+ if (hisParent->expr == PRED_OR_LIST &&
+ myParent->expr == PRED_OR_LIST) {
+ myParent->isConst=1;
+ myParent->constValue=1;
+ } else if (hisParent->expr == PRED_AND_LIST &&
+ myParent->expr == PRED_AND_LIST) {
+ myParent->isConst=1;
+ myParent->constValue=0;
+ } else if ( (hisParent->expr == PRED_OR_LIST &&
+ myParent->expr == PRED_AND_LIST)
+ ||
+ (hisParent->expr == PRED_AND_LIST &&
+ myParent->expr == PRED_OR_LIST)
+ ) {
+ me->redundant=1;
+ } else {
+ require (0,"MR_comparePredLeaves: not both PRED_LIST");
+ };
+ };
+ }; /* end same predEntry with opposite invert sense */
+ };
+
+ MR_comparePredLeaves(me->right,myParent,him,hisParent);
+ return;
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_removeRedundantPredPass1(Predicate *me,Predicate *myParent)
+#else
+void MR_removeRedundantPredPass1(me,myParent)
+ Predicate *me;
+ Predicate *myParent;
+#endif
+{
+ if (me == NULL) return;
+ if (me->redundant) {
+ MR_removeRedundantPredPass1(me->right,myParent);
+ return;
+ };
+ if (me->expr == PRED_AND_LIST ||
+ me->expr == PRED_OR_LIST) {
+ MR_removeRedundantPredPass1(me->down,me);
+ MR_removeRedundantPredPass1(me->right,myParent);
+ } else {
+ require (me->source != NULL,"me->source == NULL");
+ if (myParent != NULL) {
+ MR_comparePredLeaves(myParent->down,myParent,me,myParent);
+ };
+ MR_removeRedundantPredPass1(me->right,myParent);
+ };
+}
+
+/* pretty much ignores things with the inverted bit set */
+
+#ifdef __USE_PROTOS
+Predicate *MR_predFlatten(Predicate *p)
+#else
+Predicate *MR_predFlatten(p)
+ Predicate *p;
+#endif
+{
+ if (p == NULL) return NULL;
+ if (p->expr == PRED_OR_LIST
+ || p->expr == PRED_AND_LIST) {
+
+ Predicate *child;
+ Predicate *gchild;
+ Predicate **tail;
+ Predicate *next;
+ char *PRED_XXX_LIST=p->expr;
+
+ require (p->down != NULL,"MR_predFlatten AND/OR no child");
+
+
+ p->down=MR_predFlatten(p->down);
+ p->right=MR_predFlatten(p->right);
+ child=p->down;
+ if (child->right == NULL) {
+ child->right=p->right;
+ p->right=NULL;
+ p->down=NULL;
+ if (p->inverted) child->inverted=!child->inverted;
+ predicate_free(p);
+ return child;
+ };
+
+ /* make a single list of all children and grandchildren */
+
+ tail=&(p->down);
+ for (child=p->down; child != NULL; child=next) {
+ if (child->expr != PRED_XXX_LIST
+ || child->inverted
+ || child->predEntry != NULL) {
+ *tail=child;
+ tail=&(child->right);
+ next=child->right;
+ } else {
+ for (gchild=child->down;
+ gchild != NULL;
+ gchild=gchild->right) {
+ *tail=gchild;
+ tail=&(gchild->right);
+ };
+ next=child->right;
+ child->right=NULL;
+ child->down=NULL;
+ predicate_free(child);
+ };
+ };
+ *tail=NULL;
+ return p;
+ } else {
+ p->right=MR_predFlatten(p->right);
+ return p;
+ };
+}
+
+static char *alwaysFalseWarning=NULL;
+
+#ifdef __USE_PROTOS
+Predicate *checkPredicateConflict(Predicate *p)
+#else
+Predicate *checkPredicateConflict(p)
+ Predicate *p;
+#endif
+{
+ if (p->isConst) {
+ if (p->constValue == 1) {
+ predicate_free(p);
+ return NULL;
+ } else {
+ if (InfoP && !p->conflictReported) {
+ p->conflictReported=1;
+ fprintf(output,"\n#if 0\n\n");
+ fprintf(output,"The following predicate expression will always be false:\n\n");
+ MR_dumpPred1(1,p,1);
+ fprintf(output,"\n#endif\n");
+ };
+
+ if (alwaysFalseWarning != CurRule) {
+ alwaysFalseWarning=CurRule;
+ if (InfoP) {
+ warnNoFL(eMsg1("one (or more) predicate expression hoisted into rule \"%s\" are always false \
+- see output file for more information",CurRule));
+ } else {
+ warnNoFL(eMsg1("one (or more) predicate expressions hoisted into rule \"%s\" are always false \
+- use \"-info p\" for more information",CurRule));
+ };
+ };
+ };
+ };
+ return p;
+}
+
+
+#ifdef __USE_PROTOS
+int MR_countPredNodes(Predicate *p)
+#else
+int MR_countPredNodes(p)
+ Predicate *p;
+#endif
+{
+ if (p == NULL) return 0;
+ return 1 + MR_countPredNodes(p->down) + MR_countPredNodes(p->right);
+}
+
+#ifdef __USE_PROTOS
+Predicate *MR_predSimplifyALLX(Predicate *p,int skipPass3)
+#else
+Predicate *MR_predSimplifyALLX(p,skipPass3)
+ Predicate *p;
+ int skipPass3;
+#endif
+{
+ int countBefore;
+ int countAfter;
+
+ countAfter=MR_countPredNodes(p);
+
+ do {
+ if (p == NULL) return NULL;
+ if (p->right == NULL && p->down == NULL) return p;
+ countBefore=countAfter;
+ MR_simplifyInverted(p,0);
+ p=MR_predFlatten(p);
+ MR_removeRedundantPredPass1(p,NULL);
+ MR_removeRedundantPredPass2(p);
+ if (! skipPass3) {
+ p=checkPredicateConflict(p);
+ p=MR_removeRedundantPredPass3(p);
+ };
+ countAfter=MR_countPredNodes(p);
+ } while (countBefore != countAfter);
+
+ return p;
+}
+
+#ifdef __USE_PROTOS
+Predicate *MR_predSimplifyALL(Predicate *p)
+#else
+Predicate *MR_predSimplifyALL(p)
+ Predicate *p;
+#endif
+{
+ return MR_predSimplifyALLX(p,0);
+}
+
+#ifdef __USE_PROTOS
+void MR_releaseResourcesUsedInRule(Node *n)
+#else
+void MR_releaseResourcesUsedInRule(n)
+ Node *n;
+#endif
+{
+ Node *next;
+ Junction *j;
+ int i;
+
+ if (n == NULL) return;
+ if (n->ntype == nJunction) {
+ j=(Junction *) n;
+
+ if (j->predicate != NULL) {
+ predicate_free(j->predicate);
+ j->predicate=NULL;
+ };
+ for (i=0; i< CLL_k; i++) {
+ set_free(j->fset[i]);
+ j->fset[i]=empty;
+ };
+ if (j->ftree != NULL) {
+ Tfree(j->ftree);
+ j->ftree=NULL;
+ };
+ if (j->jtype == EndRule) return;
+ if (j->jtype != RuleBlk && j->jtype != EndBlk) {
+ if (j->p2 != NULL && !j->ignore) { /* MR11 */
+ MR_releaseResourcesUsedInRule(j->p2);
+ };
+ };
+ };
+ next=MR_advance(n);
+ MR_releaseResourcesUsedInRule(next);
+}
+
+#ifdef __USE_PROTOS
+int MR_allPredLeaves(Predicate *p)
+#else
+int MR_allPredLeaves(p)
+ Predicate *p;
+#endif
+{
+ Predicate *q;
+
+ if (p == NULL) return 1;
+
+ for (q=p; q != NULL; q=q->right) {
+ if (q->down != NULL) return 0;
+ };
+ return 1;
+}
+
+/* make sure it works for the last rule in a file */
+
+#ifdef __USE_PROTOS
+int MR_offsetFromRule(Node *n)
+#else
+int MR_offsetFromRule(n)
+ Node *n;
+#endif
+{
+ Junction *j;
+ int offset=(-1);
+
+ for (j=SynDiag; j != NULL; j=(Junction *)j->p2) {
+
+ require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block");
+
+ if (n->file < j->file) {
+ return offset;
+ };
+ if (n->file == j->file) {
+ if (n->line < j->line) {
+ return (offset < 0) ? 0 : offset;
+ } else {
+ offset=n->line - j->line;
+ if (offset == 0) return 0;
+ };
+ };
+ };
+ return offset;
+}
+
+#define ruleNameMax 50
+
+static char ruleNameStatic1[ruleNameMax];
+static char ruleNameStatic2[ruleNameMax+10];
+
+#ifdef __USE_PROTOS
+char * MR_ruleNamePlusOffset(Node *n)
+#else
+char * MR_ruleNamePlusOffset(n)
+ Node *n;
+#endif
+{
+ int offset=MR_offsetFromRule(n);
+
+ strncpy(ruleNameStatic1,n->rname,ruleNameMax);
+ if (offset < 0) {
+ sprintf(ruleNameStatic2,"%s/?",ruleNameStatic1);
+ } else {
+ sprintf(ruleNameStatic2,"%s/%d",ruleNameStatic1,offset+1);
+ };
+ return ruleNameStatic2;
+}
+
+#ifdef __USE_PROTOS
+int MR_max_height_of_tree(Tree *t)
+#else
+int MR_max_height_of_tree(t)
+ Tree *t;
+#endif
+{
+ int h;
+ int height=0;
+ Tree *u;
+
+ if (t == NULL) return 0;
+
+ require (t->token != ALT && t->token != EpToken,"MR_max_height_of_tree ALT or EpToken");
+
+ for (u=t; u != NULL; u=u->right) {
+ h=MR_max_height_of_tree(u->down)+1;
+ if (h > height) height=h;
+ };
+ return height;
+}
+
+#ifdef __USE_PROTOS
+int MR_all_leaves_same_height(Tree *t,int depth)
+#else
+int MR_all_leaves_same_height(t,depth)
+ Tree *t;
+ int depth;
+#endif
+{
+ if (t == NULL) {
+ return (depth==0);
+ };
+
+ require (t->token != ALT && t->token != EpToken,"MR_all_leaves_same_height ALT or EpToken");
+
+ if (depth == 0) {
+ return 0;
+ } else {
+ if ( ! MR_all_leaves_same_height(t->down,depth-1)) {
+ return 0;
+ };
+ if (t->right == NULL) {
+ return 1;
+ } else {
+ return MR_all_leaves_same_height(t->right,depth);
+ };
+ };
+}
+
+#ifdef __USE_PROTOS
+void MR_projectTreeOntoSet(Tree *tree,int ck,set *ckset)
+#else
+void MR_projectTreeOntoSet(tree,ck,ckset)
+ Tree *tree;
+ int ck;
+ set *ckset;
+#endif
+{
+ if (tree == NULL) return;
+
+ require(tree->token != EpToken,"MR_projectTreeOntoSet: EpToken unexpected\n");
+
+ MR_projectTreeOntoSet(tree->right,ck,ckset);
+ if (tree->token == ALT) {
+ MR_projectTreeOntoSet(tree->down,ck,ckset);
+ } else {
+ if (ck > 1) {
+ MR_projectTreeOntoSet(tree->down,ck-1,ckset);
+ } else {
+ set_orel(tree->token,ckset);
+ };
+ };
+}
+
+#ifdef __USE_PROTOS
+int MR_comparePredicates(Predicate *a,Predicate *b)
+#else
+int MR_comparePredicates(a,b)
+ Predicate *a;
+ Predicate *b;
+#endif
+{
+ Predicate *p;
+ Predicate *q;
+
+ if (a == b) return 1;
+ if (a == NULL || b == NULL ) return 0;
+ if (a->down == NULL && b->down == NULL) {
+
+ /* predicate->invert can be set only in the predEntry predicates */
+ /* thus they are only visible after the predEntry predicates have been "unfolded" */
+
+ int sameSource=(a->source == b->source);
+ int sameInvert= 1 & (1 +a->inverted + b->inverted +
+ a->source->inverted + b->source->inverted);
+ int samePredEntry=(a->source->predEntry != NULL
+ && b->source->predEntry != NULL
+ && a->source->predEntry == b->source->predEntry);
+ if (sameInvert && (sameSource || samePredEntry)) {
+ if (MR_identicalContext(a,b)) {
+ return 1;
+ };
+ };
+ return 0;
+ };
+ if (a->down == NULL || b->down == NULL) return 0;
+ if (a->expr != b->expr) return 0;
+
+ for (p=a->down; p != NULL; p=p->right) {
+ for (q=b->down; q != NULL; q=q->right) {
+ if (MR_comparePredicates(p,q)) goto NEXT_P;
+ };
+ return 0;
+NEXT_P:
+ continue;
+ };
+ return 1;
+}
+
+/*
+ * action->inverted can be set only when a predicate symbol appears in
+ * a rule: "rule : <<!XXX>>? X". It cannot be set under any
+ * other circumstances. In particular it cannot be set by
+ * "#pred NotA !A" or by "#pred Nota <<!A>>?". The first case
+ * creates a predEntry and the predicate expression of that predEntry
+ * has inverted set. In the second case, the code for handling "!"
+ * is only present in buildAction, which is not called by the #pred
+ * semantic routines, only when a <<...>>? is recognized as part of
+ * a rule definition.
+ *
+ * predicate->inverted can only be set by a predicate created by a #pred
+ * expression, such as "#pred NotA !A" or "#pred NotXY ! (X && Y) or
+ * "#pred XbarY !(X && Y)". In particular, it cannot be set by any
+ * predicate expression occurring under any other circumstances.
+ * The #pred predicate expressions are stored with in predEntry->pred
+ * and do not normally appear anywhere else until the predicates are
+ * "unfolded" in order to recognize redundancies, conflicts, and
+ * tautologies.
+ *
+ * The unfold routine expands all references to #pred expressions.
+ *
+ * The simplifyInvert goes through and propagates the invert bit so that
+ * all OR and AND nodes are un-inverted.
+ *
+ * Note that !(A and B) => (!A or !B)
+ * !(A or B) => (!A and !B)
+ *
+ * MR_unfold() is called to expand predicate symbols by replacing predicates
+ * that reference predicate entries with the copies of the predicate entries.
+ * Each reference receives a duplicate of the original. This is necessary
+ * because the next phase involves simplification and removal of redundant
+ * predicate nodes. Anyway, the point I'm making is that predicate->invert
+ * should not be set in any predicate until it has been expanded.
+ *
+ * This is a recursive structure, but there is no need for "recursive expansion"
+ * by which I mean a predicate symbol refers to other predicate symbols which
+ * must also be expanded.
+ *
+ * Recursive expansion is *not* performed by this routine because it is not
+ * necessary. Expansion of references is performed by predPrimary when
+ * a new predicate symbol is created by referring to others in the pred expr.
+ */
+
+#ifdef __USE_PROTOS
+Predicate *MR_unfold(Predicate *pred)
+#else
+Predicate *MR_unfold(pred)
+ Predicate *pred;
+#endif
+{
+ Predicate *result;
+
+ if (pred == NULL) return NULL;
+
+ pred->right=MR_unfold(pred->right);
+
+ if (pred->down == NULL) {
+ if (pred->source->predEntry != NULL) {
+ if (pred->source->predEntry->pred == NULL) {
+ ; /* do nothing */ /* a reference to a literal #pred (perhaps with "!" */
+ } else {
+ result=predicate_dup_without_context(pred->source->predEntry->pred);
+ if (pred->inverted) {
+ result->inverted=!result->inverted;
+ };
+ if (pred->source->inverted) {
+ result->inverted=!result->inverted;
+ };
+ result->right=pred->right;
+ pred->right=NULL;
+ predicate_free(pred);
+/*** result=MR_unfold(result); *** not necessary */ /* recursive expansion */
+ return result;
+ };
+ } else {
+ ; /* do nothing */ /* an inline literal predicate */
+ };
+ } else {
+ pred->down=MR_unfold(pred->down);
+ };
+ return pred;
+}
+
+/* this should be called immediately after MR_unfold() and
+ at no other times
+*/
+
+#ifdef __USE_PROTOS
+void MR_simplifyInverted(Predicate *pred,int inverted)
+#else
+void MR_simplifyInverted(pred,inverted)
+ Predicate *pred;
+ int inverted;
+#endif
+{
+ int newInverted;
+
+ if (pred == NULL) return;
+
+ MR_simplifyInverted(pred->right,inverted);
+
+ newInverted= 1 & (inverted + pred->inverted);
+
+ if (pred->down == NULL) {
+ pred->inverted=newInverted;
+ } else {
+ if (newInverted != 0) {
+ if (pred->expr == PRED_AND_LIST) {
+ pred->expr=PRED_OR_LIST;
+ } else {
+ pred->expr=PRED_AND_LIST;
+ };
+ };
+ pred->inverted=0;
+ MR_simplifyInverted(pred->down,newInverted);
+ };
+}
+
+/* only remove it from AND and OR nodes, not leaves */
+
+#ifdef __USE_PROTOS
+void MR_clearPredEntry(Predicate *p)
+#else
+void MR_clearPredEntry(p)
+ Predicate *p;
+#endif
+{
+ if (p == NULL) return;
+ MR_clearPredEntry(p->down);
+ MR_clearPredEntry(p->right);
+ if (p->down != NULL) p->predEntry=NULL;
+}
+
+
+#ifdef __USE_PROTOS
+void MR_orphanRules(FILE *f)
+#else
+void MR_orphanRules(f)
+ FILE *f;
+#endif
+{
+ set a;
+ Junction *p;
+ unsigned e;
+ RuleEntry *re;
+
+ a=empty;
+
+ if (! InfoO) return;
+
+ for (p=SynDiag; p!=NULL; p = (Junction *)p->p2) {
+ if ( (Junction *) (p->end)->p1 == NULL) {
+ re=(RuleEntry *) hash_get(Rname,p->rname);
+ require (re != NULL,"RuleEntry == NULL");
+ set_orel(re->rulenum, &a);
+ }
+ }
+
+ if (set_deg(a) > 1) {
+ fprintf(f,"note: Start rules: {");
+ for (; !set_nil(a); set_rm(e,a)) {
+ e=set_int(a);
+ fprintf(f," %s",RulePtr[e]->rname);
+ };
+ fprintf(f," }\n");
+ };
+ set_free( a );
+}
+
+/* merge (X Y) and (X) to create (X) */
+
+static int *mergeChain;
+static Tree *mergeTree;
+
+#ifdef __USE_PROTOS
+Tree *MR_merge_tree_contexts_client(Tree *t,int chain[])
+#else
+Tree *MR_merge_tree_contexts_client(t,chain)
+ Tree *t;
+ int chain[];
+#endif
+{
+ if (t == NULL) return NULL;
+ if (chain[0] == 0) {
+ Tree *u=t->right;
+ t->right=NULL;
+ Tfree(t);
+ return MR_merge_tree_contexts_client(u,&chain[0]);
+ }
+ if (chain[0] == t->token) {
+ t->down=MR_merge_tree_contexts_client(t->down,&chain[1]);
+ };
+ t->right=MR_merge_tree_contexts_client(t->right,&chain[0]);
+ return t;
+}
+
+#ifdef __USE_PROTOS
+void MR_iterateOverTreeContexts(Tree *t,int chain[])
+#else
+void MR_iterateOverTreeContexts(t,chain)
+ Tree *t;
+ int chain[];
+#endif
+{
+ if (t == NULL) return;
+ chain[0]=t->token;
+ if (t->down != NULL) {
+ MR_iterateOverTreeContexts(t->down,&chain[1]);
+ } else {
+ MR_merge_tree_contexts_client(mergeTree,mergeChain);
+ };
+ MR_iterateOverTreeContexts(t->right,&chain[0]);
+ chain[0]=0;
+}
+
+#ifdef __USE_PROTOS
+Tree *MR_merge_tree_contexts(Tree *t)
+#else
+Tree *MR_merge_tree_contexts(t)
+ Tree *t;
+#endif
+{
+ int h=MR_max_height_of_tree(t);
+
+ mergeTree=t;
+ mergeChain=(int *) calloc(h+1,sizeof(int));
+ require (mergeChain != NULL,"MR_merge_tree_contexts: can't alloc chain");
+ MR_iterateOverTreeContexts(t,mergeChain);
+ t=tshrink(t);
+ t=tflatten(t);
+ t=tleft_factor(t);
+ free ( (char *) mergeChain);
+ mergeChain=NULL;
+ return t;
+}
+
+#ifdef __USE_PROTOS
+Tree *MR_compute_pred_tree_context(Predicate *p)
+#else
+Tree *MR_compute_pred_tree_context(p)
+ Predicate *p;
+#endif
+{
+ Tree *t;
+
+ t=MR_compute_pred_tree_ctxXX(p);
+ MR_merge_tree_contexts(t);
+ return t;
+}
+
+#ifdef __USE_PROTOS
+void MR_guardPred_plainSet(ActionNode *anode,Predicate *pred)
+#else
+void MR_guardPred_plainSet(anode,pred)
+ ActionNode *anode;
+ Predicate *pred;
+#endif
+{
+ Junction *j;
+ Predicate *workPred;
+ set maskSet;
+
+ maskSet=empty;
+
+ if (!MRhoisting) return;
+
+ /* it doesn't really matter whether the predicate has
+ depth k=1 or k>1 because we're not really looking
+ at the predicate itself, just the stuff "behind"
+ the predicate.
+ */
+
+ /* shouldn't have to worry about REACHing off the end
+ of the rule containing the predicate because the
+ Rule->end->halt should have been set already by the
+ the code which handles RuleRef nodes.
+
+ We don't want to REACH off the end of the rule because
+ this would give the "global" follow context rather than
+ the "local" context.
+
+ r1a : (A)? => <<p>>? r2 (A|B)
+ r1b : (A)? => <<p>>? r2 (A|C)
+ r2 : ();
+
+ For r1a we want follow of predicate = {A B}
+ we want plainSet = {B}
+ For r1b we want follow of predicate = {A C}
+ we want plainSet = {C}
+ */
+
+ require (anode->next->ntype == nJunction,"MR_guardpred_plainSet not Junction");
+ j=(Junction *)(anode->next);
+
+ workPred=predicate_dup_without_context(pred);
+ workPred->k=1;
+ workPred->scontext[1]=MR_First(1,j, &(workPred->completionSet) );
+ MR_complete_predicates(1,workPred);
+ if (pred->k == 1) {
+ maskSet=pred->scontext[1];
+ } else {
+ MR_projectTreeOntoSet(pred->tcontext,1,&maskSet);
+ }
+ pred->plainSet=set_dif(workPred->scontext[1],maskSet);
+ predicate_free(workPred);
+}
+
+/*******************************************************************************/
+
+static Tree * suppressTree;
+static int * suppressChain; /* element 0 not used */
+static set * suppressSets;
+static Node * suppressNode;
+static int suppressChainLength;
+int MR_SuppressSearch=0;
+static int suppressSucceeded;
+static Predicate * suppressPredicate;
+
+#ifdef __USE_PROTOS
+int MR_isChain(Tree *t)
+#else
+int MR_isChain(t)
+ Tree *t;
+#endif
+{
+ Tree *u;
+
+ for (u=t; u != NULL; u=u->down) {
+ if (u->right != NULL) return 0;
+ }
+ return 1;
+}
+
+#ifdef __USE_PROTOS
+int MR_suppressK_client(Tree *tree,int tokensInChain[])
+#else
+int MR_suppressK_client(tree,tokensInChain)
+ Tree *tree;
+ int tokensInChain[];
+#endif
+{
+ int i;
+ set *save_fset;
+ int save_ConstrainSearch;
+ set incomplete;
+ Tree *t;
+
+ suppressSucceeded=0; /* volatile */
+
+ if (suppressSets == NULL) {
+ suppressSets=(set *) calloc (CLL_k+1,sizeof(set));
+ require (suppressSets != NULL,"MR_suppressK_client: suppressSets alloc");
+ };
+
+ for (suppressChainLength=1;
+ tokensInChain[suppressChainLength+1] != 0;
+ suppressChainLength++) {};
+
+ require (suppressChainLength != 0,"MR_suppressK_client: chain empty");
+
+ for (i=1 ; i <= suppressChainLength ; i++) {
+ set_clr(suppressSets[i]);
+ set_orel( (unsigned) tokensInChain[i],
+ &suppressSets[i]);
+ };
+
+ save_fset=fset;
+ save_ConstrainSearch=ConstrainSearch;
+
+ fset=suppressSets;
+
+ MR_SuppressSearch=1;
+ MR_AmbSourceSearch=1;
+ MR_MaintainBackTrace=1;
+ ConstrainSearch=1;
+
+ maxk = suppressChainLength;
+
+ incomplete=empty;
+ t=NULL;
+
+/*** constrain = &(fset[1]); ***/
+
+ MR_setConstrainPointer(&(fset[1])); /* MR18 */
+
+ MR_pointerStackReset(&MR_BackTraceStack);
+
+ TRAV(suppressNode,maxk,&incomplete,t);
+
+ Tfree(t);
+
+ require (set_nil(incomplete),"MR_suppressK_client TRAV incomplete");
+ require (MR_BackTraceStack.count == 0,
+ "MR_suppressK_client: MR_BackTraceStack.count != 0");
+ set_free(incomplete);
+
+ ConstrainSearch=save_ConstrainSearch;
+ fset=save_fset;
+
+ MR_AmbSourceSearch=0;
+ MR_MaintainBackTrace=0;
+ MR_SuppressSearch=0;
+ return suppressSucceeded;
+}
+
+#ifdef __USE_PROTOS
+Tree * MR_iterateOverTreeSuppressK(Tree *t,int chain[])
+#else
+Tree * MR_iterateOverTreeSuppressK(t,chain)
+ Tree *t;
+ int chain[];
+#endif
+{
+ if (t == NULL) return NULL;
+ t->right=MR_iterateOverTreeSuppressK(t->right,&chain[0]);
+ chain[0]=t->token;
+ if (t->down != NULL) {
+ t->down=MR_iterateOverTreeSuppressK(t->down,&chain[1]);
+ if (t->down == NULL) {
+ Tree *u=t->right;
+ t->right=NULL;
+ Tfree(t);
+ chain[0]=0;
+ return u;
+ };
+ } else {
+ MR_suppressK_client(suppressTree,suppressChain);
+ if (suppressSucceeded) {
+ Tree *u=t->right;
+ t->right=NULL;
+ Tfree(t);
+ chain[0]=0;
+ return u;
+ };
+ };
+ chain[0]=0;
+ return t;
+}
+
+/* @@@ */
+
+#ifdef __USE_PROTOS
+Predicate * MR_suppressK(Node *j,Predicate *p)
+#else
+Predicate * MR_suppressK(j,p)
+ Node *j;
+ Predicate *p;
+#endif
+{
+ Predicate *result;
+ int guardPred=0;
+ int ampersandPred=0;
+ Node *nodePrime;
+
+ if (! MRhoistingk) {
+ return p;
+ }
+
+ if (! MRhoisting) return p;
+ if (CLL_k == 1) return p;
+
+ if (suppressChain == NULL) {
+ suppressChain=(int *) calloc(CLL_k+2,sizeof(int));
+ require (suppressChain != NULL,"MR_suppressK: can't allocate chain");
+ }
+
+ if (p == NULL) return NULL;
+
+ if (j->ntype == nJunction) {
+ nodePrime=(Node *) MR_junctionWithoutP2( (Junction *) j);
+ } else {
+ nodePrime=j;
+ };
+
+ p->down=MR_suppressK(j,p->down);
+ p->right=MR_suppressK(j,p->right);
+ if (p->down != NULL) {
+ result=p;
+ goto EXIT;
+ };
+ if (p->k == 1) {
+ result=p;
+ goto EXIT;
+ };
+
+ if (p->source != NULL) {
+ if (p->source->guardpred != NULL) guardPred=1;
+ if (p->source->ampersandPred != NULL) ampersandPred=1;
+ }
+
+ suppressPredicate=p;
+ suppressNode=nodePrime; /* was j*/
+
+ suppressTree=p->tcontext;
+
+ if (guardPred || ampersandPred) {
+ p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);
+ if (p->tcontext == NULL) {
+ predicate_free(p);
+ result=NULL;
+ goto EXIT;
+ };
+ } else {
+ if (MR_isChain(p->tcontext)) {
+ p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]);
+ if (p->tcontext == NULL) {
+ predicate_free(p);
+ result=NULL;
+ goto EXIT;
+ };
+ }
+ }
+ result=p;
+EXIT:
+ return result;
+}
+
+#ifdef __USE_PROTOS
+void MR_suppressSearchReport(void)
+#else
+void MR_suppressSearchReport()
+#endif
+{
+ int i;
+ Node *p;
+ TokNode *tn;
+ int depth;
+ set setAnd;
+
+ /* number of tokens in back trace stack matches length of chain */
+
+ depth=0;
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ p=(Node *) MR_BackTraceStack.data[i];
+ if (p->ntype == nToken) depth++;
+ };
+
+ require (depth == suppressChainLength,"depth > suppressChainLength");
+
+ /* token codes match chain */
+
+ depth=0;
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ p=(Node *) MR_BackTraceStack.data[i];
+ if (p->ntype != nToken) continue;
+ tn=(TokNode *) p;
+ depth++;
+ if (set_nil(tn->tset)) {
+ require(set_el( (unsigned) tn->token,fset[depth]),
+ "MR_suppressSearchReport: no match to #token in chain");
+ } else {
+ setAnd=set_and(fset[depth],tn->tset);
+ require(!set_nil(setAnd),
+ "MR_suppressSearchReport: no match to #token set in chain");
+ set_free(setAnd);
+ };
+ };
+
+ /* have a match - now remove it from the predicate */
+
+ suppressSucceeded=1;
+
+ if (suppressSucceeded) {
+ fprintf(output,"\n");
+ fprintf(output,"#if 0\n");
+ fprintf(output,"\n");
+ fprintf(output,"Part (or all) of predicate with depth > 1 suppressed by ");
+ fprintf(output,"alternative without predicate\n\n");
+ MR_dumpPred(suppressPredicate,1);
+ fprintf(output,"The token sequence which is suppressed:");
+ fprintf(output," (");
+ for (i=1; i <= suppressChainLength; i++) {
+ fprintf(output," %s",TerminalString(suppressChain[i]));
+ };
+ fprintf(output," )\n");
+ fprintf(output,"The sequence of references which generate that sequence of tokens:\n\n");
+
+ MR_backTraceDumpItemReset();
+
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);
+ };
+ fprintf(output,"\n");
+ fprintf(output,"#endif\n");
+ }
+}
+
+#ifdef __USE_PROTOS
+void MR_markCompromisedRule(Node *n)
+#else
+void MR_markCompromisedRule(n)
+ Node *n;
+#endif
+{
+ RuleEntry *q;
+ Node *mark=NULL;
+ Junction *j;
+
+ if (n->ntype == nRuleRef) {
+ mark=(Node *) MR_ruleReferenced( (RuleRefNode *) n);
+ } else if (n->ntype == nToken) {
+ mark=n;
+ } else if (n->ntype == nJunction) {
+ j=(Junction *)n;
+ switch (j->jtype) {
+ case aOptBlk:
+ case aLoopBlk:
+ case RuleBlk:
+ case EndRule:
+ case aPlusBlk:
+ case aLoopBegin:
+ mark=n;
+ break;
+ default:
+ break;
+ };
+ }
+
+ if (mark == NULL) return;
+
+ require (RulePtr != NULL,"RulePtr not initialized");
+
+ q = (RuleEntry *) hash_get(Rname,mark->rname);
+ require (q != NULL,"RuleEntry not found");
+ set_orel(q->rulenum,&MR_CompromisedRules);
+}
+
+#ifdef __USE_PROTOS
+void MR_alphaBetaTraceReport(void)
+#else
+void MR_alphaBetaTraceReport()
+#endif
+{
+ int i;
+
+ if (! AlphaBetaTrace) return;
+
+ MR_AlphaBetaMessageCount++;
+
+ fprintf(output,"\n");
+ fprintf(output,"#if 0\n");
+ fprintf(output,"\n");
+ fprintf(output,"Trace of references leading to attempt to compute the follow set of\n");
+ fprintf(output,"alpha in an \"(alpha)? beta\" block. It is not possible for antlr to\n");
+ fprintf(output,"compute this follow set because it is not known what part of beta has\n");
+ fprintf(output,"already been matched by alpha and what part remains to be matched.\n");
+ fprintf(output,"\n");
+ fprintf(output,"Rules which make use of the incorrect follow set will also be incorrect\n");
+ fprintf(output,"\n");
+
+ MR_backTraceDumpItemReset();
+
+ for (i=0; i < MR_BackTraceStack.count ; i++) {
+ MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]);
+ if (i < MR_BackTraceStack.count-1) {
+ MR_markCompromisedRule( (Node *) MR_BackTraceStack.data[i]);
+ };
+ };
+ fprintf(output,"\n");
+ fprintf(output,"#endif\n");
+}
+
+#ifdef __USE_PROTOS
+void MR_dumpRuleSet(set s)
+#else
+void MR_dumpRuleSet(s)
+ set s;
+#endif
+{
+ unsigned *cursor;
+ unsigned *origin=set_pdq(s);
+
+ require(origin != NULL,"set_pdq failed");
+
+ if (RulePtr == NULL) {
+ fprintf(stderr,"RulePtr[] not yet initialized");
+ } else {
+ for (cursor=origin; *cursor != nil ; cursor++) {
+/**** if (cursor != origin) fprintf(stderr,","); ****/
+ fprintf(stderr," %s",RulePtr[*cursor]->rname);
+ fprintf(stderr,"\n");
+ };
+ free( (char *) origin);
+ };
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/parser.dlg b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/parser.dlg
new file mode 100644
index 00000000..6f043212
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/parser.dlg
@@ -0,0 +1,1387 @@
+<<
+/* parser.dlg -- DLG Description of scanner
+ *
+ * Generated from: antlr.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include "pcctscfg.h"
+#include "set.h"
+#include <ctype.h>
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#define zzcr_attr(attr,tok,t)
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+LOOKAHEAD
+
+void
+#ifdef __USE_PROTOS
+zzerraction(void)
+#else
+zzerraction()
+#endif
+{
+ (*zzerr)("invalid token");
+ zzadvance();
+ zzskip();
+}
+>>
+
+<<%%lexaction
+
+/* maintained, but not used for now */
+set AST_nodes_refd_in_actions = set_init;
+int inAlt = 0;
+set attribsRefdFromAction = set_init; /* MR20 */
+int UsedOldStyleAttrib = 0;
+int UsedNewStyleLabel = 0;
+#ifdef __USE_PROTOS
+char *inline_set(char *);
+#else
+char *inline_set();
+#endif
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+/* MR1 in DLG action */
+
+int tokenActionActive=0; /* MR1 */
+
+
+>>
+
+<<%%lexaction
+
+
+static char *
+#ifdef __USE_PROTOS
+getFileNameFromTheLineInfo(char *toStr, char *fromStr)
+#else
+getFileNameFromTheLineInfo(toStr, fromStr)
+char *toStr, *fromStr;
+#endif
+{
+ int i, j, k;
+
+ if (!fromStr || !toStr) return toStr;
+
+ /* find the first " */
+
+ for (i=0;
+ (i<MaxFileName) &&
+ (fromStr[i] != '\n') &&
+ (fromStr[i] != '\r') &&
+ (fromStr[i] != '\"');
+ i++) /* nothing */ ;
+
+ if ( (i == MaxFileName) ||
+ (fromStr[i] == '\n') ||
+ (fromStr[i] == '\r') ) {
+ return toStr;
+}
+
+ /* find the second " */
+
+ for (j=i+1;
+(j<MaxFileName) &&
+(fromStr[j] != '\n') &&
+(fromStr[j] != '\r') &&
+(fromStr[j] != '\"');
+j++) /* nothing */ ;
+
+ if ((j == MaxFileName) ||
+(fromStr[j] == '\n') ||
+(fromStr[j] == '\r') ) {
+ return toStr;
+}
+
+ /* go back until the last / or \ */
+
+ for (k=j-1;
+(fromStr[k] != '\"') &&
+(fromStr[k] != '/') &&
+(fromStr[k] != '\\');
+k--) /* nothing */ ;
+
+ /* copy the string after " / or \ into toStr */
+
+ for (i=k+1; fromStr[i] != '\"'; i++) {
+toStr[i-k-1] = fromStr[i];
+}
+
+ toStr[i-k-1] = '\0';
+
+ return toStr;
+}
+
+/* MR14 end of a block to support #line in antlr source code */
+
+
+>>
+
+<<%%lexaction
+
+#ifdef __USE_PROTOS
+void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */
+#else
+void mark_label_used_in_sem_pred(le) /* MR10 */
+LabelEntry *le;
+#endif
+{
+ TokNode *tn;
+ require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");
+ tn=(TokNode *)le->elem;
+ require (tn->label != 0,"mark_label_used... TokNode has no label");
+ tn->label_used_in_semantic_pred=1;
+}
+>>
+
+
+%%START
+
+@
+ <<
+ NLA = Eof;
+ /* L o o k F o r A n o t h e r F i l e */
+ {
+ FILE *new_input;
+ new_input = NextFile();
+ if ( new_input == NULL ) { NLA=Eof; return; }
+ fclose( input );
+ input = new_input;
+ zzrdstream( input );
+ zzskip(); /* Skip the Eof (@) char i.e continue */
+ }
+ >>
+
+[\t\ ]+
+ <<
+ NLA = 76;
+ zzskip();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 77;
+ zzline++; zzskip();
+ >>
+
+\[
+ <<
+ NLA = 78;
+ zzmode(ACTIONS); zzmore();
+ istackreset();
+ pushint(']');
+ >>
+
+\<\<
+ <<
+ NLA = 79;
+ action_file=CurFile; action_line=zzline;
+ zzmode(ACTIONS); zzmore();
+ list_free(&CurActionLabels,0); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ istackreset();
+ pushint('>');
+ >>
+
+\"
+ <<
+ NLA = 80;
+ zzmode(STRINGS); zzmore();
+ >>
+
+/\*
+ <<
+ NLA = 81;
+ zzmode(COMMENTS); zzskip();
+ >>
+
+\*/
+ <<
+ NLA = 82;
+ warn("Missing /*; found dangling */"); zzskip();
+ >>
+
+//
+ <<
+ NLA = 83;
+ zzmode(CPP_COMMENTS); zzskip();
+ >>
+
+#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)
+ <<
+ NLA = 84;
+
+ zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();
+ getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);
+ >>
+
+#line ~[\n\r]* (\n|\r|\r\n)
+ <<
+ NLA = 85;
+
+ zzline++; zzmore();
+ >>
+
+\>\>
+ <<
+ NLA = 86;
+ warn("Missing <<; found dangling \>\>"); zzskip();
+ >>
+
+.
+ <<
+ NLA = WildCard;
+ >>
+
+\@
+ <<
+ NLA = 88;
+ FoundException = 1; /* MR6 */
+ FoundAtOperator = 1;
+ >>
+
+{\\}#pragma
+ <<
+ NLA = Pragma;
+ >>
+
+{\\}#FirstSetSymbol
+ <<
+ NLA = FirstSetSymbol;
+ >>
+
+{\\}#header
+ <<
+ NLA = 94;
+ >>
+
+{\\}#first
+ <<
+ NLA = 95;
+ >>
+
+{\\}#parser
+ <<
+ NLA = 96;
+ >>
+
+{\\}#tokdefs
+ <<
+ NLA = 97;
+ >>
+
+\}
+ <<
+ NLA = 98;
+ >>
+
+class
+ <<
+ NLA = 99;
+ >>
+
+\{
+ <<
+ NLA = 102;
+ >>
+
+!
+ <<
+ NLA = 103;
+ >>
+
+\<
+ <<
+ NLA = 104;
+ >>
+
+\>
+ <<
+ NLA = 105;
+ >>
+
+:
+ <<
+ NLA = 106;
+ >>
+
+;
+ <<
+ NLA = 107;
+ >>
+
+{\\}#lexaction
+ <<
+ NLA = 108;
+ >>
+
+{\\}#lexmember
+ <<
+ NLA = 109;
+ >>
+
+{\\}#lexprefix
+ <<
+ NLA = 110;
+ >>
+
+{\\}#pred
+ <<
+ NLA = 111;
+ >>
+
+\|\|
+ <<
+ NLA = 112;
+ >>
+
+&&
+ <<
+ NLA = 113;
+ >>
+
+\(
+ <<
+ NLA = 114;
+ >>
+
+\)
+ <<
+ NLA = 115;
+ >>
+
+{\\}#lexclass
+ <<
+ NLA = 116;
+ >>
+
+{\\}#errclass
+ <<
+ NLA = 117;
+ >>
+
+{\\}#tokclass
+ <<
+ NLA = 118;
+ >>
+
+..
+ <<
+ NLA = 119;
+ >>
+
+{\\}#token
+ <<
+ NLA = 120;
+ >>
+
+=
+ <<
+ NLA = 121;
+ >>
+
+[0-9]+
+ <<
+ NLA = 122;
+ >>
+
+\|
+ <<
+ NLA = 123;
+ >>
+
+\~
+ <<
+ NLA = 124;
+ >>
+
+^
+ <<
+ NLA = 125;
+ >>
+
+approx
+ <<
+ NLA = 126;
+ >>
+
+LL\(1\)
+ <<
+ NLA = 127;
+ >>
+
+LL\(2\)
+ <<
+ NLA = 128;
+ >>
+
+\*
+ <<
+ NLA = 129;
+ >>
+
+\+
+ <<
+ NLA = 130;
+ >>
+
+?
+ <<
+ NLA = 131;
+ >>
+
+=>
+ <<
+ NLA = 132;
+ >>
+
+exception
+ <<
+ NLA = 133;
+ >>
+
+default
+ <<
+ NLA = 134;
+ >>
+
+catch
+ <<
+ NLA = 135;
+ >>
+
+[a-z] [A-Za-z0-9_]*
+ <<
+ NLA = NonTerminal;
+
+ while ( zzchar==' ' || zzchar=='\t' ) {
+ zzadvance();
+ }
+ if ( zzchar == ':' && inAlt ) NLA = LABEL;
+ >>
+
+[A-Z] [A-Za-z0-9_]*
+ <<
+ NLA = TokenTerm;
+
+ while ( zzchar==' ' || zzchar=='\t' ) {
+ zzadvance();
+ }
+ if ( zzchar == ':' && inAlt ) NLA = LABEL;
+ >>
+
+{\\}#[A-Za-z0-9_]*
+ <<
+ NLA = 136;
+ warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip();
+ >>
+
+
+%%STRINGS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\"
+ <<
+ NLA = QuotedTerm;
+ zzmode(START);
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 3;
+
+ zzline++;
+ warn("eoln found in string");
+ zzskip();
+ >>
+
+\\(\n|\r|\r\n)
+ <<
+ NLA = 4;
+ zzline++; zzmore();
+ >>
+
+\\~[]
+ <<
+ NLA = 5;
+ zzmore();
+ >>
+
+~[\n\r\"\\]+
+ <<
+ NLA = 6;
+ zzmore();
+ >>
+
+
+%%ACTION_STRINGS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\"
+ <<
+ NLA = 7;
+ zzmode(ACTIONS); zzmore();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 8;
+
+ zzline++;
+ warn("eoln found in string (in user action)");
+ zzskip();
+ >>
+
+\\(\n|\r|\r\n)
+ <<
+ NLA = 9;
+ zzline++; zzmore();
+ >>
+
+\\~[]
+ <<
+ NLA = 10;
+ zzmore();
+ >>
+
+~[\n\r\"\\]+
+ <<
+ NLA = 11;
+ zzmore();
+ >>
+
+
+%%ACTION_CHARS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+'
+ <<
+ NLA = 12;
+ zzmode(ACTIONS); zzmore();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 13;
+
+ zzline++;
+ warn("eoln found in char literal (in user action)");
+ zzskip();
+ >>
+
+\\~[]
+ <<
+ NLA = 14;
+ zzmore();
+ >>
+
+~[\n\r'\\]+
+ <<
+ NLA = 15;
+ zzmore();
+ >>
+
+
+%%ACTION_COMMENTS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\*/
+ <<
+ NLA = 16;
+ zzmode(ACTIONS); zzmore();
+ >>
+
+\*
+ <<
+ NLA = 17;
+ zzmore();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 18;
+ zzline++; zzmore(); DAWDLE;
+ >>
+
+~[\n\r\*]+
+ <<
+ NLA = 19;
+ zzmore();
+ >>
+
+
+%%TOK_DEF_COMMENTS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\*/
+ <<
+ NLA = 20;
+ zzmode(PARSE_ENUM_FILE);
+ zzmore();
+ >>
+
+\*
+ <<
+ NLA = 21;
+ zzmore();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 22;
+ zzline++; zzmore(); DAWDLE;
+ >>
+
+~[\n\r\*]+
+ <<
+ NLA = 23;
+ zzmore();
+ >>
+
+
+%%TOK_DEF_CPP_COMMENTS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 24;
+ zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE;
+ >>
+
+~[\n\r]+
+ <<
+ NLA = 25;
+ zzskip();
+ >>
+
+
+%%ACTION_CPP_COMMENTS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 26;
+ zzline++; zzmode(ACTIONS); zzmore(); DAWDLE;
+ >>
+
+~[\n\r]+
+ <<
+ NLA = 27;
+ zzmore();
+ >>
+
+
+%%CPP_COMMENTS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 28;
+ zzline++; zzmode(START); zzskip(); DAWDLE;
+ >>
+
+~[\n\r]+
+ <<
+ NLA = 29;
+ zzskip();
+ >>
+
+
+%%COMMENTS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\*/
+ <<
+ NLA = 30;
+ zzmode(START); zzskip();
+ >>
+
+\*
+ <<
+ NLA = 31;
+ zzskip();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 32;
+ zzline++; zzskip(); DAWDLE;
+ >>
+
+~[\n\r\*]+
+ <<
+ NLA = 33;
+ zzskip();
+ >>
+
+
+%%ACTIONS
+
+@
+ <<
+ NLA = Eof;
+ >>
+
+\>\>
+ <<
+ NLA = Action;
+ /* these do not nest */
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ NLATEXT[1] = ' ';
+ zzbegexpr[0] = ' ';
+ zzbegexpr[1] = ' ';
+ if ( zzbufovf ) {
+ err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));
+ }
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+ /* MR1 in DLG action */
+ /* MR1 Doesn't matter what kind of action it is - reset*/
+
+ tokenActionActive=0; /* MR1 */
+ >>
+
+\>\>?
+ <<
+ NLA = Pred;
+ /* these do not nest */
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ NLATEXT[1] = ' ';
+ zzbegexpr[0] = '\0';
+ if ( zzbufovf ) {
+ err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));
+ };
+#ifdef __cplusplus__
+ /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+#ifdef __STDC__
+ /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+#ifdef __USE_PROTOS
+ /* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+ /* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred);
+#endif
+#endif
+#endif
+ >>
+
+\]
+ <<
+ NLA = PassAction;
+ if ( topint() == ']' ) {
+ popint();
+ if ( istackempty() ) /* terminate action */
+ {
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ zzbegexpr[0] = ' ';
+ if ( zzbufovf ) {
+ err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));
+ }
+ }
+ else {
+ /* terminate $[..] and #[..] */
+ if ( GenCC ) zzreplstr("))");
+ else zzreplstr(")");
+ zzmore();
+ }
+ }
+ else if ( topint() == '|' ) { /* end of simple [...] */
+ popint();
+ zzmore();
+ }
+ else zzmore();
+ >>
+
+consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)
+ <<
+ NLA = 37;
+
+ zzmore();
+ zzreplstr(inline_set(zzbegexpr+
+ strlen("consumeUntil(")));
+ >>
+
+consumeUntil\( ~[\)]+ \)
+ <<
+ NLA = 38;
+ zzmore();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 39;
+ zzline++; zzmore(); DAWDLE;
+ >>
+
+\>
+ <<
+ NLA = 40;
+ zzmore();
+ >>
+
+$
+ <<
+ NLA = 41;
+ zzmore();
+ >>
+
+$$
+ <<
+ NLA = 42;
+ if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}
+ else err("$$ use invalid in C++ mode");
+ >>
+
+$\[\]
+ <<
+ NLA = 43;
+ if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}
+ else err("$[] use invalid in C++ mode");
+ >>
+
+$\[
+ <<
+ NLA = 44;
+
+ pushint(']');
+ if ( !GenCC ) zzreplstr("zzconstr_attr(");
+ else err("$[..] use invalid in C++ mode");
+ zzmore();
+ >>
+
+$[0-9]+
+ <<
+ NLA = 45;
+ {
+ static char buf[100];
+ numericActionLabel=1; /* MR10 */
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("$i attrib ref too big");
+ set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",
+ BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"_t%d%s",
+ BlkLevel-1,zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ >>
+
+$[0-9]+.
+ <<
+ NLA = 46;
+ {
+ static char buf[100];
+ numericActionLabel=1; /* MR10 */
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("$i.field attrib ref too big");
+ zzbegexpr[strlen(zzbegexpr)-1] = ' ';
+ set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",
+ BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"_t%d%s.",
+ BlkLevel-1,zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ >>
+
+$[0-9]+.[0-9]+
+ <<
+ NLA = 47;
+ {
+ static char buf[100];
+ static char i[20], j[20];
+ char *p,*q;
+ numericActionLabel=1; /* MR10 */
+ if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");
+ for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {
+ if ( q == &i[20] )
+ fatalFL("i of $i.j attrib ref too big",
+ FileStr[CurFile], zzline );
+ *q++ = *p;
+ }
+ *q = '\0';
+ for (p++, q= &j[0]; *p!='\0'; p++) {
+ if ( q == &j[20] )
+ fatalFL("j of $i.j attrib ref too big",
+ FileStr[CurFile], zzline );
+ *q++ = *p;
+ }
+ *q = '\0';
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);
+ else sprintf(buf,"_t%s%s",i,j);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ >>
+
+$[_a-zA-Z][_a-zA-Z0-9]*
+ <<
+ NLA = 48;
+ { static char buf[300]; LabelEntry *el;
+ zzbegexpr[0] = ' ';
+ if ( CurRule != NULL &&
+ strcmp(CurRule, &zzbegexpr[1])==0 ) {
+ if ( !GenCC ) zzreplstr("zzaRet");
+ }
+ else if ( CurRetDef != NULL &&
+ strmember(CurRetDef, &zzbegexpr[1])) {
+ if ( hasMultipleOperands( CurRetDef ) ) {
+ require (strlen(zzbegexpr)<=(size_t)285,
+ "$retval attrib ref too big");
+ sprintf(buf,"_retv.%s",&zzbegexpr[1]);
+ zzreplstr(buf);
+ }
+ else zzreplstr("_retv");
+ }
+ else if ( CurParmDef != NULL &&
+ strmember(CurParmDef, &zzbegexpr[1])) {
+ ;
+ }
+ else if ( Elabel==NULL ) {
+ { err("$-variables in actions outside of rules are not allowed"); }
+ } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {
+ /* MR10 */
+ /* MR10 */ /* element labels might exist without an elem when */
+ /* MR10 */ /* it is a forward reference (to a rule) */
+ /* MR10 */
+ /* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )
+ /* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }
+ /* MR10 */
+ /* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {
+ /* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs");
+ /* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")");
+ /* MR10 */ };
+ /* MR10 */
+ /* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */
+ /* MR10 */ /* element labels contain pointer to the owners node */
+ /* MR10 */
+ /* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) {
+ /* MR10 */ list_add(&CurActionLabels,el);
+ /* MR10 */ };
+}
+else
+warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));
+}
+zzmore();
+ >>
+
+#0
+ <<
+ NLA = 49;
+ zzreplstr("(*_root)"); zzmore(); chkGTFlag();
+ >>
+
+#\[\]
+ <<
+ NLA = 50;
+ if ( GenCC ) {
+ if (NewAST) zzreplstr("(newAST)");
+ else zzreplstr("(new AST)");}
+ else {zzreplstr("zzastnew()");} zzmore();
+ chkGTFlag();
+ >>
+
+#\(\)
+ <<
+ NLA = 51;
+ zzreplstr("NULL"); zzmore(); chkGTFlag();
+ >>
+
+#[0-9]+
+ <<
+ NLA = 52;
+ {
+ static char buf[100];
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("#i AST ref too big");
+ if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);
+ chkGTFlag();
+ }
+ >>
+
+#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)
+ <<
+ NLA = 53;
+
+ zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();
+ getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);
+ >>
+
+#line ~[\n\r]* (\n|\r|\r\n)
+ <<
+ NLA = 54;
+
+ zzline++; zzmore();
+ >>
+
+#[_a-zA-Z][_a-zA-Z0-9]*
+ <<
+ NLA = 55;
+
+ if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||
+ strcmp(zzbegexpr, "#if")==0 ||
+ strcmp(zzbegexpr, "#else")==0 ||
+ strcmp(zzbegexpr, "#endif")==0 ||
+ strcmp(zzbegexpr, "#ifndef")==0 ||
+ strcmp(zzbegexpr, "#define")==0 ||
+ strcmp(zzbegexpr, "#pragma")==0 ||
+ strcmp(zzbegexpr, "#undef")==0 ||
+ strcmp(zzbegexpr, "#import")==0 ||
+ strcmp(zzbegexpr, "#line")==0 ||
+ strcmp(zzbegexpr, "#include")==0 ||
+ strcmp(zzbegexpr, "#error")==0) )
+ {
+ static char buf[100];
+ sprintf(buf, "%s_ast", zzbegexpr+1);
+ /* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));
+ zzreplstr(buf);
+ chkGTFlag();
+ }
+ zzmore();
+ >>
+
+#\[
+ <<
+ NLA = 56;
+
+ pushint(']');
+ if ( GenCC ) {
+ if (NewAST) zzreplstr("(newAST(");
+ else zzreplstr("(new AST("); }
+ else zzreplstr("zzmk_ast(zzastnew(),");
+ zzmore();
+ chkGTFlag();
+ >>
+
+#\(
+ <<
+ NLA = 57;
+
+ pushint('}');
+ if ( GenCC ) {
+ if (tmakeInParser) {
+ zzreplstr("tmake(");
+ }
+ else {
+ zzreplstr("ASTBase::tmake(");
+ }
+ }
+ else {
+ zzreplstr("zztmake(");
+ }
+ zzmore();
+ chkGTFlag();
+ >>
+
+#
+ <<
+ NLA = 58;
+ zzmore();
+ >>
+
+\)
+ <<
+ NLA = 59;
+
+ if ( istackempty() )
+ zzmore();
+ else if ( topint()==')' ) {
+ popint();
+ }
+ else if ( topint()=='}' ) {
+ popint();
+ /* terminate #(..) */
+ zzreplstr(", NULL)");
+ }
+ zzmore();
+ >>
+
+\[
+ <<
+ NLA = 60;
+
+ pushint('|'); /* look for '|' to terminate simple [...] */
+ zzmore();
+ >>
+
+\(
+ <<
+ NLA = 61;
+
+ pushint(')');
+ zzmore();
+ >>
+
+\\\]
+ <<
+ NLA = 62;
+ zzreplstr("]"); zzmore();
+ >>
+
+\\\)
+ <<
+ NLA = 63;
+ zzreplstr(")"); zzmore();
+ >>
+
+\\>
+ <<
+ NLA = 64;
+ if (! tokenActionActive) zzreplstr(">"); /* MR1 */
+ zzmore(); /* MR1 */
+ >>
+
+'
+ <<
+ NLA = 65;
+ zzmode(ACTION_CHARS); zzmore();
+ >>
+
+\"
+ <<
+ NLA = 66;
+ zzmode(ACTION_STRINGS); zzmore();
+ >>
+
+\\$
+ <<
+ NLA = 67;
+ zzreplstr("$"); zzmore();
+ >>
+
+\\#
+ <<
+ NLA = 68;
+ zzreplstr("#"); zzmore();
+ >>
+
+\\(\n|\r|\r\n)
+ <<
+ NLA = 69;
+ zzline++; zzmore();
+ >>
+
+\\~[\]\)>$#]
+ <<
+ NLA = 70;
+ zzmore();
+ >>
+
+/
+ <<
+ NLA = 71;
+ zzmore();
+ >>
+
+/\*
+ <<
+ NLA = 72;
+ zzmode(ACTION_COMMENTS); zzmore();
+ >>
+
+\*/
+ <<
+ NLA = 73;
+ warn("Missing /*; found dangling */ in action"); zzmore();
+ >>
+
+//
+ <<
+ NLA = 74;
+ zzmode(ACTION_CPP_COMMENTS); zzmore();
+ >>
+
+~[\n\r\)\(\\$#\>\]\[\"'/]+
+ <<
+ NLA = 75;
+ zzmore();
+ >>
+
+
+%%PARSE_ENUM_FILE
+
+@
+ <<
+ NLA = Eof;
+ ;
+ >>
+
+[\t\ ]+
+ <<
+ NLA = 137;
+ zzskip();
+ >>
+
+\n|\r|\r\n
+ <<
+ NLA = 138;
+ zzline++; zzskip();
+ >>
+
+//
+ <<
+ NLA = 139;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzmore();
+ >>
+
+/\*
+ <<
+ NLA = 140;
+ zzmode(TOK_DEF_COMMENTS); zzskip();
+ >>
+
+#ifdef
+ <<
+ NLA = 141;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ >>
+
+#if
+ <<
+ NLA = 142;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ >>
+
+#ifndef
+ <<
+ NLA = 143;
+ ;
+ >>
+
+#else
+ <<
+ NLA = 144;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ >>
+
+#endif
+ <<
+ NLA = 145;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ >>
+
+#undef
+ <<
+ NLA = 146;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ >>
+
+#import
+ <<
+ NLA = 147;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ >>
+
+#define
+ <<
+ NLA = 149;
+ >>
+
+enum
+ <<
+ NLA = 151;
+ >>
+
+\{
+ <<
+ NLA = 152;
+ >>
+
+=
+ <<
+ NLA = 153;
+ >>
+
+,
+ <<
+ NLA = 154;
+ >>
+
+\}
+ <<
+ NLA = 155;
+ >>
+
+;
+ <<
+ NLA = 156;
+ >>
+
+[0-9]+
+ <<
+ NLA = INT;
+ >>
+
+[a-zA-Z_][_a-zA-Z0-9]*
+ <<
+ NLA = ID;
+ >>
+
+%%
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/pred.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/pred.c
new file mode 100644
index 00000000..2ee2dcc4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/pred.c
@@ -0,0 +1,821 @@
+/*
+ * pred.c -- source for predicate detection, manipulation
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "pcctscfg.h"
+#include "set.h"
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#include "dlgdef.h"
+#include <ctype.h>
+
+#ifdef __USE_PROTOS
+static void complete_context_sets(RuleRefNode *, Predicate *);
+static void complete_context_trees(RuleRefNode *, Predicate *);
+#else
+static void complete_context_sets();
+static void complete_context_trees();
+#endif
+
+char *PRED_AND_LIST = "AND";
+char *PRED_OR_LIST = "OR";
+
+/*
+ * In C mode, return the largest constant integer found as the
+ * sole argument to LATEXT(i).
+ *
+ * In C++ mode, return the largest constant integer found as the
+ * sole argument to LT(i) given that the char before is nonalpha.
+ */
+
+int
+#ifdef __USE_PROTOS
+predicateLookaheadDepth(ActionNode *a)
+#else
+predicateLookaheadDepth(a)
+ActionNode *a;
+#endif
+{
+ int max_k=0;
+
+ if (a->predEntry != NULL) {
+ MR_pred_depth(a->predEntry->pred,&max_k);
+ goto PREDENTRY_EXIT;
+ }
+
+ if ( GenCC )
+ {
+ /* scan for LT(i) */
+ int k = 0;
+ char *p = a->action;
+ while ( p!=NULL )
+ {
+ p = strstr(p, "LT(");
+ if ( p!=NULL )
+ {
+ if ( p>=a->action && !isalpha(*(p-1)) )
+ {
+ k = atoi(p+strlen("LT("));
+ if ( k>max_k ) max_k=k;
+ }
+ p += strlen("LT(");
+ }
+ }
+ }
+ else {
+ /* scan for LATEXT(i) */
+ int k = 0;
+ char *p = a->action;
+ while ( p!=NULL )
+ {
+ p = strstr(p, "LATEXT(");
+ if ( p!=NULL )
+ {
+ p += strlen("LATEXT(");
+ k = atoi(p);
+ if ( k>max_k ) max_k=k;
+ }
+ }
+ }
+
+ if (max_k==0) {
+ max_k = 1; /* MR33 Badly designed if didn't set max_k when CLL_k = 1 */
+ if (CLL_k > 1) /* MR27 Don't warn if max(k,ck) == 1 */
+ {
+ if ( !a->frmwarned )
+ {
+ a->frmwarned = 1;
+ warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1",
+ GenCC?"LT(i)":"LATEXT(i)"),
+ FileStr[a->file], a->line);
+ }
+ }
+ }
+
+/* MR10 */ if ( max_k > CLL_k) {
+/* MR10 */ if ( !a->frmwarned )
+/* MR10 */ {
+/* MR10 */ a->frmwarned = 1;
+/* MR11 */ errFL(eMsgd2("predicate refers to lookahead token %d. Semantic lookahead is limited to max(k,ck)==%d",
+/* MR10 */ max_k,CLL_k),
+/* MR10 */ FileStr[a->file],a->line);
+/* MR10 */ if (max_k >= OutputLL_k) {
+/* MR10 */ if (!GenCC) {
+/* MR10 */ errFL(eMsgd(" the lookahead buffer size in C mode is %d token(s) (including the one just recognized)",
+/* MR10 */ OutputLL_k),
+/* MR10 */ FileStr[a->file],a->line);
+/* MR10 */ };
+/* MR10 */ };
+/* MR10 */ };
+/* MR10 */ max_k= CLL_k;
+/* MR10 */ };
+
+PREDENTRY_EXIT:
+ return max_k;
+}
+
+/* Find all predicates in a block of alternatives. DO NOT find predicates
+ * behind the block because that predicate could depend on things set in
+ * one of the nonoptional blocks
+ */
+
+Predicate *
+#ifdef __USE_PROTOS
+find_in_aSubBlk( Junction *alt )
+#else
+find_in_aSubBlk( alt )
+Junction *alt;
+#endif
+{
+ Predicate *a, *head=NULL, *tail=NULL, *root=NULL;
+ Junction *p = alt;
+
+ if (MRhoisting) {
+ return MR_find_in_aSubBlk(alt);
+ };
+ for (; p!=NULL; p=(Junction *)p->p2)
+ {
+ /* ignore empty alts */
+ if ( p->p1->ntype != nJunction ||
+ ((Junction *)p->p1)->jtype != EndBlk )
+ {
+ a = find_predicates(p->p1); /* get preds for this alt */
+ if ( a==NULL ) continue;
+
+ /* make an OR list of predicates */
+ if ( head==NULL )
+ {
+ root = new_pred();
+ root->expr = PRED_OR_LIST;
+ head = tail = a;
+ root->down = head;
+ }
+ else {
+ tail->right = a;
+ a->left = tail;
+ a->up = tail->up;
+ tail = a;
+ }
+ }
+ }
+
+ /* if just one pred, remove OR root */
+ if ( root!=NULL && root->down->right == NULL )
+ {
+ Predicate *d = root->down;
+ free( (char *) root);
+ return d;
+ }
+
+ return root;
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+find_in_aOptBlk( Junction *alt )
+#else
+find_in_aOptBlk( alt )
+Junction *alt;
+#endif
+{
+ return find_in_aSubBlk( alt );
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+find_in_aLoopBegin( Junction *alt )
+#else
+find_in_aLoopBegin( alt )
+Junction *alt;
+#endif
+{
+ return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+find_in_aPlusBlk( Junction *alt )
+#else
+find_in_aPlusBlk( alt )
+Junction *alt;
+#endif
+{
+ require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk");
+ return find_in_aSubBlk( alt );
+}
+
+/* Look for a predicate;
+ *
+ * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs.
+ * This means that a "hoisting distance" of zero is the only distance
+ * allowable. Init actions are ignored.
+ *
+ * WARNING:
+ * Assumes no (..)? block after predicate for the moment.
+ * Does not check to see if pred is in production that can generate
+ * a sequence contained in the set of ambiguous tuples.
+ *
+ * Return the predicate found if any.
+ */
+
+
+Predicate *
+#ifdef __USE_PROTOS
+find_predicates( Node *alt )
+#else
+find_predicates( alt )
+Node *alt;
+#endif
+{
+#ifdef DBG_PRED
+ Junction *j;
+ RuleRefNode *r;
+ TokNode *t;
+#endif
+ Predicate *pred;
+
+ if ( alt==NULL ) return NULL;
+
+#ifdef DBG_PRED
+ switch ( alt->ntype )
+ {
+ case nJunction :
+ j = (Junction *) alt;
+ fprintf(stderr, "Junction(in %s)", j->rname);
+ switch ( j->jtype )
+ {
+ case aSubBlk :
+ fprintf(stderr,"aSubBlk\n");
+ break;
+ case aOptBlk :
+ fprintf(stderr,"aOptBlk\n");
+ break;
+ case aLoopBegin :
+ fprintf(stderr,"aLoopBeginBlk\n");
+ break;
+ case aLoopBlk :
+ fprintf(stderr,"aLoopBlk\n");
+ break;
+ case aPlusBlk :
+ fprintf(stderr,"aPlusBlk\n");
+ break;
+ case EndBlk :
+ fprintf(stderr,"EndBlk\n");
+ break;
+ case RuleBlk :
+ fprintf(stderr,"RuleBlk\n");
+ break;
+ case Generic :
+ fprintf(stderr,"Generic\n");
+ break;
+ case EndRule :
+ fprintf(stderr,"EndRule\n");
+ break;
+ }
+ break;
+ case nRuleRef :
+ r = (RuleRefNode *) alt;
+ fprintf(stderr, "RuleRef(in %s)\n", r->rname);
+ break;
+ case nToken :
+ t = (TokNode *) alt;
+ fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token));
+ break;
+ case nAction :
+ fprintf(stderr, "Action\n");
+ break;
+ }
+#endif
+
+ switch ( alt->ntype )
+ {
+ case nJunction :
+ {
+ Predicate *a, *b;
+ Junction *p = (Junction *) alt;
+
+ /* lock nodes */
+ if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
+ p->jtype==aPlusBlk || p->jtype==EndRule )
+ {
+ require(p->pred_lock!=NULL, "rJunc: lock array is NULL");
+ if ( p->pred_lock[1] )
+ {
+ return NULL;
+ }
+ p->pred_lock[1] = TRUE;
+ }
+
+ switch ( p->jtype )
+ {
+ case aSubBlk :
+ a = find_in_aSubBlk(p);
+ return a; /* nothing is visible past this guy */
+ case aOptBlk :
+ a = find_in_aOptBlk(p);
+ return a;
+ case aLoopBegin :
+ a = find_in_aLoopBegin(p);
+ return a;
+ case aLoopBlk :
+ a = find_in_aSubBlk(p);
+ p->pred_lock[1] = FALSE;
+ return a;
+ case aPlusBlk :
+ a = find_in_aPlusBlk(p);
+ p->pred_lock[1] = FALSE;
+ return a; /* nothing is visible past this guy */
+ case RuleBlk :
+ a = find_predicates(p->p1);
+ p->pred_lock[1] = FALSE;
+ return a;
+ case Generic :
+ a = find_predicates(p->p1);
+ b = find_predicates(p->p2);
+ if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE;
+ if ( a==NULL ) return b;
+ if ( b==NULL ) return a;
+ /* otherwise OR the two preds together */
+ {
+ fatal_internal("hit unknown situation during predicate hoisting");
+ }
+ case EndBlk :
+ case EndRule : /* Find no predicates after a rule ref */
+ return NULL;
+ default:
+ fatal_internal("this cannot be printed\n");
+ break;
+ }
+ }
+ case nAction :
+ {
+ ActionNode *p = (ActionNode *) alt;
+ if ( p->noHoist) return NULL; /* MR12c */
+ if ( p->init_action ) return find_predicates(p->next);
+ if ( p->is_predicate )
+ {
+ Tree *t=NULL;
+#ifdef DBG_PRED
+ fprintf(stderr, "predicate: <<%s>>?\n", p->action);
+#endif
+ if ( p->guardpred!=NULL )
+ {
+ pred = predicate_dup(p->guardpred);
+ MR_guardPred_plainSet(p,pred); /* MR12c */
+ }
+ else
+ {
+ pred = new_pred();
+ pred->k = predicateLookaheadDepth(p);
+ pred->source = p;
+ pred->expr = p->action;
+ if ( HoistPredicateContext && pred->k > 1 )
+ {
+ /* MR30 No need to use first_item_is_guess_block_extra
+ since we know this is an action, not a (...)* or
+ (...)+ block.
+ */
+
+ if ( first_item_is_guess_block((Junction *)p->next) )
+ {
+ warnFL("cannot compute context of predicate in front of (..)? block",
+ FileStr[p->file], p->line);
+ }
+ else
+ {
+ ConstrainSearch = 0;
+/* MR11 */ if (p->ampersandPred != NULL) {
+/* MR11 */ TRAV(p,
+/* MR11 */ pred->k,
+/* MR11 */ &(pred->completionTree), t);
+/* MR11 */ } else {
+ TRAV(p->next,
+ pred->k,
+ &(pred->completionTree), t);
+ };
+ pred->tcontext = t;
+ MR_check_pred_too_long(pred,pred->completionTree);
+#ifdef DBG_PRED
+ fprintf(stderr, "LL(%d) context:", pred->k);
+ preorder(t);
+ fprintf(stderr, "\n");
+#endif
+ }
+ }
+ else if ( HoistPredicateContext && pred->k == 1 )
+ {
+ pred->scontext[1] = empty;
+ /* MR30 No need to use first_item_is_guess_block_extra
+ since we know this is an action.
+ */
+ if ( first_item_is_guess_block((Junction *)p->next) )
+ {
+ warnFL("cannot compute context of predicate in front of (..)? block",
+ FileStr[p->file], p->line);
+ }
+ else
+ {
+ REACH((Junction *)p->next,
+ 1,
+ &(pred->completionSet),
+ pred->scontext[1]);
+ MR_check_pred_too_long(pred,pred->completionSet);
+#ifdef DBG_PRED
+ fprintf(stderr, "LL(1) context:");
+ s_fprT(stderr, pred->scontext[1]);
+ fprintf(stderr, "\n");
+#endif
+ }
+ }
+ }
+ {
+ Predicate *d = find_predicates(p->next);
+ Predicate *root;
+
+/* Warning: Doesn't seem like the up pointers will all be set correctly;
+ * TJP: that's ok, we're not using them now.
+ */
+ if ( d!=NULL )
+ {
+ root = new_pred();
+ root->expr = PRED_AND_LIST;
+ root->down = pred;
+ pred->right = d;
+ pred->up = root;
+ d->left = pred;
+ d->up = pred->up;
+ return root;
+ }
+ }
+ return pred;
+ }
+ return NULL;
+ }
+ case nRuleRef :
+ {
+ Predicate *a;
+ RuleRefNode *p = (RuleRefNode *) alt;
+ Junction *r;
+ Junction *save_MR_RuleBlkWithHalt;
+
+ RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
+ if ( q == NULL )
+ {
+ warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );
+ return NULL;
+ }
+ r = RulePtr[q->rulenum];
+ if ( r->pred_lock[1] )
+ {
+ /* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis
+ * must have seen it earlier.
+ */
+ return NULL;
+ }
+
+ /* MR10 There should only be one halt set at a time. */
+ /* MR10 Life would have been easier with a global variable */
+ /* MR10 (at least for this particular need) */
+ /* MR10 Unset the old one and set the new one, later undo. */
+
+ require(r->end->halt == FALSE,"should only have one halt at a time");
+
+/* MR10 */ require(MR_RuleBlkWithHalt == NULL ||
+/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
+/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or does not have halt set");
+/* MR10 */ if (MR_RuleBlkWithHalt != NULL) {
+/* MR10 */ MR_RuleBlkWithHalt->end->halt=FALSE;
+/* MR10 */ };
+
+/*** fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq); ***/
+
+ require(r->end->halt == FALSE,"rule->end->halt already set");
+
+ save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
+
+/* MR10 */ MR_pointerStackPush(&MR_RuleBlkWithHaltStack,MR_RuleBlkWithHalt);
+/* MR10 */ MR_pointerStackPush(&MR_PredRuleRefStack,p);
+
+ r->end->halt = TRUE;
+/* MR10 */ MR_RuleBlkWithHalt=r;
+
+ a = find_predicates((Node *)r);
+
+ require(r->end->halt == TRUE,"rule->end->halt not set");
+ r->end->halt = FALSE;
+
+/* MR10 */ MR_pointerStackPop(&MR_PredRuleRefStack);
+/* MR10 */ MR_RuleBlkWithHalt=(Junction *) MR_pointerStackPop(&MR_RuleBlkWithHaltStack);
+
+ require (MR_RuleBlkWithHalt==save_MR_RuleBlkWithHalt,
+ "RuleBlkWithHaltStack not consistent");
+
+/* MR10 */ require(MR_RuleBlkWithHalt == NULL ||
+/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == FALSE),
+/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or has no halt set");
+/* MR10 */ if (MR_RuleBlkWithHalt != NULL) {
+/* MR10 */ MR_RuleBlkWithHalt->end->halt=TRUE;
+/* MR10 */ };
+
+/*** fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq); ***/
+
+ if ( a==NULL ) return NULL;
+
+ /* attempt to compute the "local" FOLLOW just like in normal lookahead
+ * computation if needed
+ */
+
+ complete_context_sets(p,a);
+ complete_context_trees(p,a);
+
+/* MR10 */ MR_cleanup_pred_trees(a);
+
+ return a;
+ }
+ case nToken :
+ break;
+ }
+
+ return NULL;
+}
+
+#ifdef __USE_PROTOS
+Predicate *MR_find_predicates_and_supp(Node *alt)
+#else
+Predicate *MR_find_predicates_and_supp(alt)
+ Node *alt;
+#endif
+{
+ Predicate *p;
+
+ p=find_predicates(alt);
+ p=MR_suppressK(alt,p);
+ return p;
+}
+
+Predicate *
+#ifdef __USE_PROTOS
+new_pred( void )
+#else
+new_pred( )
+#endif
+{
+ Predicate *p = (Predicate *) calloc(1,sizeof(Predicate)); /* MR10 */
+ require(p!=NULL, "new_pred: cannot alloc predicate");
+ p->scontext[0]=empty;
+ p->scontext[1]=empty;
+ p->completionTree=empty;
+ p->completionSet=empty;
+ p->plainSet=empty;
+ return p;
+}
+
+static void
+#ifdef __USE_PROTOS
+complete_context_sets( RuleRefNode *p, Predicate *a )
+#else
+complete_context_sets( p, a )
+RuleRefNode *p;
+Predicate *a;
+#endif
+{
+ set rk2, b;
+ int k2;
+
+#ifdef DBG_PRED
+ fprintf(stderr, "enter complete_context_sets\n");
+#endif
+ for (; a!=NULL; a=a->right)
+ {
+ if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
+ {
+ complete_context_sets(p,a->down);
+ continue;
+ }
+ rk2 = b = empty;
+ while ( !set_nil(a->completionSet) )
+ {
+ k2 = set_int(a->completionSet);
+ set_rm(k2, a->completionSet);
+
+ REACH(p->next, k2, &rk2, b);
+ set_orin(&(a->scontext[1]), b);
+ set_free(b);
+ }
+
+ set_orin(&(a->completionSet), rk2);/* remember what we couldn't do */
+ set_free(rk2);
+#ifdef DBG_PRED
+ fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a);
+ s_fprT(stderr, a->scontext[1]);
+ fprintf(stderr, "\n");
+#endif
+/* complete_context_sets(p, a->down);*/
+ }
+#ifdef DBG_PRED
+ fprintf(stderr, "exit complete_context_sets\n");
+#endif
+}
+
+static void
+#ifdef __USE_PROTOS
+complete_context_trees( RuleRefNode *p, Predicate *a )
+#else
+complete_context_trees( p, a )
+RuleRefNode *p;
+Predicate *a;
+#endif
+{
+ set rk2;
+ int k2;
+ Tree *u;
+
+#ifdef DBG_PRED
+ fprintf(stderr, "enter complete_context_trees\n");
+#endif
+ for (; a!=NULL; a=a->right)
+ {
+ if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
+ {
+ complete_context_trees(p, a->down);
+ continue;
+ }
+ rk2 = empty;
+
+ /* any k left to do? if so, link onto tree */
+ while ( !set_nil(a->completionTree) )
+ {
+ k2 = set_int(a->completionTree);
+ set_rm(k2, a->completionTree);
+ u = NULL;
+
+ TRAV(p->next, k2, &rk2, u);
+
+ /* any subtrees missing k2 tokens, add u onto end */
+ a->tcontext = tlink(a->tcontext, u, k2);
+ Tfree(u); /* MR10 */
+ }
+ set_orin(&(a->completionTree), rk2);/* remember what we couldn't do */
+ set_free(rk2);
+#ifdef DBG_PRED
+ fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k);
+ preorder(a->tcontext);
+ fprintf(stderr, "\n");
+#endif
+/* complete_context_trees(p, a->down);*/
+ }
+#ifdef DBG_PRED
+ fprintf(stderr, "exit complete_context_trees\n");
+#endif
+}
+
+/* Walk a list of predicates and return the set of all tokens in scontext[1]'s */
+set
+#ifdef __USE_PROTOS
+covered_set( Predicate *p )
+#else
+covered_set( p )
+Predicate *p;
+#endif
+{
+ set a;
+
+ a = empty;
+ for (; p!=NULL; p=p->right)
+ {
+ if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST )
+ {
+ set_orin(&a, covered_set(p->down));
+ continue;
+ }
+ set_orin(&a, p->scontext[1]);
+ set_orin(&a, covered_set(p->down));
+ }
+ return a;
+}
+
+/* MR10 predicate_free()
+ MR10 Don't free the leaf nodes since they are part of the action node
+*/
+
+#ifdef __USE_PROTOS
+void predicate_free(Predicate *p)
+#else
+void predicate_free(p)
+ Predicate *p;
+#endif
+{
+ if (p == NULL) return;
+ predicate_free(p->right);
+ predicate_free(p->down);
+ if (p->cloned ||
+ p->source == NULL ||
+ p->source->guardpred == NULL ||
+ p->expr == PRED_AND_LIST ||
+ p->expr == PRED_OR_LIST) {
+ set_free(p->scontext[1]);
+ set_free(p->completionSet);
+ set_free(p->completionTree);
+ set_free(p->plainSet);
+ Tfree(p->tcontext);
+ free( (char *) p);
+ } else {
+ p->right=NULL;
+ p->down=NULL; /* MR13 *** debug */
+ };
+}
+
+/* MR10 predicate_dup() */
+
+#ifdef __USE_PROTOS
+Predicate * predicate_dup_xxx(Predicate *p,int contextToo)
+#else
+Predicate * predicate_dup_xxx(p,contextToo)
+ Predicate *p;
+ int contextToo;
+#endif
+{
+ Predicate *q;
+
+ if (p == NULL) return NULL;
+ q=new_pred();
+ q->down=predicate_dup(p->down);
+ q->right=predicate_dup(p->right);
+
+ /*
+ don't replicate expr - it is read-only
+ and address comparison is used to look
+ for identical predicates.
+ */
+
+ q->expr=p->expr;
+ q->k=p->k;
+ q->source=p->source;
+ q->cloned=1;
+ q->ampersandStyle=p->ampersandStyle;
+ q->inverted=p->inverted;
+ q->predEntry=p->predEntry;
+ q->plainSet=set_dup(p->plainSet);
+
+ if (contextToo) {
+ q->tcontext=tdup(p->tcontext);
+ q->scontext[0]=set_dup(p->scontext[0]);
+ q->scontext[1]=set_dup(p->scontext[1]);
+ q->completionTree=set_dup(p->completionTree);
+ q->completionSet=set_dup(p->completionSet);
+ };
+
+ /* don't need to dup "redundant" */
+
+ return q;
+
+}
+
+#ifdef __USE_PROTOS
+Predicate * predicate_dup_without_context(Predicate *p)
+#else
+Predicate * predicate_dup_without_context(p)
+ Predicate *p;
+#endif
+{
+ return predicate_dup_xxx(p,0);
+}
+
+#ifdef __USE_PROTOS
+Predicate * predicate_dup(Predicate *p)
+#else
+Predicate * predicate_dup(p)
+ Predicate *p;
+#endif
+{
+ return predicate_dup_xxx(p,1);
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/proto.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/proto.h
new file mode 100644
index 00000000..33f7b371
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/proto.h
@@ -0,0 +1,857 @@
+/*
+ * proto.h -- function prototypes
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+ /* V a r i a b l e s */
+
+extern int tp;
+extern Junction *SynDiag;
+extern char Version[];
+extern char VersionDef[];
+#ifdef __cplusplus
+extern void (*fpPrint[])(...);
+#else
+extern void (*fpPrint[])();
+#endif
+#ifdef __cplusplus
+extern struct _set (*fpReach[])(...);
+#else
+extern struct _set (*fpReach[])();
+#endif
+#ifdef __cplusplus
+extern struct _tree *(*fpTraverse[])(...);
+#else
+extern struct _tree *(*fpTraverse[])();
+#endif
+#ifdef __cplusplus
+extern void (**fpTrans)(...);
+#else
+extern void (**fpTrans)();
+#endif
+#ifdef __cplusplus
+extern void (**fpJTrans)(...);
+#else
+extern void (**fpJTrans)();
+#endif
+#ifdef __cplusplus
+extern void (*C_Trans[NumNodeTypes+1])(...);
+#else
+extern void (*C_Trans[])();
+#endif
+#ifdef __cplusplus
+extern void (*C_JTrans[NumJuncTypes+1])(...);
+#else
+extern void (*C_JTrans[])();
+#endif
+extern int BlkLevel;
+extern int CurFile;
+extern char *CurPredName;
+extern char *CurRule;
+extern int CurRuleDebug; /* MR13 */
+extern Junction *CurRuleBlk;
+extern RuleEntry *CurRuleNode;
+extern ListNode *CurElementLabels;
+extern ListNode *CurAstLabelsInActions; /* MR27 */
+extern ListNode *ContextGuardPredicateList; /* MR13 */
+extern ListNode *CurActionLabels;
+extern int numericActionLabel; /* MR10 << ... $1 ... >> or << ... $1 ... >>? */
+extern ListNode *NumericPredLabels; /* MR10 << ... $1 ... >>? ONLY */
+extern char *FileStr[];
+extern int NumFiles;
+extern int EpToken;
+extern int WildCardToken;
+extern Entry **Tname,
+ **Texpr,
+ **Rname,
+ **Fcache,
+ **Tcache,
+ **Elabel,
+ **Sname,
+ **Pname; /* MR11 */
+extern ListNode *ExprOrder;
+extern ListNode **Cycles;
+extern int TokenNum;
+extern int LastTokenCounted;
+extern ListNode *BeforeActions, *AfterActions, *LexActions;
+
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */
+/* MR1 */
+
+extern ListNode *LexMemberActions; /* MR1 */
+extern ListNode *LexPrefixActions; /* MR1 */
+
+extern set *fset; /* for constrained search */ /* MR11 */
+extern int maxk; /* for constrained search */ /* MR11 */
+extern int Save_argc; /* MR10 */
+extern char **Save_argv; /* MR10 */
+extern ListNode *eclasses, *tclasses;
+extern char *HdrAction;
+extern char *FirstAction; /* MR11 */
+extern FILE *ErrFile;
+extern char *RemapFileName;
+extern char *ErrFileName;
+extern char *DlgFileName;
+extern char *DefFileName;
+extern char *ModeFileName;
+extern char *StdMsgName;
+extern int NumRules;
+extern Junction **RulePtr;
+extern int LL_k;
+extern int CLL_k;
+extern char *decodeJType[];
+extern int PrintOut;
+extern int PrintAnnotate;
+extern int CodeGen;
+extern int LexGen;
+extern int esetnum;
+extern int setnum;
+extern int wordnum;
+extern int GenAST;
+extern int GenANSI;
+extern int **FoStack;
+extern int **FoTOS;
+extern int GenExprSetsOpt;
+extern FILE *DefFile;
+extern int CannotContinue;
+extern int GenCR;
+extern int GenLineInfo;
+extern int GenLineInfoMS;
+extern int action_file, action_line;
+extern int TraceGen;
+extern int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile;
+extern char *CurAmbigbtype;
+extern int elevel;
+extern int GenEClasseForRules;
+extern FILE *input, *output;
+extern char **TokenStr, **ExprStr;
+extern int CurrentLexClass, NumLexClasses;
+extern LClass lclass[];
+extern char LexStartSymbol[];
+extern char *CurRetDef;
+extern char *CurParmDef;
+extern int OutputLL_k;
+extern int TreeResourceLimit;
+extern int DemandLookahead;
+extern char *RulePrefix;
+extern int GenStdPccts;
+extern char *stdpccts;
+extern int ParseWithPredicates;
+extern int ConstrainSearch;
+extern int PURIFY; /* MR23 */
+
+extern set MR_CompromisedRules; /* MR14 */
+extern int MR_AmbSourceSearch; /* MR11 */
+extern int MR_SuppressSearch; /* MR13 */
+extern int MR_AmbSourceSearchGroup; /* MR11 */
+extern int MR_AmbSourceSearchChoice; /* MR11 */
+extern int MR_AmbSourceSearchLimit; /* MR11 */
+extern int MR_usingPredNames; /* MR11 */
+extern int MR_ErrorSetComputationActive; /* MR14 */
+extern char *MR_AmbAidRule; /* MR11 */
+extern int MR_AmbAidLine; /* MR11 */
+extern int MR_AmbAidMultiple; /* MR11 */
+extern int MR_AmbAidDepth; /* MR11 */
+extern int MR_skipped_e3_report; /* MR11 */
+extern int MR_matched_AmbAidRule; /* MR11 */
+extern int MR_Inhibit_Tokens_h_Gen; /* MR13 */
+extern int NewAST; /* MR13 */
+extern int tmakeInParser; /* MR23 */
+extern int AlphaBetaTrace; /* MR14 */
+extern int MR_BlkErr; /* MR21 */
+extern int MR_AlphaBetaWarning; /* MR14 */
+extern int MR_AlphaBetaMessageCount; /* MR14 */
+extern int MR_MaintainBackTrace; /* MR14 */
+extern int MR_BadExprSets; /* MR13 */
+extern int FoundGuessBlk;
+extern int FoundException;
+extern int FoundAtOperator; /* MR6 */
+extern int FoundExceptionGroup; /* MR6 */
+extern int WarningLevel;
+extern int UseStdout; /* MR6 */
+extern int TabWidth; /* MR6 */
+extern int pLevel;
+extern int pAlt1;
+extern int pAlt2;
+extern int AImode;
+extern int HoistPredicateContext;
+extern int MRhoisting; /* MR9 */
+extern int MRhoistingk; /* MR13 */
+extern int MR_debugGenRule; /* MR11 */
+extern int GenCC;
+extern char *ParserName;
+extern char *StandardSymbols[];
+extern char *ASTSymbols[];
+extern set reserved_positions;
+extern set all_tokens;
+extern set imag_tokens;
+extern set tokclasses;
+extern ListNode *ForcedTokens;
+extern int *TokenInd;
+extern FILE *Parser_h, *Parser_c;
+extern char CurrentClassName[];
+extern int no_classes_found;
+extern char Parser_h_Name[];
+extern char Parser_c_Name[];
+extern char MRinfoFile_Name[]; /* MR10 */
+extern FILE *MRinfoFile; /* MR10 */
+extern int MRinfo; /* MR10 */
+extern int MRinfoSeq; /* MR10 */
+extern int InfoP; /* MR10 */
+extern int InfoT; /* MR10 */
+extern int InfoF; /* MR10 */
+extern int InfoM; /* MR10 */
+extern int InfoO; /* MR12 */
+extern int PotentialSuppression; /* MR10 */
+extern int PotentialDummy; /* MR10 */
+extern int TnodesInUse; /* MR10 */
+extern int TnodesPeak; /* MR10 */
+extern int TnodesReportThreshold; /* MR11 */
+extern int TnodesAllocated; /* MR10 */
+extern char *ClassDeclStuff; /* MR10 */
+extern char *BaseClassName; /* MR22 */
+extern ListNode *class_before_actions, *class_after_actions;
+extern char *UserTokenDefsFile;
+extern int UserDefdTokens;
+extern ListNode *MetaTokenNodes;
+extern char *OutputDirectory;
+extern int DontCopyTokens;
+extern int LTinTokenAction; /* MR23 */
+extern set AST_nodes_refd_in_actions;
+extern ListNode *CurExGroups;
+extern int CurBlockID;
+extern int CurAltNum;
+extern Junction *CurAltStart;
+extern Junction *OuterAltStart; /* chain exception groups MR7 */
+extern ExceptionGroup *DefaultExGroup;
+extern int NumSignals;
+extern int ContextGuardTRAV;
+extern Junction *MR_RuleBlkWithHalt; /* MR10 */
+extern PointerStack MR_BackTraceStack; /* MR10 */
+extern PointerStack MR_PredRuleRefStack; /* MR10 */
+extern PointerStack MR_RuleBlkWithHaltStack; /* MR10 */
+
+/* */
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+/* MR1 in DLG action */
+/* */
+extern int tokenActionActive; /* MR1 */
+
+extern char *PRED_OR_LIST; /* MR10 */
+extern char *PRED_AND_LIST; /* MR10 */
+
+#ifdef __VMS
+#define STRICMP strcasecmp /* MR21 */
+#else
+#define STRICMP stricmp /* MR21 */
+#endif
+
+/* MR26 */
+#ifdef PCCTS_USE_STDARG
+extern Tree *tmake(Tree *root, ...);
+#else
+extern Tree *tmake();
+#endif
+
+#ifdef __USE_PROTOS
+extern int STRICMP(const char*, const char*);
+extern void istackreset(void);
+extern int istacksize(void);
+extern void pushint(int);
+extern int popint( void );
+extern int istackempty( void );
+extern int topint( void );
+extern void NewSetWd( void );
+extern void DumpSetWd( void );
+extern void DumpSetWdForC( void );
+extern void DumpSetWdForCC( void );
+extern void NewSet( void );
+extern void FillSet( set );
+extern void ComputeErrorSets( void );
+extern void ComputeTokSets( void );
+extern void SubstErrorClass( set * );
+extern int DefErrSet( set *, int, char * );
+extern int DefErrSetForC( set *, int, char * );
+extern int DefErrSetForCC( set *, int, char * );
+extern int DefErrSet1(int, set *, int, char *); /* MR21 */
+extern int DefErrSetForC1(int, set *, int, char *, const char* ); /* MR21 */
+extern int DefErrSetForCC1(int, set *, int, char *, const char* ); /* MR21 */
+extern int DefErrSetWithSuffix(int, set *, int, char *, const char *); /* MR21 */
+extern void GenErrHdr( void );
+extern void dumpExpr( FILE *, char * );
+extern void addParm( Node *, char * );
+extern Graph buildAction( char *, int, int, int );
+extern Graph buildToken( char * );
+extern Graph buildWildCard( char * );
+extern Graph buildRuleRef( char * );
+extern Graph Or( Graph, Graph );
+extern Graph Cat( Graph, Graph );
+extern Graph makeOpt( Graph, int, char *);
+extern Graph makeBlk( Graph, int, char *);
+extern Graph makeLoop( Graph, int, char *);
+extern Graph makePlus( Graph, int, char *);
+extern Graph emptyAlt( void );
+extern Graph emptyAlt3( void );
+extern TokNode * newTokNode( void );
+extern RuleRefNode * newRNode( void );
+extern Junction * newJunction( void );
+extern ActionNode * newActionNode( void );
+extern char * makelocks( void );
+extern void preorder( Tree * );
+extern Tree * tnode( int );
+extern void _Tfree( Tree * );
+extern Tree * tdup( Tree * );
+extern int is_single_tuple( Tree * );
+extern Tree * tappend( Tree *, Tree * );
+extern void Tfree( Tree * );
+extern Tree * tlink( Tree *, Tree *, int );
+extern Tree * tshrink( Tree * );
+extern Tree * tflatten( Tree * );
+extern Tree * tJunc( Junction *, int, set * );
+extern Tree * tRuleRef( RuleRefNode *, int, set * );
+extern Tree * tToken( TokNode *, int, set * );
+extern Tree * tAction( ActionNode *, int, set * );
+extern int tmember( Tree *, Tree * );
+extern int tmember_constrained( Tree *, Tree * );
+extern Tree * tleft_factor( Tree * );
+extern Tree * trm_perm( Tree *, Tree * );
+extern void tcvt( set *, Tree * );
+extern Tree * permute( int, int );
+extern Tree * VerifyAmbig( Junction *, Junction *, unsigned **, set *, Tree **, Tree **, int * );
+extern set rJunc( Junction *, int, set * );
+extern set rRuleRef( RuleRefNode *, int, set * );
+extern set rToken( TokNode *, int, set * );
+extern set rAction( ActionNode *, int, set * );
+extern void HandleAmbiguity( Junction *, Junction *, Junction *, int );
+extern set First( Junction *, int, int, int * );
+extern void freeBlkFsets( Junction * );
+extern void genAction( ActionNode * );
+extern void genRuleRef( RuleRefNode * );
+extern void genToken( TokNode * );
+extern void genOptBlk( Junction * );
+extern void genLoopBlk( Junction *, Junction *, Junction *, int );
+extern void genLoopBegin( Junction * );
+extern void genPlusBlk( Junction * );
+extern void genSubBlk( Junction * );
+extern void genRule( Junction * );
+extern void genJunction( Junction * );
+extern void genEndBlk( Junction * );
+extern void genEndRule( Junction * );
+extern void genHdr( int );
+extern void genHdr1( int );
+extern void dumpAction( char *, FILE *, int, int, int, int );
+extern void dumpActionPlus(ActionNode*, char *, FILE *, int, int, int, int ); /* MR21 */
+extern Entry ** newHashTable( void );
+extern Entry * hash_add( Entry **, char *, Entry * );
+extern Entry * hash_get( Entry **, char * );
+extern void hashStat( Entry ** );
+extern char * mystrdup( char * );
+extern void genLexDescr( void );
+extern void dumpLexClasses( FILE * );
+extern void genDefFile( void );
+extern void DumpListOfParmNames( char *, FILE *, int ); /* MR5 janm 26-May-97 */
+extern int DumpNextNameInDef( char **, FILE * );
+extern void DumpOldStyleParms( char *, FILE * );
+extern void DumpType( char *, FILE * );
+extern int strmember( char *, char * );
+/* extern int HasComma( char * ); MR23 Replaced by hasMultipleOperands() */
+extern void DumpRetValStruct( FILE *, char *, int );
+extern char * StripQuotes( char * );
+extern int main( int, char *[] );
+extern void readDescr( void );
+extern FILE * NextFile( void );
+extern char * outnameX( char *, char *);
+extern char * outname( char * );
+extern void fatalFL( char *, char *, int );
+extern void fatal_intern( char *, char *, int );
+#ifdef VBOX
+# ifdef __GNUC__
+extern void __attribute__((noreturn)) fatal_intern( char *, char *, int );
+# endif
+#endif
+extern void cleanUp( void );
+extern char * eMsg3( char *, char *, char *, char * );
+extern char * eMsgd( char *, int );
+extern char * eMsgd2( char *, int, int );
+extern void s_fprT( FILE *, set );
+extern char * TerminalString( int );
+extern void lexclass( char * );
+extern void lexmode( int );
+extern int LexClassIndex( char * );
+extern int hasAction( char * );
+extern void setHasAction( char *, char * );
+extern int addTname( char * );
+extern int addTexpr( char * );
+extern int Tnum( char * );
+extern void Tklink( char *, char * );
+extern Entry * newEntry( char *, int );
+extern void list_add( ListNode **, void * );
+extern void list_free( ListNode **, int freeData ); /* MR10 */
+extern void list_apply( ListNode *, void (*)(void *) );
+extern int list_search_cstring (ListNode *, char *); /* MR27 */
+extern char * Fkey( char *, int, int );
+extern void FoPush( char *, int );
+extern void FoPop( int );
+extern void RegisterCycle( char *, int );
+extern void ResolveFoCycles( int );
+extern void pJunc( Junction * );
+extern void pRuleRef( RuleRefNode * );
+extern void pToken( TokNode * );
+extern void pAction( ActionNode * );
+extern void FoLink( Node * );
+extern void addFoLink( Node *, char *, Junction * );
+extern void GenCrossRef( Junction * );
+extern void defErr( char *, long, long, long, long, long, long );
+extern void genStdPCCTSIncludeFile(FILE *,char *); /* MR10 */
+extern char * pcctsBaseName(char *); /* MR32 */
+extern Predicate *find_predicates(Node *); /* MR10 */
+extern Predicate *MR_find_predicates_and_supp(Node *); /* MR13 */
+extern int predicateLookaheadDepth(ActionNode *); /* MR10 */
+extern void predicate_free(Predicate *); /* MR10 */
+extern Predicate * predicate_dup(Predicate *); /* MR10 */
+extern Predicate * predicate_dup_without_context(Predicate *); /* MR11 */
+extern void GenRulePrototypes(FILE *, Junction *);
+extern Junction *first_item_is_guess_block(Junction *);
+extern Junction *first_item_is_guess_block_extra(Junction * q); /* MR30 */
+extern Junction *analysis_point(Junction *);
+extern Tree *make_tree_from_sets(set *, set *);
+extern Tree *tdup_chain(Tree *);
+extern Tree *tdif(Tree *, Predicate *, set *, set *);
+extern set covered_set(Predicate *);
+extern void AmbiguityDialog(Junction *, int, Junction *, Junction *, int *, int *);
+extern void dumpAmbigMsg(set *, FILE *, int);
+extern void GenRuleFuncRedefs(FILE *, Junction *);
+extern void GenPredefinedSymbolRedefs(FILE *);
+extern void GenASTSymbolRedefs(FILE *);
+extern void GenRemapFile(void);
+extern void GenSetRedefs(FILE *);
+extern ForcedToken *newForcedToken(char *, int);
+extern void RemapForcedTokens(void);
+extern char *TokenOrExpr(int);
+extern void setUpperRange(TokNode *, char *);
+extern void GenParser_c_Hdr(void);
+extern void GenParser_h_Hdr(void);
+extern void GenRuleMemberDeclarationsForCC(FILE *, Junction *);
+extern int addForcedTname( char *, int );
+extern char *OutMetaName(char *);
+extern void OutFirstSetSymbol(Junction *q, char *); /* MR21 */
+extern void warnNoFL(char *err);
+extern void warnFL(char *err,char *f,int l);
+extern void warn(char *err);
+extern void warnNoCR( char *err );
+extern void errNoFL(char *err);
+extern void errFL(char *err,char *f,int l);
+extern void err(char *err);
+extern void errNoCR( char *err );
+extern void genPredTree( Predicate *p, Node *j, int ,int);
+extern UserAction *newUserAction(char *);
+extern char *gate_symbol(char *name);
+extern char *makeAltID(int blockid, int altnum);
+extern void DumpRemainingTokSets(void);
+extern void DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInit); /* MR23 */
+extern void DumpFormals(FILE *, char *, int bInit); /* MR23 */
+extern char* hideDefaultArgs(const char* pdecl); /* MR22 VHS */
+extern Predicate *computePredFromContextGuard(Graph,int *msgDone); /* MR21 */
+extern void recomputeContextGuard(Predicate *); /* MR13 */
+extern Predicate *new_pred(void);
+extern void chkGTFlag(void);
+extern void leAdd(LabelEntry *); /* MR7 */
+extern void leFixup(void); /* MR7 */
+extern void egAdd(ExceptionGroup *); /* MR7 */
+extern void egFixup(void); /* MR7 */
+extern void altAdd(Junction *); /* MR7 */
+extern void altFixup(void); /* MR7 */
+extern Predicate * MR_find_in_aSubBlk(Junction *alt); /* MR10 */
+extern Predicate * MR_predFlatten(Predicate *p); /* MR10 */
+extern Predicate * MR_predSimplifyALL(Predicate *p); /* MR10 */
+extern Predicate * MR_predSimplifyALLX(Predicate *p,int skipPass3); /* MR10 */
+extern int MR_allPredLeaves(Predicate *p); /* MR10 */
+extern void MR_cleanup_pred_trees(Predicate *p); /* MR10 */
+extern int MR_predicate_context_completed(Predicate *p); /* MR10 */
+extern void MR_check_pred_too_long(Predicate *p,set completion); /* MR10 */
+extern Tree * MR_remove_epsilon_from_tree(Tree *t); /* MR10 */
+extern Tree * MR_computeTreeAND(Tree *l,Tree *r); /* MR10 */
+extern int MR_tree_equ(Tree *big, Tree *small); /* MR10 */
+extern set MR_First(int ck,Junction *j,set *incomplete); /* MR10 */
+extern set MR_compute_pred_set(Predicate *p); /* MR10 */
+extern Tree * MR_compute_pred_tree_context(Predicate *p); /* MR10 */
+extern int MR_pointerStackPush(PointerStack *,void *); /* MR10 */
+extern void * MR_pointerStackPop(PointerStack *); /* MR10 */
+extern void * MR_pointerStackTop(PointerStack *); /* MR10 */
+extern void MR_pointerStackReset(PointerStack *); /* MR10 */
+extern void MR_backTraceReport(void); /* MR10 */
+extern void MR_alphaBetaTraceReport(void); /* MR14 */
+extern void MR_dumpRuleSet(set); /* MR14 */
+extern void MR_predContextPresent(Predicate *p,int *,int *); /* MR10 */
+extern void MR_dumpPred(Predicate *p,int withContext); /* MR10 */
+extern void MR_dumpPred1(int,Predicate *p,int withContext); /* MR10 */
+extern void MR_xxxIndent(FILE *f,int depth); /* MR11 */
+extern void MR_outputIndent(int depth); /* MR11 */
+extern void MR_stderrIndent(int depth); /* MR11 */
+extern Junction * MR_ruleReferenced(RuleRefNode *rrn); /* MR10 */
+extern Junction * MR_nameToRuleBlk(char *); /* MR10 */
+extern void MR_releaseResourcesUsedInRule(Node *); /* MR10 */
+extern void MR_dumpTreeX(int depth,Tree *t,int across); /* MR10 */
+extern void MR_dumpTreeF(FILE *f,int depth,Tree *t,int across); /* MR10 */
+extern void DumpFcache(void); /* MR10 */
+extern void MR_dumpTokenSet(FILE *f,int depth,set s); /* MR10 */
+extern void MR_traceAmbSource(set *,Junction *,Junction *); /* MR11 */
+extern void MR_traceAmbSourceK(Tree *,Junction *a1,Junction *a2); /* MR11 */
+extern void MR_traceAmbSourceKclient(void); /* MR20 */
+extern Node *MR_advance(Node *); /* MR11 */
+extern int MR_offsetFromRule(Node *); /* MR11 */
+extern char *MR_ruleNamePlusOffset(Node *); /* MR11 */
+extern int MR_max_height_of_tree(Tree *); /* MR11 */
+extern int MR_all_leaves_same_height(Tree *,int); /* MR11 */
+extern void MR_projectTreeOntoSet(Tree *t,int k,set *); /* MR11 */
+extern Tree *MR_make_tree_from_set(set); /* MR11 */
+extern Predicate *MR_removeRedundantPredPass3(Predicate *); /* MR11 */
+extern void MR_pred_depth(Predicate *,int *); /* MR11 */
+extern int MR_comparePredicates(Predicate *,Predicate *); /* MR11 */
+extern Predicate * MR_unfold(Predicate *); /* MR11 */
+extern void MR_simplifyInverted(Predicate *,int); /* MR11 */
+extern int MR_secondPredicateUnreachable /* MR11 */
+ (Predicate *first,Predicate *second); /* MR11 */
+extern void MR_clearPredEntry(Predicate *); /* MR11 */
+extern void MR_orphanRules(FILE *); /* MR12 */
+extern void MR_merge_contexts(Tree *); /* MR12 */
+extern int ci_strequ(char *,char *); /* MR12 */
+extern void MR_guardPred_plainSet(ActionNode *anode,Predicate *); /* MR12c */
+extern void MR_suppressSearchReport(void); /* MR12c */
+extern Predicate * MR_suppressK(Node *,Predicate *); /* MR13 */
+extern void MR_backTraceDumpItem(FILE *,int skip,Node *n); /* MR13 */
+extern void MR_backTraceDumpItemReset(void); /* MR13 */
+extern Junction * MR_junctionWithoutP2(Junction *); /* MR13 */
+extern void MR_setConstrainPointer(set *); /* MR18 */
+extern void BlockPreambleOption(Junction *q, char * pSymbol); /* MR23 */
+extern char* getInitializer(char *); /* MR23 */
+extern char *endFormal(char *pStart, /* MR23 */
+ char **ppDataType, /* MR23 */
+ char **ppSymbol, /* MR23 */
+ char **ppEqualSign, /* MR23 */
+ char **ppValue, /* MR23 */
+ char **ppSeparator, /* MR23 */
+ int *pNext); /* MR23 */
+extern char *strBetween(char *pStart, /* MR23 */
+ char *pNext, /* MR23 */
+ char *pStop); /* MR23 */
+extern int hasMultipleOperands(char *); /* MR23 */
+extern void DumpInitializers(FILE*, RuleEntry*, char*); /* MR23 */
+extern int isTermEntryTokClass(TermEntry *); /* MR23 */
+extern int isEmptyAlt(Node *, Node *); /* MR23 */
+#else
+extern int STRICMP();
+extern void istackreset();
+extern int istacksize();
+extern void pushint();
+extern int popint();
+extern int istackempty();
+extern int topint();
+extern void NewSetWd();
+extern void DumpSetWd();
+extern void DumpSetWdForC();
+extern void DumpSetWdForCC();
+extern void NewSet();
+extern void FillSet();
+extern void ComputeErrorSets();
+extern void ComputeTokSets();
+extern void SubstErrorClass();
+extern int DefErrSet();
+extern int DefErrSetForC();
+extern int DefErrSetForCC();
+extern int DefErrSet1();
+extern int DefErrSetForC1();
+extern int DefErrSetForCC1();
+extern int DefErrSetWithSuffix(); /* MR21 */
+extern void GenErrHdr();
+extern void dumpExpr();
+extern void addParm();
+extern Graph buildAction();
+extern Graph buildToken();
+extern Graph buildWildCard();
+extern Graph buildRuleRef();
+extern Graph Or();
+extern Graph Cat();
+extern Graph makeOpt();
+extern Graph makeBlk();
+extern Graph makeLoop();
+extern Graph makePlus();
+extern Graph emptyAlt();
+extern Graph emptyAlt3();
+extern TokNode * newTokNode();
+extern RuleRefNode * newRNode();
+extern Junction * newJunction();
+extern ActionNode * newActionNode();
+extern char * makelocks();
+extern void preorder();
+extern Tree * tnode();
+extern void _Tfree();
+extern Tree * tdup();
+extern int is_single_tuple();
+extern Tree * tappend();
+extern void Tfree();
+extern Tree * tlink();
+extern Tree * tshrink();
+extern Tree * tflatten();
+extern Tree * tJunc();
+extern Tree * tRuleRef();
+extern Tree * tToken();
+extern Tree * tAction();
+extern int tmember();
+extern int tmember_constrained();
+extern Tree * tleft_factor();
+extern Tree * trm_perm();
+extern void tcvt();
+extern Tree * permute();
+extern Tree * VerifyAmbig();
+extern set rJunc();
+extern set rRuleRef();
+extern set rToken();
+extern set rAction();
+extern void HandleAmbiguity();
+extern set First();
+extern void freeBlkFsets();
+extern void genAction();
+extern void genRuleRef();
+extern void genToken();
+extern void genOptBlk();
+extern void genLoopBlk();
+extern void genLoopBegin();
+extern void genPlusBlk();
+extern void genSubBlk();
+extern void genRule();
+extern void genJunction();
+extern void genEndBlk();
+extern void genEndRule();
+extern void genHdr();
+extern void genHdr1();
+extern void dumpAction();
+extern void dumpActionPlus(); /* MR21 */
+extern Entry ** newHashTable();
+extern Entry * hash_add();
+extern Entry * hash_get();
+extern void hashStat();
+extern char * mystrdup();
+extern void genLexDescr();
+extern void dumpLexClasses();
+extern void genDefFile();
+extern void DumpListOfParmNames(); /* MR5 janm 26-May-97 */
+extern int DumpNextNameInDef();
+extern void DumpOldStyleParms();
+extern void DumpType();
+extern int strmember();
+/* extern int HasComma(); MR23 Replaced by hasMultipleOperands() */
+extern void DumpRetValStruct();
+extern char * StripQuotes();
+extern int main();
+extern void readDescr();
+extern FILE * NextFile();
+extern char * outnameX();
+extern char * outname();
+extern void fatalFL();
+extern void fatal_intern();
+extern void cleanUp();
+extern char * eMsg3();
+extern char * eMsgd();
+extern char * eMsgd2();
+extern void s_fprT();
+extern char * TerminalString();
+extern void lexclass();
+extern void lexmode();
+extern int LexClassIndex();
+extern int hasAction();
+extern void setHasAction();
+extern int addTname();
+extern int addTexpr();
+extern int Tnum();
+extern void Tklink();
+extern Entry * newEntry();
+extern void list_add();
+extern void list_free(); /* MR10 */
+extern void list_apply();
+extern int list_search_cstring (); /* MR27 */
+extern char * Fkey();
+extern void FoPush();
+extern void FoPop();
+extern void RegisterCycle();
+extern void ResolveFoCycles();
+extern void pJunc();
+extern void pRuleRef();
+extern void pToken();
+extern void pAction();
+extern void FoLink();
+extern void addFoLink();
+extern void GenCrossRef();
+extern void defErr();
+extern void genStdPCCTSIncludeFile();
+extern char * pcctsBaseName(); /* MR32 */
+extern Predicate *find_predicates();
+extern Predicate *MR_find_predicates_and_supp(); /* MR13 */
+extern int predicateLookaheadDepth(); /* MR10 */
+extern void predicate_free(); /* MR10 */
+extern Predicate * predicate_dup(); /* MR10 */
+extern Predicate * predicate_dup_without_context(); /* MR11 */
+extern void GenRulePrototypes();
+extern Junction *first_item_is_guess_block();
+extern Junction *first_item_is_guess_block_extra(); /* MR30 */
+extern Junction *analysis_point();
+extern Tree *make_tree_from_sets();
+extern Tree *tdup_chain();
+extern Tree *tdif();
+extern set covered_set();
+extern void AmbiguityDialog();
+extern void dumpAmbigMsg();
+extern void GenRuleFuncRedefs();
+extern void GenPredefinedSymbolRedefs();
+extern void GenASTSymbolRedefs();
+extern void GenRemapFile();
+extern void GenSetRedefs();
+extern ForcedToken *newForcedToken();
+extern void RemapForcedTokens();
+extern char *TokenOrExpr();
+extern void setUpperRange();
+extern void GenParser_c_Hdr();
+extern void GenParser_h_Hdr();
+extern void GenRuleMemberDeclarationsForCC();
+extern int addForcedTname();
+extern char *OutMetaName();
+extern void OutFirstSetSymbol(); /* MR21 */
+extern void warnNoFL();
+extern void warnFL();
+extern void warn();
+extern void warnNoCR();
+extern void errNoFL();
+extern void errFL();
+extern void err();
+extern void errNoCR();
+extern void genPredTree();
+extern UserAction *newUserAction();
+extern char *gate_symbol();
+extern char *makeAltID();
+extern void DumpRemainingTokSets();
+extern void DumpANSIFunctionArgDef();
+extern void DumpFormals(); /* MR23 */
+extern char* hideDefaultArgs(); /* MR22 VHS */
+extern Predicate *computePredFromContextGuard();
+extern void recomputeContextGuard(); /* MR13 */
+extern Predicate *new_pred();
+extern void chkGTFlag();
+extern void leAdd(); /* MR7 */
+extern void leFixup(); /* MR7 */
+extern void egAdd(); /* MR7 */
+extern void egFixup(); /* MR7 */
+extern void altAdd(); /* MR7 */
+extern void altFixup(); /* MR7 */
+extern Predicate * MR_find_in_aSubBlk(); /* MR10 */
+extern Predicate * MR_predFlatten(); /* MR10 */
+extern Predicate * MR_predSimplifyALL(); /* MR10 */
+extern Predicate * MR_predSimplifyALLX(); /* MR10 */
+extern void MR_cleanup_pred_trees(); /* MR10 */
+extern int MR_allPredLeaves(); /* MR10 */
+extern int MR_predicate_context_completed(); /* MR10 */
+extern void MR_check_pred_too_long(); /* MR10 */
+extern Tree * MR_remove_epsilon_from_tree(); /* MR10 */
+extern Tree * MR_computeTreeAND(); /* MR10 */
+extern int MR_tree_equ(); /* MR10 */
+extern set MR_First(); /* MR10 */
+extern set MR_compute_pred_set(); /* MR10 */
+extern Tree * MR_compute_pred_tree_context(); /* MR10 */
+extern int MR_pointerStackPush(); /* MR10 */
+extern void * MR_pointerStackPop(); /* MR10 */
+extern void * MR_pointerStackTop(); /* MR10 */
+extern void MR_pointerStackReset(); /* MR10 */
+extern void MR_backTraceReport(); /* MR10 */
+extern void MR_alphaBetaTraceReport(); /* MR14 */
+extern void MR_dumpRuleSet(); /* MR14 */
+extern void MR_predContextPresent(); /* MR10 */
+extern void MR_dumpPred(); /* MR10 */
+extern void MR_dumpPred1(); /* MR10 */
+extern void MR_xxxIndent(); /* MR11 */
+extern void MR_stderrIndent(); /* MR11 */
+extern void MR_outputIndent(); /* MR11 */
+extern Junction * MR_ruleReferenced(); /* MR10 */
+extern void MR_releaseResourcesUsedInRule(); /* MR10 */
+extern void MR_dumpTreeX(); /* MR10 */
+extern void MR_dumpTreeF(); /* MR10 */
+extern void DumpFcache(); /* MR10 */
+extern void MR_dumpTokenSet(); /* MR10 */
+extern void MR_traceAmbSource(); /* MR11 */
+extern Node *MR_advance(); /* MR11 */
+extern int MR_offsetFromRule(); /* MR11 */
+extern char *MR_ruleNamePlusOffset(); /* MR11 */
+extern void MR_traceAmbSourceK(); /* MR11 */
+extern void MR_traceAmbSourceKclient(); /* [i_a] added */
+extern int MR_max_height_of_tree(); /* MR11 */
+extern int MR_all_leaves_same_height(); /* MR11 */
+extern void MR_projectTreeOntoSet(); /* MR11 */
+extern Tree *MR_make_tree_from_set(); /* MR11 */
+extern Predicate *MR_removeRedundantPredPass3(); /* MR11 */
+extern void MR_pred_depth(); /* MR11 */
+extern int MR_comparePredicates(); /* MR11 */
+extern Predicate * MR_unfold(); /* MR11 */
+extern void MR_simplifyInverted(); /* MR11 */
+extern int MR_secondPredicateUnreachable(); /* MR11 */
+extern Junction * MR_nameToRuleBlk(); /* MR10 */
+extern void MR_clearPredEntry(); /* MR11 */
+extern void MR_orphanRules(); /* MR12 */
+extern void MR_merge_contexts(); /* MR12 */
+extern int ci_strequ(); /* MR12 */
+extern void MR_guardPred_plainSet(); /* MR12c */
+extern void MR_suppressSearchReport(); /* MR12c */
+extern Predicate * MR_suppressK(); /* MR13 */
+extern void MR_backTraceDumpItem(); /* MR13 */
+extern void MR_backTraceDumpItemReset(); /* MR13 */
+extern Junction * MR_junctionWithoutP2(); /* MR13 */
+extern void MR_setConstrainPointer(); /* MR18 */
+extern void BlockPreambleOption(); /* MR23 */
+extern char* getInitializer(); /* MR23 */
+extern int hasMultipleOperands(); /* MR23 */
+extern char *endFormal(); /* MR23 */
+extern char *strBetween(); /* MR23 */
+extern void DumpInitializers(); /* MR23 */
+extern int isTermEntryTokClass(); /* MR23 */
+extern int isEmptyAlt();
+
+#endif
+
+#ifdef __USE_PROTOS
+#include <stdlib.h>
+#endif
+
+/* MR20 G. Hobbelt Create proper externs for dlg variables */
+
+extern set attribsRefdFromAction;
+extern int inAlt;
+extern int UsedOldStyleAttrib;
+extern int UsedNewStyleLabel;
+
+#define MAX_BLK_LEVEL 100 /* MR23 */
+extern int CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */
+extern int CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/scan.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/scan.c
new file mode 100644
index 00000000..24651f97
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/scan.c
@@ -0,0 +1,5735 @@
+
+/* parser.dlg -- DLG Description of scanner
+ *
+ * Generated from: antlr.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include "pcctscfg.h"
+#include "set.h"
+#include <ctype.h>
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#define zzcr_attr(attr,tok,t) /*vbox: */ memset((attr), 0, sizeof(*attr))
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+LOOKAHEAD
+
+void
+#ifdef __USE_PROTOS
+zzerraction(void)
+#else
+zzerraction()
+#endif
+{
+ (*zzerr)("invalid token");
+ zzadvance();
+ zzskip();
+}
+/*
+ * D L G tables
+ *
+ * Generated from: parser.dlg
+ *
+ * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz
+ * Purdue University Electrical Engineering
+ * DLG Version 1.33MR33
+ */
+
+#include "mode.h"
+
+
+
+
+/* maintained, but not used for now */
+set AST_nodes_refd_in_actions = set_init;
+int inAlt = 0;
+set attribsRefdFromAction = set_init; /* MR20 */
+int UsedOldStyleAttrib = 0;
+int UsedNewStyleLabel = 0;
+#ifdef __USE_PROTOS
+char *inline_set(char *);
+#else
+char *inline_set();
+#endif
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+/* MR1 in DLG action */
+
+int tokenActionActive=0; /* MR1 */
+
+
+
+
+
+static char *
+#ifdef __USE_PROTOS
+getFileNameFromTheLineInfo(char *toStr, char *fromStr)
+#else
+getFileNameFromTheLineInfo(toStr, fromStr)
+char *toStr, *fromStr;
+#endif
+{
+ int i, j, k;
+
+ if (!fromStr || !toStr) return toStr;
+
+ /* find the first " */
+
+ for (i=0;
+ (i<MaxFileName) &&
+ (fromStr[i] != '\n') &&
+ (fromStr[i] != '\r') &&
+ (fromStr[i] != '\"');
+ i++) /* nothing */ ;
+
+ if ( (i == MaxFileName) ||
+ (fromStr[i] == '\n') ||
+ (fromStr[i] == '\r') ) {
+ return toStr;
+}
+
+ /* find the second " */
+
+ for (j=i+1;
+(j<MaxFileName) &&
+(fromStr[j] != '\n') &&
+(fromStr[j] != '\r') &&
+(fromStr[j] != '\"');
+j++) /* nothing */ ;
+
+ if ((j == MaxFileName) ||
+(fromStr[j] == '\n') ||
+(fromStr[j] == '\r') ) {
+ return toStr;
+}
+
+ /* go back until the last / or \ */
+
+ for (k=j-1;
+(fromStr[k] != '\"') &&
+(fromStr[k] != '/') &&
+(fromStr[k] != '\\');
+k--) /* nothing */ ;
+
+ /* copy the string after " / or \ into toStr */
+
+ for (i=k+1; fromStr[i] != '\"'; i++) {
+toStr[i-k-1] = fromStr[i];
+}
+
+ toStr[i-k-1] = '\0';
+
+ return toStr;
+}
+
+/* MR14 end of a block to support #line in antlr source code */
+
+
+
+
+#ifdef __USE_PROTOS
+void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */
+#else
+void mark_label_used_in_sem_pred(le) /* MR10 */
+LabelEntry *le;
+#endif
+{
+ TokNode *tn;
+ require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");
+ tn=(TokNode *)le->elem;
+ require (tn->label != 0,"mark_label_used... TokNode has no label");
+ tn->label_used_in_semantic_pred=1;
+}
+
+static void act1()
+{
+ NLA = Eof;
+ /* L o o k F o r A n o t h e r F i l e */
+ {
+ FILE *new_input;
+ new_input = NextFile();
+ if ( new_input == NULL ) { NLA=Eof; return; }
+ fclose( input );
+ input = new_input;
+ zzrdstream( input );
+ zzskip(); /* Skip the Eof (@) char i.e continue */
+ }
+ }
+
+
+static void act2()
+{
+ NLA = 76;
+ zzskip();
+ }
+
+
+static void act3()
+{
+ NLA = 77;
+ zzline++; zzskip();
+ }
+
+
+static void act4()
+{
+ NLA = 78;
+ zzmode(ACTIONS); zzmore();
+ istackreset();
+ pushint(']');
+ }
+
+
+static void act5()
+{
+ NLA = 79;
+ action_file=CurFile; action_line=zzline;
+ zzmode(ACTIONS); zzmore();
+ list_free(&CurActionLabels,0); /* MR10 */
+ numericActionLabel=0; /* MR10 */
+ istackreset();
+ pushint('>');
+ }
+
+
+static void act6()
+{
+ NLA = 80;
+ zzmode(STRINGS); zzmore();
+ }
+
+
+static void act7()
+{
+ NLA = 81;
+ zzmode(COMMENTS); zzskip();
+ }
+
+
+static void act8()
+{
+ NLA = 82;
+ warn("Missing /*; found dangling */"); zzskip();
+ }
+
+
+static void act9()
+{
+ NLA = 83;
+ zzmode(CPP_COMMENTS); zzskip();
+ }
+
+
+static void act10()
+{
+ NLA = 84;
+
+ zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();
+ getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);
+ }
+
+
+static void act11()
+{
+ NLA = 85;
+
+ zzline++; zzmore();
+ }
+
+
+static void act12()
+{
+ NLA = 86;
+ warn("Missing <<; found dangling >>"); zzskip();
+ }
+
+
+static void act13()
+{
+ NLA = WildCard;
+ }
+
+
+static void act14()
+{
+ NLA = 88;
+ FoundException = 1; /* MR6 */
+ FoundAtOperator = 1;
+ }
+
+
+static void act15()
+{
+ NLA = Pragma;
+ }
+
+
+static void act16()
+{
+ NLA = FirstSetSymbol;
+ }
+
+
+static void act17()
+{
+ NLA = 94;
+ }
+
+
+static void act18()
+{
+ NLA = 95;
+ }
+
+
+static void act19()
+{
+ NLA = 96;
+ }
+
+
+static void act20()
+{
+ NLA = 97;
+ }
+
+
+static void act21()
+{
+ NLA = 98;
+ }
+
+
+static void act22()
+{
+ NLA = 99;
+ }
+
+
+static void act23()
+{
+ NLA = 102;
+ }
+
+
+static void act24()
+{
+ NLA = 103;
+ }
+
+
+static void act25()
+{
+ NLA = 104;
+ }
+
+
+static void act26()
+{
+ NLA = 105;
+ }
+
+
+static void act27()
+{
+ NLA = 106;
+ }
+
+
+static void act28()
+{
+ NLA = 107;
+ }
+
+
+static void act29()
+{
+ NLA = 108;
+ }
+
+
+static void act30()
+{
+ NLA = 109;
+ }
+
+
+static void act31()
+{
+ NLA = 110;
+ }
+
+
+static void act32()
+{
+ NLA = 111;
+ }
+
+
+static void act33()
+{
+ NLA = 112;
+ }
+
+
+static void act34()
+{
+ NLA = 113;
+ }
+
+
+static void act35()
+{
+ NLA = 114;
+ }
+
+
+static void act36()
+{
+ NLA = 115;
+ }
+
+
+static void act37()
+{
+ NLA = 116;
+ }
+
+
+static void act38()
+{
+ NLA = 117;
+ }
+
+
+static void act39()
+{
+ NLA = 118;
+ }
+
+
+static void act40()
+{
+ NLA = 119;
+ }
+
+
+static void act41()
+{
+ NLA = 120;
+ }
+
+
+static void act42()
+{
+ NLA = 121;
+ }
+
+
+static void act43()
+{
+ NLA = 122;
+ }
+
+
+static void act44()
+{
+ NLA = 123;
+ }
+
+
+static void act45()
+{
+ NLA = 124;
+ }
+
+
+static void act46()
+{
+ NLA = 125;
+ }
+
+
+static void act47()
+{
+ NLA = 126;
+ }
+
+
+static void act48()
+{
+ NLA = 127;
+ }
+
+
+static void act49()
+{
+ NLA = 128;
+ }
+
+
+static void act50()
+{
+ NLA = 129;
+ }
+
+
+static void act51()
+{
+ NLA = 130;
+ }
+
+
+static void act52()
+{
+ NLA = 131;
+ }
+
+
+static void act53()
+{
+ NLA = 132;
+ }
+
+
+static void act54()
+{
+ NLA = 133;
+ }
+
+
+static void act55()
+{
+ NLA = 134;
+ }
+
+
+static void act56()
+{
+ NLA = 135;
+ }
+
+
+static void act57()
+{
+ NLA = NonTerminal;
+
+ while ( zzchar==' ' || zzchar=='\t' ) {
+ zzadvance();
+ }
+ if ( zzchar == ':' && inAlt ) NLA = LABEL;
+ }
+
+
+static void act58()
+{
+ NLA = TokenTerm;
+
+ while ( zzchar==' ' || zzchar=='\t' ) {
+ zzadvance();
+ }
+ if ( zzchar == ':' && inAlt ) NLA = LABEL;
+ }
+
+
+static void act59()
+{
+ NLA = 136;
+ warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip();
+ }
+
+static unsigned char shift0[257] = {
+ 0, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 1, 2, 58, 58, 3, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 1, 40, 6, 9, 58, 58, 45,
+ 58, 46, 47, 8, 52, 58, 58, 18, 7, 16,
+ 14, 15, 16, 16, 16, 16, 16, 16, 16, 41,
+ 42, 5, 48, 17, 53, 19, 56, 56, 56, 56,
+ 56, 26, 56, 56, 56, 56, 56, 51, 56, 56,
+ 56, 56, 56, 56, 29, 56, 56, 56, 56, 56,
+ 56, 56, 4, 20, 58, 50, 57, 58, 23, 31,
+ 38, 34, 13, 35, 24, 33, 11, 55, 36, 10,
+ 25, 12, 32, 21, 55, 22, 27, 28, 54, 55,
+ 55, 43, 30, 55, 39, 44, 37, 49, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58
+};
+
+
+static void act60()
+{
+ NLA = Eof;
+ }
+
+
+static void act61()
+{
+ NLA = QuotedTerm;
+ zzmode(START);
+ }
+
+
+static void act62()
+{
+ NLA = 3;
+
+ zzline++;
+ warn("eoln found in string");
+ zzskip();
+ }
+
+
+static void act63()
+{
+ NLA = 4;
+ zzline++; zzmore();
+ }
+
+
+static void act64()
+{
+ NLA = 5;
+ zzmore();
+ }
+
+
+static void act65()
+{
+ NLA = 6;
+ zzmore();
+ }
+
+static unsigned char shift1[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 2, 5, 5, 3, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 1, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 4, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act66()
+{
+ NLA = Eof;
+ }
+
+
+static void act67()
+{
+ NLA = 7;
+ zzmode(ACTIONS); zzmore();
+ }
+
+
+static void act68()
+{
+ NLA = 8;
+
+ zzline++;
+ warn("eoln found in string (in user action)");
+ zzskip();
+ }
+
+
+static void act69()
+{
+ NLA = 9;
+ zzline++; zzmore();
+ }
+
+
+static void act70()
+{
+ NLA = 10;
+ zzmore();
+ }
+
+
+static void act71()
+{
+ NLA = 11;
+ zzmore();
+ }
+
+static unsigned char shift2[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 2, 5, 5, 3, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 1, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 4, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act72()
+{
+ NLA = Eof;
+ }
+
+
+static void act73()
+{
+ NLA = 12;
+ zzmode(ACTIONS); zzmore();
+ }
+
+
+static void act74()
+{
+ NLA = 13;
+
+ zzline++;
+ warn("eoln found in char literal (in user action)");
+ zzskip();
+ }
+
+
+static void act75()
+{
+ NLA = 14;
+ zzmore();
+ }
+
+
+static void act76()
+{
+ NLA = 15;
+ zzmore();
+ }
+
+static unsigned char shift3[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 2, 5, 5, 3, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 1, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 4, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act77()
+{
+ NLA = Eof;
+ }
+
+
+static void act78()
+{
+ NLA = 16;
+ zzmode(ACTIONS); zzmore();
+ }
+
+
+static void act79()
+{
+ NLA = 17;
+ zzmore();
+ }
+
+
+static void act80()
+{
+ NLA = 18;
+ zzline++; zzmore(); DAWDLE;
+ }
+
+
+static void act81()
+{
+ NLA = 19;
+ zzmore();
+ }
+
+static unsigned char shift4[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 3, 5, 5, 4, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 1, 5, 5, 5, 5, 2, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act82()
+{
+ NLA = Eof;
+ }
+
+
+static void act83()
+{
+ NLA = 20;
+ zzmode(PARSE_ENUM_FILE);
+ zzmore();
+ }
+
+
+static void act84()
+{
+ NLA = 21;
+ zzmore();
+ }
+
+
+static void act85()
+{
+ NLA = 22;
+ zzline++; zzmore(); DAWDLE;
+ }
+
+
+static void act86()
+{
+ NLA = 23;
+ zzmore();
+ }
+
+static unsigned char shift5[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 3, 5, 5, 4, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 1, 5, 5, 5, 5, 2, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act87()
+{
+ NLA = Eof;
+ }
+
+
+static void act88()
+{
+ NLA = 24;
+ zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE;
+ }
+
+
+static void act89()
+{
+ NLA = 25;
+ zzskip();
+ }
+
+static unsigned char shift6[257] = {
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 1, 3, 3, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3
+};
+
+
+static void act90()
+{
+ NLA = Eof;
+ }
+
+
+static void act91()
+{
+ NLA = 26;
+ zzline++; zzmode(ACTIONS); zzmore(); DAWDLE;
+ }
+
+
+static void act92()
+{
+ NLA = 27;
+ zzmore();
+ }
+
+static unsigned char shift7[257] = {
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 1, 3, 3, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3
+};
+
+
+static void act93()
+{
+ NLA = Eof;
+ }
+
+
+static void act94()
+{
+ NLA = 28;
+ zzline++; zzmode(START); zzskip(); DAWDLE;
+ }
+
+
+static void act95()
+{
+ NLA = 29;
+ zzskip();
+ }
+
+static unsigned char shift8[257] = {
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 1, 3, 3, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3
+};
+
+
+static void act96()
+{
+ NLA = Eof;
+ }
+
+
+static void act97()
+{
+ NLA = 30;
+ zzmode(START); zzskip();
+ }
+
+
+static void act98()
+{
+ NLA = 31;
+ zzskip();
+ }
+
+
+static void act99()
+{
+ NLA = 32;
+ zzline++; zzskip(); DAWDLE;
+ }
+
+
+static void act100()
+{
+ NLA = 33;
+ zzskip();
+ }
+
+static unsigned char shift9[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 3, 5, 5, 4, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 1, 5, 5, 5, 5, 2, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act101()
+{
+ NLA = Eof;
+ }
+
+
+static void act102()
+{
+ NLA = Action;
+ /* these do not nest */
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ NLATEXT[1] = ' ';
+ zzbegexpr[0] = ' ';
+ zzbegexpr[1] = ' ';
+ if ( zzbufovf ) {
+ err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));
+ }
+
+/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */
+ /* MR1 in DLG action */
+ /* MR1 Doesn't matter what kind of action it is - reset*/
+
+ tokenActionActive=0; /* MR1 */
+ }
+
+
+static void act103()
+{
+ NLA = Pred;
+ /* these do not nest */
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ NLATEXT[1] = ' ';
+ zzbegexpr[0] = '\0';
+ if ( zzbufovf ) {
+ err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));
+ };
+#ifdef __cplusplus__
+ /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+#ifdef __STDC__
+ /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+#ifdef __USE_PROTOS
+ /* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);
+#else
+ /* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred);
+#endif
+#endif
+#endif
+ }
+
+
+static void act104()
+{
+ NLA = PassAction;
+ if ( topint() == ']' ) {
+ popint();
+ if ( istackempty() ) /* terminate action */
+ {
+ zzmode(START);
+ NLATEXT[0] = ' ';
+ zzbegexpr[0] = ' ';
+ if ( zzbufovf ) {
+ err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));
+ }
+ }
+ else {
+ /* terminate $[..] and #[..] */
+ if ( GenCC ) zzreplstr("))");
+ else zzreplstr(")");
+ zzmore();
+ }
+ }
+ else if ( topint() == '|' ) { /* end of simple [...] */
+ popint();
+ zzmore();
+ }
+ else zzmore();
+ }
+
+
+static void act105()
+{
+ NLA = 37;
+
+ zzmore();
+ zzreplstr(inline_set(zzbegexpr+
+ strlen("consumeUntil(")));
+ }
+
+
+static void act106()
+{
+ NLA = 38;
+ zzmore();
+ }
+
+
+static void act107()
+{
+ NLA = 39;
+ zzline++; zzmore(); DAWDLE;
+ }
+
+
+static void act108()
+{
+ NLA = 40;
+ zzmore();
+ }
+
+
+static void act109()
+{
+ NLA = 41;
+ zzmore();
+ }
+
+
+static void act110()
+{
+ NLA = 42;
+ if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}
+ else err("$$ use invalid in C++ mode");
+ }
+
+
+static void act111()
+{
+ NLA = 43;
+ if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}
+ else err("$[] use invalid in C++ mode");
+ }
+
+
+static void act112()
+{
+ NLA = 44;
+
+ pushint(']');
+ if ( !GenCC ) zzreplstr("zzconstr_attr(");
+ else err("$[..] use invalid in C++ mode");
+ zzmore();
+ }
+
+
+static void act113()
+{
+ NLA = 45;
+ {
+ static char buf[100];
+ numericActionLabel=1; /* MR10 */
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("$i attrib ref too big");
+ set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",
+ BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"_t%d%s",
+ BlkLevel-1,zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ }
+
+
+static void act114()
+{
+ NLA = 46;
+ {
+ static char buf[100];
+ numericActionLabel=1; /* MR10 */
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("$i.field attrib ref too big");
+ zzbegexpr[strlen(zzbegexpr)-1] = ' ';
+ set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",
+ BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"_t%d%s.",
+ BlkLevel-1,zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ }
+
+
+static void act115()
+{
+ NLA = 47;
+ {
+ static char buf[100];
+ static char i[20], j[20];
+ char *p,*q;
+ numericActionLabel=1; /* MR10 */
+ if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");
+ for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {
+ if ( q == &i[20] )
+ fatalFL("i of $i.j attrib ref too big",
+ FileStr[CurFile], zzline );
+ *q++ = *p;
+ }
+ *q = '\0';
+ for (p++, q= &j[0]; *p!='\0'; p++) {
+ if ( q == &j[20] )
+ fatalFL("j of $i.j attrib ref too big",
+ FileStr[CurFile], zzline );
+ *q++ = *p;
+ }
+ *q = '\0';
+ if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);
+ else sprintf(buf,"_t%s%s",i,j);
+ zzreplstr(buf);
+ zzmore();
+ UsedOldStyleAttrib = 1;
+ if ( UsedNewStyleLabel )
+ err("cannot mix old-style $i with new-style labels");
+ }
+ }
+
+
+static void act116()
+{
+ NLA = 48;
+ { static char buf[300]; LabelEntry *el;
+ zzbegexpr[0] = ' ';
+ if ( CurRule != NULL &&
+ strcmp(CurRule, &zzbegexpr[1])==0 ) {
+ if ( !GenCC ) zzreplstr("zzaRet");
+ }
+ else if ( CurRetDef != NULL &&
+ strmember(CurRetDef, &zzbegexpr[1])) {
+ if ( hasMultipleOperands( CurRetDef ) ) {
+ require (strlen(zzbegexpr)<=(size_t)285,
+ "$retval attrib ref too big");
+ sprintf(buf,"_retv.%s",&zzbegexpr[1]);
+ zzreplstr(buf);
+ }
+ else zzreplstr("_retv");
+ }
+ else if ( CurParmDef != NULL &&
+ strmember(CurParmDef, &zzbegexpr[1])) {
+ ;
+ }
+ else if ( Elabel==NULL ) {
+ { err("$-variables in actions outside of rules are not allowed"); }
+ } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {
+ /* MR10 */
+ /* MR10 */ /* element labels might exist without an elem when */
+ /* MR10 */ /* it is a forward reference (to a rule) */
+ /* MR10 */
+ /* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )
+ /* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }
+ /* MR10 */
+ /* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {
+ /* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs");
+ /* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...>>\")");
+ /* MR10 */ };
+ /* MR10 */
+ /* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */
+ /* MR10 */ /* element labels contain pointer to the owners node */
+ /* MR10 */
+ /* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) {
+ /* MR10 */ list_add(&CurActionLabels,el);
+ /* MR10 */ };
+}
+else
+warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));
+}
+zzmore();
+ }
+
+
+static void act117()
+{
+ NLA = 49;
+ zzreplstr("(*_root)"); zzmore(); chkGTFlag();
+ }
+
+
+static void act118()
+{
+ NLA = 50;
+ if ( GenCC ) {
+ if (NewAST) zzreplstr("(newAST)");
+ else zzreplstr("(new AST)");}
+ else {zzreplstr("zzastnew()");} zzmore();
+ chkGTFlag();
+ }
+
+
+static void act119()
+{
+ NLA = 51;
+ zzreplstr("NULL"); zzmore(); chkGTFlag();
+ }
+
+
+static void act120()
+{
+ NLA = 52;
+ {
+ static char buf[100];
+ if ( strlen(zzbegexpr)>(size_t)85 )
+ fatal("#i AST ref too big");
+ if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);
+ else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);
+ zzreplstr(buf);
+ zzmore();
+ set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);
+ chkGTFlag();
+ }
+ }
+
+
+static void act121()
+{
+ NLA = 53;
+
+ zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();
+ getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);
+ }
+
+
+static void act122()
+{
+ NLA = 54;
+
+ zzline++; zzmore();
+ }
+
+
+static void act123()
+{
+ NLA = 55;
+
+ if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||
+ strcmp(zzbegexpr, "#if")==0 ||
+ strcmp(zzbegexpr, "#else")==0 ||
+ strcmp(zzbegexpr, "#endif")==0 ||
+ strcmp(zzbegexpr, "#ifndef")==0 ||
+ strcmp(zzbegexpr, "#define")==0 ||
+ strcmp(zzbegexpr, "#pragma")==0 ||
+ strcmp(zzbegexpr, "#undef")==0 ||
+ strcmp(zzbegexpr, "#import")==0 ||
+ strcmp(zzbegexpr, "#line")==0 ||
+ strcmp(zzbegexpr, "#include")==0 ||
+ strcmp(zzbegexpr, "#error")==0) )
+ {
+ static char buf[100];
+ sprintf(buf, "%s_ast", zzbegexpr+1);
+ /* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));
+ zzreplstr(buf);
+ chkGTFlag();
+ }
+ zzmore();
+ }
+
+
+static void act124()
+{
+ NLA = 56;
+
+ pushint(']');
+ if ( GenCC ) {
+ if (NewAST) zzreplstr("(newAST(");
+ else zzreplstr("(new AST("); }
+ else zzreplstr("zzmk_ast(zzastnew(),");
+ zzmore();
+ chkGTFlag();
+ }
+
+
+static void act125()
+{
+ NLA = 57;
+
+ pushint('}');
+ if ( GenCC ) {
+ if (tmakeInParser) {
+ zzreplstr("tmake(");
+ }
+ else {
+ zzreplstr("ASTBase::tmake(");
+ }
+ }
+ else {
+ zzreplstr("zztmake(");
+ }
+ zzmore();
+ chkGTFlag();
+ }
+
+
+static void act126()
+{
+ NLA = 58;
+ zzmore();
+ }
+
+
+static void act127()
+{
+ NLA = 59;
+
+ if ( istackempty() )
+ zzmore();
+ else if ( topint()==')' ) {
+ popint();
+ }
+ else if ( topint()=='}' ) {
+ popint();
+ /* terminate #(..) */
+ zzreplstr(", NULL)");
+ }
+ zzmore();
+ }
+
+
+static void act128()
+{
+ NLA = 60;
+
+ pushint('|'); /* look for '|' to terminate simple [...] */
+ zzmore();
+ }
+
+
+static void act129()
+{
+ NLA = 61;
+
+ pushint(')');
+ zzmore();
+ }
+
+
+static void act130()
+{
+ NLA = 62;
+ zzreplstr("]"); zzmore();
+ }
+
+
+static void act131()
+{
+ NLA = 63;
+ zzreplstr(")"); zzmore();
+ }
+
+
+static void act132()
+{
+ NLA = 64;
+ if (! tokenActionActive) zzreplstr(">"); /* MR1 */
+ zzmore(); /* MR1 */
+ }
+
+
+static void act133()
+{
+ NLA = 65;
+ zzmode(ACTION_CHARS); zzmore();
+ }
+
+
+static void act134()
+{
+ NLA = 66;
+ zzmode(ACTION_STRINGS); zzmore();
+ }
+
+
+static void act135()
+{
+ NLA = 67;
+ zzreplstr("$"); zzmore();
+ }
+
+
+static void act136()
+{
+ NLA = 68;
+ zzreplstr("#"); zzmore();
+ }
+
+
+static void act137()
+{
+ NLA = 69;
+ zzline++; zzmore();
+ }
+
+
+static void act138()
+{
+ NLA = 70;
+ zzmore();
+ }
+
+
+static void act139()
+{
+ NLA = 71;
+ zzmore();
+ }
+
+
+static void act140()
+{
+ NLA = 72;
+ zzmode(ACTION_COMMENTS); zzmore();
+ }
+
+
+static void act141()
+{
+ NLA = 73;
+ warn("Missing /*; found dangling */ in action"); zzmore();
+ }
+
+
+static void act142()
+{
+ NLA = 74;
+ zzmode(ACTION_CPP_COMMENTS); zzmore();
+ }
+
+
+static void act143()
+{
+ NLA = 75;
+ zzmore();
+ }
+
+static unsigned char shift10[257] = {
+ 0, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 16, 19, 33, 33, 20, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 16, 33, 28, 27, 21, 33, 33,
+ 30, 15, 18, 32, 33, 33, 33, 25, 31, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 33,
+ 33, 33, 33, 1, 2, 33, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 11, 26, 26, 26,
+ 26, 26, 22, 29, 3, 33, 26, 33, 26, 26,
+ 4, 26, 10, 26, 26, 26, 13, 26, 26, 14,
+ 9, 6, 5, 26, 26, 26, 7, 12, 8, 26,
+ 26, 26, 26, 26, 17, 33, 34, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33
+};
+
+
+static void act144()
+{
+ NLA = Eof;
+ ;
+ }
+
+
+static void act145()
+{
+ NLA = 137;
+ zzskip();
+ }
+
+
+static void act146()
+{
+ NLA = 138;
+ zzline++; zzskip();
+ }
+
+
+static void act147()
+{
+ NLA = 139;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzmore();
+ }
+
+
+static void act148()
+{
+ NLA = 140;
+ zzmode(TOK_DEF_COMMENTS); zzskip();
+ }
+
+
+static void act149()
+{
+ NLA = 141;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ }
+
+
+static void act150()
+{
+ NLA = 142;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ }
+
+
+static void act151()
+{
+ NLA = 143;
+ ;
+ }
+
+
+static void act152()
+{
+ NLA = 144;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ }
+
+
+static void act153()
+{
+ NLA = 145;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ }
+
+
+static void act154()
+{
+ NLA = 146;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ }
+
+
+static void act155()
+{
+ NLA = 147;
+ zzmode(TOK_DEF_CPP_COMMENTS); zzskip();
+ }
+
+
+static void act156()
+{
+ NLA = 149;
+ }
+
+
+static void act157()
+{
+ NLA = 151;
+ }
+
+
+static void act158()
+{
+ NLA = 152;
+ }
+
+
+static void act159()
+{
+ NLA = 153;
+ }
+
+
+static void act160()
+{
+ NLA = 154;
+ }
+
+
+static void act161()
+{
+ NLA = 155;
+ }
+
+
+static void act162()
+{
+ NLA = 156;
+ }
+
+
+static void act163()
+{
+ NLA = INT;
+ }
+
+
+static void act164()
+{
+ NLA = ID;
+ }
+
+static unsigned char shift11[257] = {
+ 0, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 1, 2, 27, 27, 3, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 1, 27, 27, 6, 27, 27, 27,
+ 27, 27, 27, 5, 27, 22, 27, 27, 4, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 27,
+ 24, 27, 21, 27, 27, 27, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 27, 27, 27, 27, 26, 27, 26, 26,
+ 26, 9, 10, 8, 26, 26, 7, 26, 26, 12,
+ 15, 11, 17, 16, 26, 18, 13, 19, 14, 26,
+ 26, 26, 26, 26, 20, 27, 23, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27
+};
+
+#define DfaStates 436
+typedef unsigned short DfaState;
+
+static DfaState st0[60] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 11, 11, 12, 13, 13, 13, 14, 15, 16,
+ 17, 11, 11, 18, 11, 11, 19, 11, 11, 19,
+ 11, 11, 11, 11, 20, 11, 11, 21, 22, 23,
+ 24, 25, 26, 11, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 11, 11, 19, 436, 436, 436
+};
+
+static DfaState st1[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st2[60] = {
+ 436, 2, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st3[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st4[60] = {
+ 436, 436, 37, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st5[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st6[60] = {
+ 436, 436, 436, 436, 436, 38, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st7[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st8[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 39, 40, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st9[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 41, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st10[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 42, 43, 43, 44, 43, 43, 43, 436, 436, 436,
+ 436, 45, 43, 43, 43, 43, 46, 43, 47, 43,
+ 43, 43, 43, 48, 43, 49, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st11[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st12[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 51, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st13[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 13, 13, 13, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st14[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 52, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st15[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 53, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st16[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st17[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 54,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st18[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 55, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st19[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 56, 56, 56, 56, 56, 56, 56, 436, 436, 436,
+ 436, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 436, 56, 436,
+ 436, 436, 436, 56, 436, 436, 436, 436, 436, 436,
+ 436, 56, 436, 436, 56, 56, 56, 56, 436, 436
+};
+
+static DfaState st20[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 57, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st21[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st22[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 58, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 59, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st23[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st24[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st25[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st26[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st27[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 60, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st28[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 61, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st29[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st30[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st31[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 62, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st32[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st33[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st34[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 56, 56, 56, 56, 56, 56, 56, 436, 436, 436,
+ 436, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 436, 56, 436,
+ 436, 436, 436, 56, 436, 436, 436, 436, 436, 436,
+ 436, 63, 436, 436, 56, 56, 56, 56, 436, 436
+};
+
+static DfaState st35[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st36[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st37[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st38[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st39[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st40[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st41[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st42[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 64, 43, 65, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st43[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st44[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 66, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st45[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 67, 68, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st46[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 69, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st47[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 70, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st48[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 71, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st49[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 72, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st50[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st51[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 73, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st52[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st53[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st54[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 74, 43, 43, 44, 43, 43, 43, 436, 436, 436,
+ 436, 45, 43, 43, 43, 43, 46, 43, 47, 43,
+ 43, 43, 43, 48, 43, 49, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st55[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 75, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st56[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 56, 56, 56, 56, 56, 56, 56, 436, 436, 436,
+ 436, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 436, 56, 436,
+ 436, 436, 436, 56, 436, 436, 436, 436, 436, 436,
+ 436, 56, 436, 436, 56, 56, 56, 56, 436, 436
+};
+
+static DfaState st57[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 76, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st58[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 77, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st59[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 78, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st60[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st61[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st62[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st63[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 56, 56, 56, 56, 56, 56, 56, 436, 436, 436,
+ 436, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 436, 56, 436,
+ 436, 436, 436, 56, 436, 436, 79, 436, 436, 436,
+ 436, 56, 436, 436, 56, 56, 56, 56, 436, 436
+};
+
+static DfaState st64[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 80, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st65[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 81, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st66[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 82, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st67[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 83, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 84, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st68[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 85, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st69[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 86, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st70[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 87, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st71[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 88, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st72[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 89, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st73[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 90, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st74[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 65, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st75[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 91, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st76[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 92, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st77[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 93, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st78[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 94, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st79[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 95, 96, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st80[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 97, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st81[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 98, 43, 99, 43, 100, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 101, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st82[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 102, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st83[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 103, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st84[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 104, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st85[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 105, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st86[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 106, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st87[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 107, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 108, 43, 43, 436, 109, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st88[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 110, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st89[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 111, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st90[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 112, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st91[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 113, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st92[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 114, 50, 50, 50, 436, 436
+};
+
+static DfaState st93[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 115, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st94[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 116, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st95[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 117, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st96[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 118, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st97[60] = {
+ 436, 119, 120, 121, 122, 122, 122, 122, 122, 122,
+ 123, 123, 123, 123, 124, 124, 124, 122, 122, 122,
+ 122, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+ 123, 123, 123, 123, 123, 123, 123, 122, 123, 122,
+ 122, 122, 122, 123, 122, 122, 122, 122, 122, 122,
+ 122, 123, 122, 122, 123, 123, 123, 123, 122, 436
+};
+
+static DfaState st98[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 125, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st99[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 126, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st100[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 127, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st101[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 128, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st102[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 129, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st103[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st104[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 130, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st105[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 131, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st106[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 132, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st107[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 133, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st108[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 134, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st109[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 135, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st110[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 136, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st111[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 137, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st112[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 138, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st113[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 139, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st114[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 140, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st115[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st116[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st117[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st118[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st119[60] = {
+ 436, 119, 120, 121, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 141, 141, 141, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st120[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st121[60] = {
+ 436, 436, 142, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st122[60] = {
+ 436, 122, 120, 121, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st123[60] = {
+ 436, 122, 120, 121, 122, 122, 122, 122, 122, 122,
+ 123, 123, 123, 123, 123, 123, 123, 122, 122, 122,
+ 122, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+ 123, 123, 123, 123, 123, 123, 123, 122, 123, 122,
+ 122, 122, 122, 123, 122, 122, 122, 122, 122, 122,
+ 122, 123, 122, 122, 123, 123, 123, 123, 122, 436
+};
+
+static DfaState st124[60] = {
+ 436, 143, 144, 145, 122, 122, 146, 122, 122, 122,
+ 123, 123, 123, 123, 124, 124, 124, 122, 122, 122,
+ 122, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+ 123, 123, 123, 123, 123, 123, 123, 122, 123, 122,
+ 122, 122, 122, 123, 122, 122, 122, 122, 122, 122,
+ 122, 123, 122, 122, 123, 123, 123, 123, 122, 436
+};
+
+static DfaState st125[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 147, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st126[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 148, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st127[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 149, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st128[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 150, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st129[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 151, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st130[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 152, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st131[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 153, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st132[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 154,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st133[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st134[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 155, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st135[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 156, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st136[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 157, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st137[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st138[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 158, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st139[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st140[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 159, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st141[60] = {
+ 436, 143, 144, 145, 122, 122, 146, 122, 122, 122,
+ 122, 122, 122, 122, 141, 141, 141, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st142[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st143[60] = {
+ 436, 143, 120, 121, 122, 122, 146, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st144[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st145[60] = {
+ 436, 436, 160, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st146[60] = {
+ 436, 161, 162, 163, 161, 161, 122, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 436
+};
+
+static DfaState st147[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 164, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st148[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 165, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st149[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 166, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st150[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 167, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st151[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 168, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st152[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st153[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st154[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 169, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st155[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 170, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st156[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 171, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st157[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st158[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 172, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st159[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st160[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st161[60] = {
+ 436, 161, 162, 163, 161, 161, 173, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 436
+};
+
+static DfaState st162[60] = {
+ 436, 174, 174, 174, 174, 174, 175, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 436
+};
+
+static DfaState st163[60] = {
+ 436, 174, 176, 174, 174, 174, 175, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 436
+};
+
+static DfaState st164[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 177, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st165[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 178, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st166[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 179, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st167[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 180, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st168[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 181, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st169[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 182, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st170[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st171[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 183, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st172[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 184, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st173[60] = {
+ 436, 185, 144, 145, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 186, 186, 186, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st174[60] = {
+ 436, 174, 174, 174, 174, 174, 175, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 436
+};
+
+static DfaState st175[60] = {
+ 436, 187, 188, 189, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 190, 190, 190, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st176[60] = {
+ 436, 174, 174, 174, 174, 174, 175, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 436
+};
+
+static DfaState st177[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 191, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st178[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 192, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st179[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 193, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st180[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st181[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st182[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 194,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st183[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st184[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 50, 50, 50, 50, 50, 50, 50, 436, 436, 436,
+ 436, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 436, 50, 436,
+ 436, 436, 436, 50, 436, 436, 436, 436, 436, 436,
+ 436, 50, 436, 436, 50, 50, 50, 50, 436, 436
+};
+
+static DfaState st185[60] = {
+ 436, 185, 144, 145, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 186, 186, 186, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st186[60] = {
+ 436, 185, 144, 145, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 186, 186, 186, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+ 122, 122, 122, 122, 122, 122, 122, 122, 122, 436
+};
+
+static DfaState st187[60] = {
+ 436, 187, 188, 189, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 190, 190, 190, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st188[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st189[60] = {
+ 436, 436, 195, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st190[60] = {
+ 436, 187, 188, 189, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 190, 190, 190, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st191[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st192[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st193[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st194[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 196, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st195[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st196[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 197, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st197[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 198, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st198[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 199, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st199[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 200, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st200[60] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 43, 43, 43, 43, 43, 43, 43, 436, 436, 436,
+ 436, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 436, 43, 436,
+ 436, 436, 436, 43, 436, 436, 436, 436, 436, 436,
+ 436, 43, 436, 436, 43, 43, 43, 43, 436, 436
+};
+
+static DfaState st201[7] = {
+ 202, 203, 204, 205, 206, 207, 436
+};
+
+static DfaState st202[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st203[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st204[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st205[7] = {
+ 436, 436, 208, 436, 436, 436, 436
+};
+
+static DfaState st206[7] = {
+ 436, 209, 210, 211, 209, 209, 436
+};
+
+static DfaState st207[7] = {
+ 436, 436, 436, 436, 436, 207, 436
+};
+
+static DfaState st208[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st209[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st210[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st211[7] = {
+ 436, 436, 212, 436, 436, 436, 436
+};
+
+static DfaState st212[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st213[7] = {
+ 214, 215, 216, 217, 218, 219, 436
+};
+
+static DfaState st214[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st215[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st216[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st217[7] = {
+ 436, 436, 220, 436, 436, 436, 436
+};
+
+static DfaState st218[7] = {
+ 436, 221, 222, 223, 221, 221, 436
+};
+
+static DfaState st219[7] = {
+ 436, 436, 436, 436, 436, 219, 436
+};
+
+static DfaState st220[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st221[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st222[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st223[7] = {
+ 436, 436, 224, 436, 436, 436, 436
+};
+
+static DfaState st224[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st225[7] = {
+ 226, 227, 228, 229, 230, 231, 436
+};
+
+static DfaState st226[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st227[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st228[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st229[7] = {
+ 436, 436, 232, 436, 436, 436, 436
+};
+
+static DfaState st230[7] = {
+ 436, 233, 233, 233, 233, 233, 436
+};
+
+static DfaState st231[7] = {
+ 436, 436, 436, 436, 436, 231, 436
+};
+
+static DfaState st232[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st233[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st234[7] = {
+ 235, 236, 237, 238, 239, 237, 436
+};
+
+static DfaState st235[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st236[7] = {
+ 436, 436, 240, 436, 436, 436, 436
+};
+
+static DfaState st237[7] = {
+ 436, 436, 237, 436, 436, 237, 436
+};
+
+static DfaState st238[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st239[7] = {
+ 436, 436, 436, 241, 436, 436, 436
+};
+
+static DfaState st240[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st241[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st242[7] = {
+ 243, 244, 245, 246, 247, 245, 436
+};
+
+static DfaState st243[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st244[7] = {
+ 436, 436, 248, 436, 436, 436, 436
+};
+
+static DfaState st245[7] = {
+ 436, 436, 245, 436, 436, 245, 436
+};
+
+static DfaState st246[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st247[7] = {
+ 436, 436, 436, 249, 436, 436, 436
+};
+
+static DfaState st248[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st249[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st250[5] = {
+ 251, 252, 253, 254, 436
+};
+
+static DfaState st251[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st252[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st253[5] = {
+ 436, 255, 436, 436, 436
+};
+
+static DfaState st254[5] = {
+ 436, 436, 436, 254, 436
+};
+
+static DfaState st255[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st256[5] = {
+ 257, 258, 259, 260, 436
+};
+
+static DfaState st257[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st258[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st259[5] = {
+ 436, 261, 436, 436, 436
+};
+
+static DfaState st260[5] = {
+ 436, 436, 436, 260, 436
+};
+
+static DfaState st261[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st262[5] = {
+ 263, 264, 265, 266, 436
+};
+
+static DfaState st263[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st264[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st265[5] = {
+ 436, 267, 436, 436, 436
+};
+
+static DfaState st266[5] = {
+ 436, 436, 436, 266, 436
+};
+
+static DfaState st267[5] = {
+ 436, 436, 436, 436, 436
+};
+
+static DfaState st268[7] = {
+ 269, 270, 271, 272, 273, 271, 436
+};
+
+static DfaState st269[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st270[7] = {
+ 436, 436, 274, 436, 436, 436, 436
+};
+
+static DfaState st271[7] = {
+ 436, 436, 271, 436, 436, 271, 436
+};
+
+static DfaState st272[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st273[7] = {
+ 436, 436, 436, 275, 436, 436, 436
+};
+
+static DfaState st274[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st275[7] = {
+ 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st276[36] = {
+ 277, 278, 279, 280, 281, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 282, 279, 279, 283, 284,
+ 285, 286, 287, 279, 279, 279, 279, 288, 289, 290,
+ 291, 292, 293, 279, 279, 436
+};
+
+static DfaState st277[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st278[36] = {
+ 436, 294, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st279[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st280[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st281[36] = {
+ 436, 436, 279, 436, 279, 295, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st282[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st283[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st284[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st285[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 296,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st286[36] = {
+ 436, 436, 436, 436, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 436, 436, 436, 436, 436,
+ 436, 298, 299, 300, 300, 436, 297, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st287[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st288[36] = {
+ 436, 436, 436, 436, 301, 301, 301, 301, 301, 301,
+ 301, 301, 301, 301, 302, 303, 436, 436, 436, 436,
+ 436, 436, 304, 305, 306, 436, 301, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st289[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st290[36] = {
+ 436, 307, 308, 309, 308, 308, 308, 308, 308, 308,
+ 308, 308, 308, 308, 308, 308, 308, 308, 310, 311,
+ 312, 313, 308, 308, 308, 308, 308, 314, 308, 308,
+ 308, 308, 308, 308, 308, 436
+};
+
+static DfaState st291[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st292[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 315, 316, 436, 436, 436
+};
+
+static DfaState st293[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 317, 279, 279, 279, 436
+};
+
+static DfaState st294[36] = {
+ 436, 436, 318, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st295[36] = {
+ 436, 436, 279, 436, 279, 279, 319, 279, 279, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st296[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st297[36] = {
+ 436, 436, 436, 436, 320, 320, 320, 320, 320, 320,
+ 320, 320, 320, 320, 320, 436, 436, 436, 436, 436,
+ 436, 436, 436, 320, 320, 436, 320, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st298[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st299[36] = {
+ 436, 436, 436, 321, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st300[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 300, 300, 322, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st301[36] = {
+ 436, 436, 436, 436, 323, 323, 323, 323, 323, 323,
+ 323, 323, 323, 323, 323, 436, 436, 436, 436, 436,
+ 436, 436, 436, 323, 323, 436, 323, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st302[36] = {
+ 436, 436, 436, 436, 323, 323, 323, 323, 323, 323,
+ 323, 323, 323, 324, 323, 436, 436, 436, 436, 436,
+ 436, 436, 436, 323, 323, 436, 323, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st303[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 325, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st304[36] = {
+ 436, 436, 436, 326, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st305[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 306, 306, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st306[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 306, 306, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st307[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st308[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st309[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st310[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st311[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st312[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 327,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st313[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st314[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st315[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st316[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st317[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st318[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st319[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 328, 279, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st320[36] = {
+ 436, 436, 436, 436, 320, 320, 320, 320, 320, 320,
+ 320, 320, 320, 320, 320, 436, 436, 436, 436, 436,
+ 436, 436, 436, 320, 320, 436, 320, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st321[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st322[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 329, 329, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st323[36] = {
+ 436, 436, 436, 436, 323, 323, 323, 323, 323, 323,
+ 323, 323, 323, 323, 323, 436, 436, 436, 436, 436,
+ 436, 436, 436, 323, 323, 436, 323, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st324[36] = {
+ 436, 436, 436, 436, 323, 323, 330, 323, 323, 323,
+ 323, 323, 323, 323, 323, 436, 436, 436, 436, 436,
+ 436, 436, 436, 323, 323, 436, 323, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st325[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st326[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st327[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st328[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 331, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st329[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 329, 329, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st330[36] = {
+ 436, 436, 436, 436, 323, 323, 323, 323, 323, 323,
+ 332, 323, 323, 323, 323, 436, 436, 436, 436, 436,
+ 436, 436, 436, 323, 323, 436, 323, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st331[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 333,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st332[36] = {
+ 436, 334, 334, 334, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 334, 336, 334, 334, 337,
+ 338, 334, 334, 339, 339, 334, 335, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st333[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 340, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st334[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 337,
+ 338, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st335[36] = {
+ 436, 334, 334, 334, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 334, 334, 334, 334, 337,
+ 338, 334, 334, 335, 335, 334, 335, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st336[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 336, 334, 334, 337,
+ 338, 334, 334, 341, 341, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st337[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st338[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 342,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st339[36] = {
+ 436, 334, 334, 334, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 334, 343, 334, 334, 344,
+ 345, 334, 334, 339, 339, 334, 335, 334, 346, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st340[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 347, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st341[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 343, 334, 334, 344,
+ 345, 334, 334, 341, 341, 334, 334, 334, 346, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st342[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st343[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 343, 334, 334, 337,
+ 338, 334, 334, 334, 334, 334, 334, 334, 346, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st344[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st345[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 348,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st346[36] = {
+ 436, 349, 349, 349, 349, 349, 349, 349, 349, 349,
+ 349, 349, 349, 349, 349, 349, 349, 349, 349, 350,
+ 351, 349, 349, 349, 349, 349, 349, 349, 334, 349,
+ 349, 349, 349, 349, 349, 436
+};
+
+static DfaState st347[36] = {
+ 436, 436, 279, 436, 279, 279, 352, 279, 279, 279,
+ 279, 279, 279, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st348[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st349[36] = {
+ 436, 349, 349, 349, 349, 349, 349, 349, 349, 349,
+ 349, 349, 349, 349, 349, 349, 349, 349, 349, 350,
+ 351, 349, 349, 349, 349, 349, 349, 349, 353, 349,
+ 349, 349, 349, 349, 349, 436
+};
+
+static DfaState st350[36] = {
+ 436, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 355, 354,
+ 354, 354, 354, 354, 354, 436
+};
+
+static DfaState st351[36] = {
+ 436, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 354, 356,
+ 354, 354, 354, 354, 354, 354, 354, 354, 355, 354,
+ 354, 354, 354, 354, 354, 436
+};
+
+static DfaState st352[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 279, 357, 279, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st353[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 358, 334, 334, 344,
+ 345, 334, 334, 359, 359, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st354[36] = {
+ 436, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 355, 354,
+ 354, 354, 354, 354, 354, 436
+};
+
+static DfaState st355[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 360, 436, 436, 361,
+ 362, 436, 436, 363, 363, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st356[36] = {
+ 436, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 354, 354,
+ 354, 354, 354, 354, 354, 354, 354, 354, 355, 354,
+ 354, 354, 354, 354, 354, 436
+};
+
+static DfaState st357[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 364, 279, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st358[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 358, 334, 334, 344,
+ 345, 334, 334, 359, 359, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st359[36] = {
+ 436, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 358, 334, 334, 344,
+ 345, 334, 334, 359, 359, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 436
+};
+
+static DfaState st360[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 360, 436, 436, 361,
+ 362, 436, 436, 363, 363, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st361[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st362[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 365,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st363[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 360, 436, 436, 361,
+ 362, 436, 436, 363, 363, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st364[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 366, 436, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st365[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st366[36] = {
+ 436, 436, 279, 436, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 367, 279, 279, 436, 436,
+ 436, 436, 436, 279, 279, 279, 279, 436, 436, 436,
+ 436, 436, 279, 279, 279, 436
+};
+
+static DfaState st367[36] = {
+ 436, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 368, 369, 370, 436, 368,
+ 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 436
+};
+
+static DfaState st368[36] = {
+ 436, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 368, 368, 368, 371, 368,
+ 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 436
+};
+
+static DfaState st369[36] = {
+ 436, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 368, 369, 370, 371, 368,
+ 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 436
+};
+
+static DfaState st370[36] = {
+ 436, 372, 372, 372, 372, 372, 372, 372, 372, 372,
+ 372, 372, 372, 372, 372, 372, 372, 372, 373, 372,
+ 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
+ 372, 372, 372, 372, 368, 436
+};
+
+static DfaState st371[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st372[36] = {
+ 436, 372, 372, 372, 372, 372, 372, 372, 372, 372,
+ 372, 372, 372, 372, 372, 372, 372, 372, 373, 372,
+ 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
+ 372, 372, 372, 372, 374, 436
+};
+
+static DfaState st373[36] = {
+ 436, 375, 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 376, 436
+};
+
+static DfaState st374[36] = {
+ 436, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 368, 377, 368, 378, 368,
+ 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 436
+};
+
+static DfaState st375[36] = {
+ 436, 375, 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 376, 436
+};
+
+static DfaState st376[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 379, 436, 380, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st377[36] = {
+ 436, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 368, 377, 368, 378, 368,
+ 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+ 368, 368, 368, 368, 368, 436
+};
+
+static DfaState st378[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st379[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 379, 436, 380, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st380[36] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st381[28] = {
+ 382, 383, 384, 385, 386, 436, 387, 388, 388, 388,
+ 389, 388, 388, 388, 388, 388, 388, 388, 388, 388,
+ 390, 391, 392, 393, 394, 395, 388, 436
+};
+
+static DfaState st382[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st383[28] = {
+ 436, 383, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st384[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st385[28] = {
+ 436, 436, 396, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st386[28] = {
+ 436, 436, 436, 436, 397, 398, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st387[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 399, 436, 400,
+ 401, 436, 436, 436, 402, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st388[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
+ 436, 436, 436, 436, 436, 403, 403, 436
+};
+
+static DfaState st389[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 403, 403, 403,
+ 403, 404, 403, 403, 403, 403, 403, 403, 403, 403,
+ 436, 436, 436, 436, 436, 403, 403, 436
+};
+
+static DfaState st390[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st391[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st392[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st393[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st394[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st395[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 395, 436, 436
+};
+
+static DfaState st396[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st397[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st398[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st399[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 405, 436,
+ 436, 436, 436, 436, 436, 406, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st400[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 407, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st401[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 408, 409, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st402[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 410, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st403[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
+ 436, 436, 436, 436, 436, 403, 403, 436
+};
+
+static DfaState st404[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 403, 403, 403,
+ 403, 403, 403, 403, 411, 403, 403, 403, 403, 403,
+ 436, 436, 436, 436, 436, 403, 403, 436
+};
+
+static DfaState st405[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 412,
+ 436, 413, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st406[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 414, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st407[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 415, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st408[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 416,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st409[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 417, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st410[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 418,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st411[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 403, 403, 403,
+ 403, 403, 403, 403, 403, 419, 403, 403, 403, 403,
+ 436, 436, 436, 436, 436, 403, 403, 436
+};
+
+static DfaState st412[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 420, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st413[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 421,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st414[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 422, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st415[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 423, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st416[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 424, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st417[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 425, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st418[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 426, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st419[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
+ 436, 436, 436, 436, 436, 403, 403, 436
+};
+
+static DfaState st420[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 427, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st421[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 428, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st422[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 429, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st423[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 430, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st424[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 431, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st425[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st426[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 432, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st427[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st428[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 433, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st429[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 434,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st430[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 435, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st431[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st432[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st433[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st434[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+static DfaState st435[28] = {
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
+ 436, 436, 436, 436, 436, 436, 436, 436
+};
+
+
+DfaState *dfa[436] = {
+ st0,
+ st1,
+ st2,
+ st3,
+ st4,
+ st5,
+ st6,
+ st7,
+ st8,
+ st9,
+ st10,
+ st11,
+ st12,
+ st13,
+ st14,
+ st15,
+ st16,
+ st17,
+ st18,
+ st19,
+ st20,
+ st21,
+ st22,
+ st23,
+ st24,
+ st25,
+ st26,
+ st27,
+ st28,
+ st29,
+ st30,
+ st31,
+ st32,
+ st33,
+ st34,
+ st35,
+ st36,
+ st37,
+ st38,
+ st39,
+ st40,
+ st41,
+ st42,
+ st43,
+ st44,
+ st45,
+ st46,
+ st47,
+ st48,
+ st49,
+ st50,
+ st51,
+ st52,
+ st53,
+ st54,
+ st55,
+ st56,
+ st57,
+ st58,
+ st59,
+ st60,
+ st61,
+ st62,
+ st63,
+ st64,
+ st65,
+ st66,
+ st67,
+ st68,
+ st69,
+ st70,
+ st71,
+ st72,
+ st73,
+ st74,
+ st75,
+ st76,
+ st77,
+ st78,
+ st79,
+ st80,
+ st81,
+ st82,
+ st83,
+ st84,
+ st85,
+ st86,
+ st87,
+ st88,
+ st89,
+ st90,
+ st91,
+ st92,
+ st93,
+ st94,
+ st95,
+ st96,
+ st97,
+ st98,
+ st99,
+ st100,
+ st101,
+ st102,
+ st103,
+ st104,
+ st105,
+ st106,
+ st107,
+ st108,
+ st109,
+ st110,
+ st111,
+ st112,
+ st113,
+ st114,
+ st115,
+ st116,
+ st117,
+ st118,
+ st119,
+ st120,
+ st121,
+ st122,
+ st123,
+ st124,
+ st125,
+ st126,
+ st127,
+ st128,
+ st129,
+ st130,
+ st131,
+ st132,
+ st133,
+ st134,
+ st135,
+ st136,
+ st137,
+ st138,
+ st139,
+ st140,
+ st141,
+ st142,
+ st143,
+ st144,
+ st145,
+ st146,
+ st147,
+ st148,
+ st149,
+ st150,
+ st151,
+ st152,
+ st153,
+ st154,
+ st155,
+ st156,
+ st157,
+ st158,
+ st159,
+ st160,
+ st161,
+ st162,
+ st163,
+ st164,
+ st165,
+ st166,
+ st167,
+ st168,
+ st169,
+ st170,
+ st171,
+ st172,
+ st173,
+ st174,
+ st175,
+ st176,
+ st177,
+ st178,
+ st179,
+ st180,
+ st181,
+ st182,
+ st183,
+ st184,
+ st185,
+ st186,
+ st187,
+ st188,
+ st189,
+ st190,
+ st191,
+ st192,
+ st193,
+ st194,
+ st195,
+ st196,
+ st197,
+ st198,
+ st199,
+ st200,
+ st201,
+ st202,
+ st203,
+ st204,
+ st205,
+ st206,
+ st207,
+ st208,
+ st209,
+ st210,
+ st211,
+ st212,
+ st213,
+ st214,
+ st215,
+ st216,
+ st217,
+ st218,
+ st219,
+ st220,
+ st221,
+ st222,
+ st223,
+ st224,
+ st225,
+ st226,
+ st227,
+ st228,
+ st229,
+ st230,
+ st231,
+ st232,
+ st233,
+ st234,
+ st235,
+ st236,
+ st237,
+ st238,
+ st239,
+ st240,
+ st241,
+ st242,
+ st243,
+ st244,
+ st245,
+ st246,
+ st247,
+ st248,
+ st249,
+ st250,
+ st251,
+ st252,
+ st253,
+ st254,
+ st255,
+ st256,
+ st257,
+ st258,
+ st259,
+ st260,
+ st261,
+ st262,
+ st263,
+ st264,
+ st265,
+ st266,
+ st267,
+ st268,
+ st269,
+ st270,
+ st271,
+ st272,
+ st273,
+ st274,
+ st275,
+ st276,
+ st277,
+ st278,
+ st279,
+ st280,
+ st281,
+ st282,
+ st283,
+ st284,
+ st285,
+ st286,
+ st287,
+ st288,
+ st289,
+ st290,
+ st291,
+ st292,
+ st293,
+ st294,
+ st295,
+ st296,
+ st297,
+ st298,
+ st299,
+ st300,
+ st301,
+ st302,
+ st303,
+ st304,
+ st305,
+ st306,
+ st307,
+ st308,
+ st309,
+ st310,
+ st311,
+ st312,
+ st313,
+ st314,
+ st315,
+ st316,
+ st317,
+ st318,
+ st319,
+ st320,
+ st321,
+ st322,
+ st323,
+ st324,
+ st325,
+ st326,
+ st327,
+ st328,
+ st329,
+ st330,
+ st331,
+ st332,
+ st333,
+ st334,
+ st335,
+ st336,
+ st337,
+ st338,
+ st339,
+ st340,
+ st341,
+ st342,
+ st343,
+ st344,
+ st345,
+ st346,
+ st347,
+ st348,
+ st349,
+ st350,
+ st351,
+ st352,
+ st353,
+ st354,
+ st355,
+ st356,
+ st357,
+ st358,
+ st359,
+ st360,
+ st361,
+ st362,
+ st363,
+ st364,
+ st365,
+ st366,
+ st367,
+ st368,
+ st369,
+ st370,
+ st371,
+ st372,
+ st373,
+ st374,
+ st375,
+ st376,
+ st377,
+ st378,
+ st379,
+ st380,
+ st381,
+ st382,
+ st383,
+ st384,
+ st385,
+ st386,
+ st387,
+ st388,
+ st389,
+ st390,
+ st391,
+ st392,
+ st393,
+ st394,
+ st395,
+ st396,
+ st397,
+ st398,
+ st399,
+ st400,
+ st401,
+ st402,
+ st403,
+ st404,
+ st405,
+ st406,
+ st407,
+ st408,
+ st409,
+ st410,
+ st411,
+ st412,
+ st413,
+ st414,
+ st415,
+ st416,
+ st417,
+ st418,
+ st419,
+ st420,
+ st421,
+ st422,
+ st423,
+ st424,
+ st425,
+ st426,
+ st427,
+ st428,
+ st429,
+ st430,
+ st431,
+ st432,
+ st433,
+ st434,
+ st435
+};
+
+
+DfaState accepts[437] = {
+ 0, 1, 2, 3, 3, 4, 25, 6, 0, 50,
+ 59, 57, 57, 43, 26, 13, 14, 0, 57, 58,
+ 57, 21, 57, 23, 24, 27, 28, 44, 0, 35,
+ 36, 42, 45, 46, 58, 51, 52, 3, 5, 9,
+ 7, 8, 59, 59, 59, 59, 59, 59, 59, 59,
+ 57, 57, 12, 40, 59, 57, 58, 57, 57, 57,
+ 33, 34, 53, 58, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 57, 59, 57, 57, 57, 57, 0,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 57, 57, 57, 57, 57, 0, 0, 59, 59, 59,
+ 59, 59, 59, 32, 59, 59, 59, 59, 59, 59,
+ 59, 59, 57, 57, 57, 22, 56, 48, 49, 0,
+ 11, 11, 0, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 41, 59, 59, 59, 18, 57, 47,
+ 57, 0, 11, 0, 10, 10, 0, 59, 59, 59,
+ 59, 59, 15, 19, 59, 59, 59, 17, 57, 55,
+ 10, 0, 11, 11, 59, 59, 59, 59, 59, 59,
+ 20, 59, 57, 0, 0, 0, 11, 59, 59, 59,
+ 37, 38, 59, 39, 54, 0, 0, 0, 10, 10,
+ 0, 31, 29, 30, 59, 10, 59, 59, 59, 59,
+ 16, 0, 60, 61, 62, 62, 0, 65, 62, 64,
+ 63, 63, 63, 0, 66, 67, 68, 68, 0, 71,
+ 68, 70, 69, 69, 69, 0, 72, 73, 74, 74,
+ 0, 76, 74, 75, 0, 77, 79, 81, 80, 80,
+ 78, 80, 0, 82, 84, 86, 85, 85, 83, 85,
+ 0, 87, 88, 88, 89, 88, 0, 90, 91, 91,
+ 92, 91, 0, 93, 94, 94, 95, 94, 0, 96,
+ 98, 100, 99, 99, 97, 99, 0, 101, 108, 143,
+ 104, 143, 129, 127, 107, 107, 109, 128, 126, 134,
+ 0, 133, 139, 143, 102, 143, 107, 116, 110, 112,
+ 113, 123, 123, 125, 124, 117, 120, 132, 138, 130,
+ 131, 137, 137, 135, 136, 142, 140, 141, 103, 143,
+ 116, 111, 114, 123, 123, 119, 118, 137, 143, 115,
+ 123, 143, 123, 143, 0, 123, 0, 122, 122, 123,
+ 143, 0, 122, 0, 121, 121, 0, 143, 121, 0,
+ 122, 122, 143, 0, 0, 0, 122, 143, 0, 0,
+ 0, 121, 121, 0, 143, 121, 143, 0, 0, 0,
+ 0, 106, 0, 106, 0, 0, 0, 0, 105, 0,
+ 105, 0, 144, 145, 146, 146, 0, 0, 164, 164,
+ 158, 159, 160, 161, 162, 163, 146, 147, 148, 0,
+ 0, 0, 0, 164, 164, 150, 0, 0, 0, 0,
+ 0, 164, 0, 0, 0, 0, 0, 0, 0, 157,
+ 0, 0, 0, 0, 0, 152, 0, 149, 0, 0,
+ 0, 153, 154, 151, 155, 156, 0
+};
+
+void (*actions[165])() = {
+ zzerraction,
+ act1,
+ act2,
+ act3,
+ act4,
+ act5,
+ act6,
+ act7,
+ act8,
+ act9,
+ act10,
+ act11,
+ act12,
+ act13,
+ act14,
+ act15,
+ act16,
+ act17,
+ act18,
+ act19,
+ act20,
+ act21,
+ act22,
+ act23,
+ act24,
+ act25,
+ act26,
+ act27,
+ act28,
+ act29,
+ act30,
+ act31,
+ act32,
+ act33,
+ act34,
+ act35,
+ act36,
+ act37,
+ act38,
+ act39,
+ act40,
+ act41,
+ act42,
+ act43,
+ act44,
+ act45,
+ act46,
+ act47,
+ act48,
+ act49,
+ act50,
+ act51,
+ act52,
+ act53,
+ act54,
+ act55,
+ act56,
+ act57,
+ act58,
+ act59,
+ act60,
+ act61,
+ act62,
+ act63,
+ act64,
+ act65,
+ act66,
+ act67,
+ act68,
+ act69,
+ act70,
+ act71,
+ act72,
+ act73,
+ act74,
+ act75,
+ act76,
+ act77,
+ act78,
+ act79,
+ act80,
+ act81,
+ act82,
+ act83,
+ act84,
+ act85,
+ act86,
+ act87,
+ act88,
+ act89,
+ act90,
+ act91,
+ act92,
+ act93,
+ act94,
+ act95,
+ act96,
+ act97,
+ act98,
+ act99,
+ act100,
+ act101,
+ act102,
+ act103,
+ act104,
+ act105,
+ act106,
+ act107,
+ act108,
+ act109,
+ act110,
+ act111,
+ act112,
+ act113,
+ act114,
+ act115,
+ act116,
+ act117,
+ act118,
+ act119,
+ act120,
+ act121,
+ act122,
+ act123,
+ act124,
+ act125,
+ act126,
+ act127,
+ act128,
+ act129,
+ act130,
+ act131,
+ act132,
+ act133,
+ act134,
+ act135,
+ act136,
+ act137,
+ act138,
+ act139,
+ act140,
+ act141,
+ act142,
+ act143,
+ act144,
+ act145,
+ act146,
+ act147,
+ act148,
+ act149,
+ act150,
+ act151,
+ act152,
+ act153,
+ act154,
+ act155,
+ act156,
+ act157,
+ act158,
+ act159,
+ act160,
+ act161,
+ act162,
+ act163,
+ act164
+};
+
+static DfaState dfa_base[] = {
+ 0,
+ 201,
+ 213,
+ 225,
+ 234,
+ 242,
+ 250,
+ 256,
+ 262,
+ 268,
+ 276,
+ 381
+};
+
+static unsigned char *b_class_no[] = {
+ shift0,
+ shift1,
+ shift2,
+ shift3,
+ shift4,
+ shift5,
+ shift6,
+ shift7,
+ shift8,
+ shift9,
+ shift10,
+ shift11
+};
+
+
+
+#define ZZSHIFT(c) (b_class_no[zzauto][1+c])
+#define MAX_MODE 12
+#include "dlgauto.h"
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/stdpccts.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/stdpccts.h
new file mode 100644
index 00000000..fc861f1d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/stdpccts.h
@@ -0,0 +1,31 @@
+#ifndef STDPCCTS_H
+#define STDPCCTS_H
+/*
+ * stdpccts.h -- P C C T S I n c l u d e
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#ifndef ANTLR_VERSION
+#define ANTLR_VERSION 13333
+#endif
+
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include "pcctscfg.h"
+#include "set.h"
+#include <ctype.h>
+#include "syn.h"
+#include "hash.h"
+#include "generic.h"
+#define zzcr_attr(attr,tok,t) /*vbox: */ memset((attr), 0, sizeof(*attr))
+#define zzSET_SIZE 20
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "mode.h"
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/syn.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/syn.h
new file mode 100644
index 00000000..87d725e0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/syn.h
@@ -0,0 +1,390 @@
+/*
+ * syn.h
+ *
+ * This file includes definitions and macros associated with syntax diagrams
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include "set.h"
+
+#define NumNodeTypes 4
+#define NumJuncTypes 9
+
+/* List the different node types */
+#define nJunction 1
+#define nRuleRef 2
+#define nToken 3
+#define nAction 4
+
+/* Different types of junctions */
+#define aSubBlk 1
+#define aOptBlk 2
+#define aLoopBlk 3
+#define EndBlk 4
+#define RuleBlk 5
+#define Generic 6 /* just a junction--no unusual characteristics */
+#define EndRule 7
+#define aPlusBlk 8
+#define aLoopBegin 9
+
+typedef int NodeType;
+
+#define TreeBlockAllocSize 500
+#define JunctionBlockAllocSize 200
+#define ActionBlockAllocSize 50
+#define RRefBlockAllocSize 100
+#define TokenBlockAllocSize 100
+
+#ifdef __cplusplus
+class ActionNode;
+class Junction;
+#endif
+
+/* note that 'right' is used by the tree node allocator as a ptr for linked list */
+typedef struct _tree {
+ struct _tree *down, *right;
+ int token;
+ union {
+ int rk; /* if token==EpToken, => how many more tokens req'd */
+ struct _tree *tref; /* if token==TREE_REF */
+ set sref; /* if token==SET */
+ } v;
+#ifdef TREE_DEBUG
+ int in_use;
+ int seq;
+#endif
+ } Tree;
+
+
+/* a predicate is defined to be a predicate action and a token tree with
+ * context info (if used); later, this struct may include the
+ * "hoisting distance" when we hoist past tokens.
+ *
+ * A tree is used to indicate && vs ||
+ *
+ * p
+ * |
+ * q--r
+ *
+ * indicates p && (q||r).
+ *
+ * If expr is PRED_AND_LIST or PRED_OR_LIST, then it's an operation node
+ * and indicates the start of an && or || list.
+ */
+
+typedef struct _Predicate {
+ struct _Predicate *down, *right; /* these have to be first */
+ struct _Predicate *up, *left; /* doubly-link me */
+ char *expr;
+ Tree *tcontext; /* used if lookahead depth of > one is needed (tree) */
+ int k; /* lookahead depth for this tcontext */
+ set scontext[2];/* used if lookahead depth of one is needed (set) */
+ /* scontext[0] is not used; only needed so genExprSets()
+ routine works (it expects an array)
+ */
+ set completionTree; /* which lookahead depths are required to complete tcontext? */
+ set completionSet; /* MR10 separate completion set for sets and trees */
+ struct _PredEntry *predEntry; /* MR11 */
+
+#ifdef __cplusplus
+ ActionNode *source; /* where did this predicate come from? */
+#else
+ struct _anode *source; /* where did this predicate come from? */
+#endif
+
+ char cloned; /* MR10 don't want to free original guard pred */
+ char redundant; /* MR10 predicate tree simplification */
+ char ampersandStyle; /* MR10 (g)? && <<p>>? */
+ char inverted; /* MR11 ! predName */
+ char isConst; /* MR11 */
+ char constValue; /* MR11 */
+ char conflictReported; /* MR11 */
+
+ set plainSet; /* MR12b */
+
+ /*** remember to change new_predicate() and predicate_dup() when changing this ***/
+
+} Predicate;
+
+typedef struct _ExceptionHandler {
+ char *signalname;
+ char *action;
+ } ExceptionHandler;
+
+typedef struct _ExceptionGroup {
+ struct _ListNode *handlers; /* list of ExceptionHandler's */
+ char *label; /* label==""; implies not attached to any
+ * particular rule ref.
+ */
+ char *altID; /* which alt did it come from (blk#:alt#) */
+
+ struct _ExceptionGroup *pendingLink; /* for alternative EG MR7 */
+ struct _ExceptionGroup *outerEG; /* for alternative EG MR7 */
+ struct _LabelEntry *labelEntry; /* for alternative EG MR7 */
+ int forRule; /* MR7 */
+ int used; /* MR7 */
+ } ExceptionGroup ;
+
+
+#define TokenString(_i) ((TokenInd!=NULL)?TokenStr[TokenInd[_i]]:TokenStr[_i])
+#define ExprString(_i) ((TokenInd!=NULL)?ExprStr[TokenInd[_i]]:ExprStr[_i])
+
+
+ /* M e s s a g e P a s s i n g T o N o d e s */
+
+/*
+ * assumes a 'Junction *r' exists. This macro calls a function with
+ * the pointer to the node to operate on and a pointer to the rule
+ * in which it is enclosed.
+ */
+#define TRANS(p) {if ( (p)==NULL ) fatal("TRANS: NULL object"); \
+ if ( (p)->ntype == nJunction ) (*(fpJTrans[((Junction *)(p))->jtype]))( p );\
+ else (*(fpTrans[(p)->ntype]))( p );}
+
+#define PRINT(p) {if ( (p)==NULL ) fatal("PRINT: NULL object");\
+ (*(fpPrint[(p)->ntype]))( p );}
+
+#define REACH(p,k,rk,a) {if ( (p)==NULL ) fatal("REACH: NULL object");\
+ (a) = (*(fpReach[(p)->ntype]))( p, k, rk );}
+
+#define TRAV(p,k,rk,a) {if ( (p)==NULL ) {\
+ if ( ContextGuardTRAV ) (a)=NULL; \
+ else fatal("TRAV: NULL object");\
+ } \
+ else (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );}
+
+/**
+*** #define TRAV(p,k,rk,a) {if ( (p)==NULL ) fatal("TRAV: NULL object");\
+*** (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );}
+**/
+
+/* All syntax diagram nodes derive from Node -- superclass
+ */
+#ifdef __cplusplus
+class Node {
+public:
+ NodeType ntype;
+ char *rname; /* what rule does this element live in? */
+ int file; /* index in FileStr */
+ int line; /* line number that element occurs on */
+ };
+#else
+typedef struct _node {
+ NodeType ntype;
+ char *rname; /* what rule does this element live in? */
+ int file; /* index in FileStr */
+ int line; /* line number that element occurs on */
+ } Node;
+#endif
+
+#ifdef __cplusplus
+class ActionNode : public Node {
+public:
+#else
+typedef struct _anode {
+ NodeType ntype;
+ char *rname; /* what rule does this action live in? */
+ int file; /* index in FileStr (name of file with action) */
+ int line; /* line number that action occurs on */
+#endif
+ Node *next;
+ char *action;
+ int is_predicate; /* true if action is a <<...>>? predicate action */
+ int done; /* don't dump if action dumped (used for predicates) */
+ int init_action; /* is this the 1st action of 1st prod of block? */
+ char *pred_fail; /* what to do/print when predicate fails */
+ Predicate *guardpred; /* if '(context)? =>' was present, already done */
+ unsigned char frmwarned;/* have we dumped a warning for pred yet? */
+ unsigned char ctxwarned;/* have we dumped a warning for pred yet? */
+ unsigned char predTooLong; /* MR10 have we dumped warning for pred yet */
+ unsigned char noHoist; /* MR12 literally "noHoist" */
+ Predicate *ampersandPred; /* MR10 (g)? && <<p>>? expr */
+#ifdef __cplusplus
+ Junction *guardNodes; /* MR11 */
+#else
+ struct _junct *guardNodes; /* MR11 */
+#endif
+ struct _PredEntry *predEntry; /* MR11 */
+ int inverted; /* MR11 <<!predSymbol>>? */
+#ifdef __cplusplus
+ };
+#else
+ } ActionNode;
+#endif
+
+#ifdef __cplusplus
+class TokNode : public Node {
+public:
+#else
+typedef struct _toknode {
+ NodeType ntype;
+ char *rname; /* name of rule it's in */
+ int file; /* index in FileStr (name of file with rule) */
+ int line; /* line number that token occurs on */
+#endif
+ Node *next;
+ int token;
+ int astnode; /* leaf/root/excluded (used to build AST's) */
+ unsigned char label;/* token label or expression ? */
+ unsigned char remapped;
+ /* used if token id's are forced to certain positions;
+ * a function walks the tree reassigning token numbers */
+ int upper_range; /* MR13 - was char */
+ /* used only if Token is of type T1..T2; in this case,
+ * use token..upper_range as the range; else
+ * upper_range must be 0 */
+ unsigned char wild_card;
+ /* indicates that the token is the "." wild-card;
+ * field token is ignored if wild_card is set
+ */
+ unsigned int elnum; /* element number within the alternative */
+#ifdef __cplusplus
+ Junction *altstart; /* pointer to node that starts alt */
+#else
+ struct _junct *altstart; /* pointer to node that starts alt */
+#endif
+ struct _TCnode *tclass; /* token class if tokclass ref */
+ set tset; /* set of tokens represented by meta token */
+ char *el_label; /* el_label:toknode */
+ unsigned char complement; /* complement the set? */
+ ExceptionGroup *ex_group; /* any exception[el_label] attached? */
+ unsigned char use_def_MT_handler;
+ unsigned char label_used_in_semantic_pred; /* MR10 */
+#ifdef __cplusplus
+ };
+#else
+ } TokNode;
+#endif
+
+#ifdef __cplusplus
+class RuleRefNode : public Node {
+public:
+#else
+typedef struct _rrnode {
+ NodeType ntype;
+ char *rname; /* name of rule it's in */
+ int file; /* index in FileStr (name of file with rule)
+ it's in */
+ int line; /* line number that rule ref occurs on */
+#endif
+ Node *next;
+ char *text; /* reference to which rule */
+ char *parms; /* point to parameters of rule invocation
+ (if present) */
+ char *assign; /* point to left-hand-side of assignment
+ (if any) */
+ int linked; /* Has a FoLink already been established? */
+ int astnode; /* excluded? (used to build AST's) */
+ unsigned int elnum; /* element number within the alternative */
+#ifdef __cplusplus
+ Junction *altstart;
+#else
+ struct _junct *altstart;
+#endif
+ char *el_label; /* el_label:rrnode */
+ ExceptionGroup *ex_group; /* any exception[el_label] attached? */
+#ifdef __cplusplus
+ };
+#else
+ } RuleRefNode;
+#endif
+
+#ifdef __cplusplus
+class Junction : public Node {
+public:
+#else
+typedef struct _junct {
+ NodeType ntype;
+ char *rname; /* name of rule junction is in */
+ int file; /* index in FileStr (name of file with rule)
+ if blk == RuleBlk */
+ int line; /* line number that rule occurs on */
+#endif
+ int seq; /* MR10 sequence number */
+ char ignore; /* used by FIRST computation to ignore
+ empty alt added for the (...)+ blks */
+ char visited; /* used by recursive routines to avoid
+ infinite recursion */
+ char pvisited; /* used by print routines to avoid
+ infinite recursion */
+ char fvisited; /* used by FoLink() to avoid
+ infinite recursion */
+ char *lock; /* used by REACH to track infinite recursion */
+ char *pred_lock; /* used by find_predicates to track infinite recursion */
+ int altnum; /* used in subblocks. altnum==0 means not an
+ alt of subrule */
+ int jtype; /* annotation for code-gen/FIRST/FOLLOW.
+ Junction type */
+#ifdef __cplusplus
+ Junction *end; /* pointer to node with EndBlk in it
+ if blk == a block type */
+#else
+ struct _junct *end; /* pointer to node with EndBlk in it
+ if blk == a block type */
+#endif
+ Node *p1, *p2;
+ char halt; /* never move past a junction with halt==TRUE */ /* MR10 was int */
+ char *pdecl; /* point to declaration of parameters on rule
+ (if present) */
+ char *parm; /* point to parameter of block invocation
+ (if present) */
+ char predparm; /* indicates that the 'parm' is a predicate
+ * to be used in the while loop generated
+ * for blocks */ /* MR10 was int */
+ char *ret; /* point to return type of rule (if present) */
+ char *erraction; /* point to error action (if present) */
+ int blockid; /* this is a unique ID */
+ char *exception_label; /* goto label for this alt */
+ set *fset; /* used for code generation */
+ Tree *ftree; /* used for code generation */
+ Predicate *predicate;/* predicate that can be used to disambiguate */
+ char guess; /* true if (...)? block */
+ char alpha_beta_guess_end; /* MR14 1 => end block of guess sub block */
+ Node *guess_analysis_point; /* MR14 */
+ char approx; /* limit block to use linear approx lookahead? */
+ set tokrefs; /* if ith element of alt is tokref then i is member */
+ set rulerefs; /* if ith element of alt is rule ref then i is member */
+ struct _ListNode *exceptions; /* list of exceptions groups for rule */
+ struct _ListNode *el_labels; /* list of element labels for rule */
+ ExceptionGroup *outerEG; /* MR7 */
+ int curAltNum; /* MR7 */
+ char* pFirstSetSymbol; /* #pragma FirstSetSymbol(Foo) MR21 */
+#ifdef __cplusplus
+ Junction *pendingLink; /* MR7 */
+#else
+ struct _junct *pendingLink; /* MR7 */
+#endif
+ char overlap_warning; /* MR10 */
+#ifdef __cplusplus
+ };
+#else
+ } Junction;
+#endif
+
+typedef struct { Node *left, *right;} Graph;
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/tokens.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/tokens.h
new file mode 100644
index 00000000..2fb253f7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/antlr/tokens.h
@@ -0,0 +1,246 @@
+#ifndef tokens_h
+#define tokens_h
+/* tokens.h -- List of labelled tokens and stuff
+ *
+ * Generated from: antlr.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * ANTLR Version 1.33MR33
+ */
+#define zzEOF_TOKEN 1
+#define Eof 1
+#define QuotedTerm 2
+#define Action 34
+#define Pred 35
+#define PassAction 36
+#define WildCard 87
+#define LABEL 89
+#define Pragma 92
+#define FirstSetSymbol 93
+#define NonTerminal 100
+#define TokenTerm 101
+#define ID 148
+#define INT 150
+
+#ifdef __USE_PROTOS
+void grammar(void);
+#else
+extern void grammar();
+#endif
+
+#ifdef __USE_PROTOS
+void class_def(void);
+#else
+extern void class_def();
+#endif
+
+#ifdef __USE_PROTOS
+void rule(void);
+#else
+extern void rule();
+#endif
+
+#ifdef __USE_PROTOS
+void laction(void);
+#else
+extern void laction();
+#endif
+
+#ifdef __USE_PROTOS
+void lmember(void);
+#else
+extern void lmember();
+#endif
+
+#ifdef __USE_PROTOS
+void lprefix(void);
+#else
+extern void lprefix();
+#endif
+
+#ifdef __USE_PROTOS
+void aPred(void);
+#else
+extern void aPred();
+#endif
+
+#ifdef __USE_PROTOS
+extern Predicate * predOrExpr(void);
+#else
+extern Predicate * predOrExpr();
+#endif
+
+#ifdef __USE_PROTOS
+extern Predicate * predAndExpr(void);
+#else
+extern Predicate * predAndExpr();
+#endif
+
+#ifdef __USE_PROTOS
+extern Predicate * predPrimary(void);
+#else
+extern Predicate * predPrimary();
+#endif
+
+#ifdef __USE_PROTOS
+void aLexclass(void);
+#else
+extern void aLexclass();
+#endif
+
+#ifdef __USE_PROTOS
+void error(void);
+#else
+extern void error();
+#endif
+
+#ifdef __USE_PROTOS
+void tclass(void);
+#else
+extern void tclass();
+#endif
+
+#ifdef __USE_PROTOS
+void token(void);
+#else
+extern void token();
+#endif
+
+#ifdef __USE_PROTOS
+void block(set * toksrefd,set * rulesrefd);
+#else
+extern void block();
+#endif
+
+#ifdef __USE_PROTOS
+void alt(set * toksrefd,set * rulesrefd);
+#else
+extern void alt();
+#endif
+
+#ifdef __USE_PROTOS
+extern LabelEntry * element_label(void);
+#else
+extern LabelEntry * element_label();
+#endif
+
+#ifdef __USE_PROTOS
+extern Node * element(int old_not,int first_on_line,int use_def_MT_handler);
+#else
+extern Node * element();
+#endif
+
+#ifdef __USE_PROTOS
+void default_exception_handler(void);
+#else
+extern void default_exception_handler();
+#endif
+
+#ifdef __USE_PROTOS
+extern ExceptionGroup * exception_group(void);
+#else
+extern ExceptionGroup * exception_group();
+#endif
+
+#ifdef __USE_PROTOS
+extern ExceptionHandler * exception_handler(void);
+#else
+extern ExceptionHandler * exception_handler();
+#endif
+
+#ifdef __USE_PROTOS
+void enum_file(char * fname);
+#else
+extern void enum_file();
+#endif
+
+#ifdef __USE_PROTOS
+void defines(char * fname);
+#else
+extern void defines();
+#endif
+
+#ifdef __USE_PROTOS
+void enum_def(char * fname);
+#else
+extern void enum_def();
+#endif
+
+#endif
+extern SetWordType zzerr1[];
+extern SetWordType zzerr2[];
+extern SetWordType zzerr3[];
+extern SetWordType zzerr4[];
+extern SetWordType setwd1[];
+extern SetWordType zzerr5[];
+extern SetWordType zzerr6[];
+extern SetWordType zzerr7[];
+extern SetWordType zzerr8[];
+extern SetWordType zzerr9[];
+extern SetWordType setwd2[];
+extern SetWordType zzerr10[];
+extern SetWordType zzerr11[];
+extern SetWordType zzerr12[];
+extern SetWordType zzerr13[];
+extern SetWordType setwd3[];
+extern SetWordType zzerr14[];
+extern SetWordType zzerr15[];
+extern SetWordType zzerr16[];
+extern SetWordType zzerr17[];
+extern SetWordType zzerr18[];
+extern SetWordType zzerr19[];
+extern SetWordType zzerr20[];
+extern SetWordType zzerr21[];
+extern SetWordType setwd4[];
+extern SetWordType zzerr22[];
+extern SetWordType zzerr23[];
+extern SetWordType zzerr24[];
+extern SetWordType zzerr25[];
+extern SetWordType zzerr26[];
+extern SetWordType setwd5[];
+extern SetWordType zzerr27[];
+extern SetWordType zzerr28[];
+extern SetWordType zzerr29[];
+extern SetWordType zzerr30[];
+extern SetWordType zzerr31[];
+extern SetWordType zzerr32[];
+extern SetWordType zzerr33[];
+extern SetWordType setwd6[];
+extern SetWordType zzerr34[];
+extern SetWordType zzerr35[];
+extern SetWordType zzerr36[];
+extern SetWordType zzerr37[];
+extern SetWordType zzerr38[];
+extern SetWordType zzerr39[];
+extern SetWordType zzerr40[];
+extern SetWordType zzerr41[];
+extern SetWordType zzerr42[];
+extern SetWordType setwd7[];
+extern SetWordType zzerr43[];
+extern SetWordType zzerr44[];
+extern SetWordType zzerr45[];
+extern SetWordType zzerr46[];
+extern SetWordType zzerr47[];
+extern SetWordType zzerr48[];
+extern SetWordType zzerr49[];
+extern SetWordType zzerr50[];
+extern SetWordType zzerr51[];
+extern SetWordType zzerr52[];
+extern SetWordType zzerr53[];
+extern SetWordType setwd8[];
+extern SetWordType zzerr54[];
+extern SetWordType zzerr55[];
+extern SetWordType zzerr56[];
+extern SetWordType zzerr57[];
+extern SetWordType setwd9[];
+extern SetWordType zzerr58[];
+extern SetWordType zzerr59[];
+extern SetWordType zzerr60[];
+extern SetWordType zzerr61[];
+extern SetWordType zzerr62[];
+extern SetWordType zzerr63[];
+extern SetWordType zzerr64[];
+extern SetWordType zzerr65[];
+extern SetWordType setwd10[];
+extern SetWordType setwd11[];
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgDDK.mak b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgDDK.mak
new file mode 100644
index 00000000..e14a2093
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgDDK.mak
@@ -0,0 +1,121 @@
+# PCCTS directory
+
+# You will need to set the LIB variable similar to this.
+# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib"
+
+# PCCTS_HOME=<your PCCTS_HOME>
+PCCTS_HOME=$(WORKSPACE)\Tools\CCode\Source\Pccts
+DLG_SRC=$(PCCTS_HOME)\dlg
+PCCTS_H=$(PCCTS_HOME)\h
+
+
+# Support directories
+SET=$(PCCTS_HOME)\support\set
+
+
+# Compiler stuff
+CC = cl
+CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \
+ -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /W3 /Zi
+
+DLG_OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \
+ output.obj relabel.obj automata.obj
+
+SUPPORT_OBJS = set.obj
+
+# Dependencies
+
+dlg.exe: $(DLG_OBJS) $(SUPPORT_OBJS)
+ $(CC) $(CFLAGS) -o dlg.exe bufferoverflowu.lib $(DLG_OBJS) $(SUPPORT_OBJS)
+ del *.obj
+ del *.ilk
+ del *.pdb
+ move dlg.exe $(WORKSPACE)\Tools\bin\.
+
+dlg_p.obj: $(DLG_SRC)\dlg_p.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\mode.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_p.c
+
+dlg_a.obj: $(DLG_SRC)\dlg_a.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgauto.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\mode.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_a.c
+
+main.obj: $(DLG_SRC)\main.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\mode.h \
+ $(DLG_SRC)\stdpccts.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\main.c
+
+err.obj: $(DLG_SRC)\err.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(PCCTS_H)\err.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\err.c
+
+support.obj: $(DLG_SRC)\support.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\support.c
+
+output.obj: $(DLG_SRC)\output.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\output.c
+
+relabel.obj: $(DLG_SRC)\relabel.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\relabel.c
+
+automata.obj: $(DLG_SRC)\automata.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\automata.c
+
+
+set.obj: $(SET)\set.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+
+ $(CC) -c $(CFLAGS) $(SET)\set.c
+
+clean:
+ del *.obj
+
+distclean:
+ del *.obj
+ del $(WORKSPACE)\Tools\bin\dlg.exe
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgMS.mak b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgMS.mak
new file mode 100644
index 00000000..e667f025
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgMS.mak
@@ -0,0 +1,126 @@
+# PCCTS directory
+
+# You will need to set the LIB variable similar to this.
+# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib"
+
+# PCCTS_HOME=<your PCCTS_HOME>
+PCCTS_HOME=$(BASE_TOOLS_PATH)\Source\C\VfrCompile\Pccts
+DLG_SRC=$(PCCTS_HOME)\dlg
+PCCTS_H=$(PCCTS_HOME)\h
+
+
+# Support directories
+SET=$(PCCTS_HOME)\support\set
+
+
+# Compiler stuff
+CC = cl
+CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \
+ -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /W3 /Zi \
+ /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE
+
+DLG_OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \
+ output.obj relabel.obj automata.obj
+
+SUPPORT_OBJS = set.obj
+
+# Dependencies
+
+$(EDK_TOOLS_PATH)\Bin\Win32\dlg.exe: $(DLG_OBJS) $(SUPPORT_OBJS)
+ $(CC) $(CFLAGS) -Fedlg.exe $(DLG_OBJS) $(SUPPORT_OBJS)
+ -@if not exist $(EDK_TOOLS_PATH)\Bin\Win32 mkdir $(EDK_TOOLS_PATH)\Bin\Win32
+ copy dlg.exe $(EDK_TOOLS_PATH)\Bin\Win32
+
+dlg_p.obj: $(DLG_SRC)\dlg_p.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\mode.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_p.c
+
+dlg_a.obj: $(DLG_SRC)\dlg_a.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgauto.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\mode.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_a.c
+
+main.obj: $(DLG_SRC)\main.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\mode.h \
+ $(DLG_SRC)\stdpccts.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\main.c
+
+err.obj: $(DLG_SRC)\err.c \
+ $(PCCTS_H)\antlr.h \
+ $(PCCTS_H)\config.h \
+ $(PCCTS_H)\dlgdef.h \
+ $(PCCTS_H)\err.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+ $(DLG_SRC)\tokens.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\err.c
+
+support.obj: $(DLG_SRC)\support.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\support.c
+
+output.obj: $(DLG_SRC)\output.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\output.c
+
+relabel.obj: $(DLG_SRC)\relabel.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\relabel.c
+
+automata.obj: $(DLG_SRC)\automata.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+ $(DLG_SRC)\dlg.h \
+
+ $(CC) -c $(CFLAGS) $(DLG_SRC)\automata.c
+
+
+set.obj: $(SET)\set.c \
+ $(PCCTS_H)\config.h \
+ $(SET)\set.h \
+
+ $(CC) -c $(CFLAGS) $(SET)\set.c
+
+clean:
+ -del *.obj
+ -del *.ilk
+ -del *.pdb
+
+cleanall:
+ -del *.obj
+ -del *.ilk
+ -del *.pdb
+ -del *.exe
+ -del $(EDK_TOOLS_PATH)\Bin\Win32\dlg.exe
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgPPC.mak b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgPPC.mak
new file mode 100644
index 00000000..2810a3b0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/DlgPPC.mak
@@ -0,0 +1,84 @@
+# File: dlgPPC.make
+# Target: dlgPPC
+# Sources: automata.c
+# dlg_a.c
+# dlg_p.c
+# err.c
+# main.c
+# output.c
+# relabel.c
+# support.c
+# ::support:set:set.c
+# Created: Sunday, May 17, 1998 11:34:20 PM
+# Author: Kenji Tanaka
+
+
+MAKEFILE = dlgPPC.make
+¥MondoBuild¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified
+Includes = ¶
+ -i "::h:" ¶
+ -i "::support:set:"
+Sym¥PPC =
+ObjDir¥PPC = ":Obj:"
+
+PPCCOptions = {Includes} {Sym¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN
+
+Objects¥PPC = ¶
+ "{ObjDir¥PPC}automata.c.x" ¶
+ "{ObjDir¥PPC}dlg_a.c.x" ¶
+ "{ObjDir¥PPC}dlg_p.c.x" ¶
+ "{ObjDir¥PPC}err.c.x" ¶
+ "{ObjDir¥PPC}main.c.x" ¶
+ "{ObjDir¥PPC}output.c.x" ¶
+ "{ObjDir¥PPC}relabel.c.x" ¶
+ "{ObjDir¥PPC}support.c.x" ¶
+ "{ObjDir¥PPC}set.c.x"
+
+
+dlgPPC ÄÄ {¥MondoBuild¥} {Objects¥PPC}
+ PPCLink ¶
+ -o {Targ} {Sym¥PPC} ¶
+ {Objects¥PPC} ¶
+ -t 'MPST' ¶
+ -c 'MPS ' ¶
+ "{SharedLibraries}InterfaceLib" ¶
+ "{SharedLibraries}StdCLib" ¶
+ "{SharedLibraries}MathLib" ¶
+ "{PPCLibraries}StdCRuntime.o" ¶
+ "{PPCLibraries}PPCCRuntime.o" ¶
+ "{PPCLibraries}PPCToolLibs.o"
+
+
+"{ObjDir¥PPC}automata.c.x" Ä {¥MondoBuild¥} automata.c
+ {PPCC} automata.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}dlg_a.c.x" Ä {¥MondoBuild¥} dlg_a.c
+ {PPCC} dlg_a.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}dlg_p.c.x" Ä {¥MondoBuild¥} dlg_p.c
+ {PPCC} dlg_p.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}err.c.x" Ä {¥MondoBuild¥} err.c
+ {PPCC} err.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}main.c.x" Ä {¥MondoBuild¥} main.c
+ {PPCC} main.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}output.c.x" Ä {¥MondoBuild¥} output.c
+ {PPCC} output.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}relabel.c.x" Ä {¥MondoBuild¥} relabel.c
+ {PPCC} relabel.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}support.c.x" Ä {¥MondoBuild¥} support.c
+ {PPCC} support.c -o {Targ} {PPCCOptions}
+
+"{ObjDir¥PPC}set.c.x" Ä {¥MondoBuild¥} "::support:set:set.c"
+ {PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions}
+
+
+dlgPPC ÄÄ dlg.r
+ Rez dlg.r -o dlgPPC -a
+
+Install Ä dlgPPC
+ Duplicate -y dlgPPC "{MPW}"Tools:dlg
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/automata.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/automata.c
new file mode 100644
index 00000000..399231ef
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/automata.c
@@ -0,0 +1,353 @@
+/* Automata conversion functions for DLG
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "pcctscfg.h"
+#include "dlg.h"
+#ifdef MEMCHK
+#include "trax.h"
+#else
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif /* __STDC__ */
+#endif
+
+#define hash_list struct _hash_list_
+hash_list{
+ hash_list *next; /* next thing in list */
+ dfa_node *node;
+ };
+
+int dfa_allocated = 0; /* keeps track of number of dfa nodes */
+dfa_node **dfa_array; /* root of binary tree that stores dfa array */
+dfa_node *dfa_model_node;
+hash_list *dfa_hash[HASH_SIZE]; /* used to quickly find */
+ /* desired dfa node */
+
+void
+#ifdef __USE_PROTOS
+make_dfa_model_node(int width)
+#else
+make_dfa_model_node(width)
+int width;
+#endif
+{
+ register int i;
+ dfa_model_node = (dfa_node*) malloc(sizeof(dfa_node)
+ + sizeof(int)*width);
+ dfa_model_node->node_no = -1; /* impossible value for real dfa node */
+ dfa_model_node->dfa_set = 0;
+ dfa_model_node->alternatives = FALSE;
+ dfa_model_node->done = FALSE;
+ dfa_model_node->nfa_states = empty;
+ for(i = 0; i<width; i++){
+ dfa_model_node->trans[i] = NIL_INDEX;
+ }
+}
+
+
+/* adds a new nfa to the binary tree and returns a pointer to it */
+dfa_node *
+#ifdef __USE_PROTOS
+new_dfa_node(set nfa_states)
+#else
+new_dfa_node(nfa_states)
+set nfa_states;
+#endif
+{
+ register int j;
+ register dfa_node *t;
+ static int dfa_size=0; /* elements dfa_array[] can hold */
+
+ ++dfa_allocated;
+ if (dfa_size<=dfa_allocated){
+ /* need to redo array */
+ if (!dfa_array){
+ /* need some to do initial allocation */
+ dfa_size=dfa_allocated+DFA_MIN;
+ dfa_array=(dfa_node **) malloc(sizeof(dfa_node*)*
+ dfa_size);
+ }else{
+ /* need more space */
+ dfa_size=2*(dfa_allocated+1);
+ dfa_array=(dfa_node **) realloc(dfa_array,
+ sizeof(dfa_node*)*dfa_size);
+ }
+ }
+ /* fill out entry in array */
+ t = (dfa_node*) malloc(sizeof(nfa_node)+sizeof(int)*class_no);
+ *t = *dfa_model_node;
+ for (j=0; j<class_no; ++j)
+ t->trans[j] = NIL_INDEX;
+ t->node_no = dfa_allocated;
+ t->nfa_states = set_dup(nfa_states);
+ dfa_array[dfa_allocated] = t;
+ return t;
+}
+
+
+/* past a pointer to the start of the nfa graph
+ * nfa_to_dfa convers this graph to dfa. The function returns
+ * a pointer to the first dfa state.
+ * NOTE: The function that prints out the table will have to figure out how
+ * to find the other dfa states given the first dfa_state and the number of dfa
+ * nodes allocated
+ */
+dfa_node **
+#ifdef __USE_PROTOS
+nfa_to_dfa(nfa_node *start)
+#else
+nfa_to_dfa(start)
+nfa_node *start;
+#endif
+{
+ register dfa_node *d_state, *trans_d_state;
+ register int a;
+ set t;
+ int last_done;
+ unsigned *nfa_list;
+ unsigned *reach_list;
+
+ reach_list = (unsigned *) malloc((2+nfa_allocated)*sizeof(unsigned));
+ if (!start) return NULL;
+ t = set_of(NFA_NO(start));
+ _set_pdq(t,reach_list);
+ closure(&t,reach_list);
+ /* Make t a dfa state */
+ d_state = dfastate(t);
+ last_done = DFA_NO(d_state);
+
+ do {
+ /* Mark dfa state x as "done" */
+ d_state->done = TRUE;
+ nfa_list = set_pdq(d_state->nfa_states);
+ for (a = 0; a<class_no; ++a) {
+ /* Add NFA states reached by a from d_state */
+ reach(nfa_list,a,reach_list);
+ /* Were any states found? */
+ if ((*reach_list)!=nil) {
+ /* was t=empty; */
+ set_free(t);
+ /* yes, compute closure */
+ closure(&t,reach_list);
+ /* Make DFA state of it ... */
+ trans_d_state = dfastate(t);
+ /* And make transition x->t, labeled with a */
+ d_state->trans[a] = DFA_NO(trans_d_state);
+ d_state->alternatives = TRUE;
+ }
+ }
+ free(nfa_list);
+ ++last_done; /* move forward in queue */
+ /* And so forth until nothing isn't done */
+ d_state = DFA(last_done);
+ } while (last_done<=dfa_allocated);
+
+ free(reach_list);
+ set_free(t);
+
+ /* returns pointer to the array that holds the automaton */
+ return dfa_array;
+}
+
+void
+#ifdef __USE_PROTOS
+clear_hash(void)
+#else
+clear_hash()
+#endif
+{
+ register int i;
+
+ for(i=0; i<HASH_SIZE; ++i)
+ dfa_hash[i] = 0;
+}
+
+#ifdef HASH_STAT /* VBox: 'def' */
+void
+#ifdef __USE_PROTOS
+fprint_hash_stats(FILE *f)
+#else
+fprint_hash_stats(f)
+FILE *f;
+#endif
+{
+ register hash_list *p;
+ register int i,j;
+ register total;
+
+ total=0;
+ for(i=0; i<HASH_SIZE; ++i){
+ j=0;
+ p = dfa_hash[i];
+ while(p){
+ ++j;
+ p = p->next;
+ }
+ total+=j;
+ fprintf(f,"bin[%d] has %d\n",i,j);
+ }
+ fprintf(f,"total = %d\n",total);
+}
+#endif
+
+/* Returns a pointer to a dfa node that has the same nfa nodes in it.
+ * This may or may not be a newly created node.
+ */
+dfa_node *
+#ifdef __USE_PROTOS
+dfastate(set nfa_states)
+#else
+dfastate(nfa_states)
+set nfa_states;
+#endif
+{
+ register hash_list *p;
+ int bin;
+
+ /* hash using set and see if it exists */
+ bin = set_hash(nfa_states,HASH_SIZE);
+ p = dfa_hash[bin];
+ while(p && !set_equ(nfa_states,(p->node)->nfa_states)){
+ p = p->next;
+ }
+ if(!p){
+ /* next state to add to hash table */
+ p = (hash_list*)malloc(sizeof(hash_list));
+ p->node = new_dfa_node(nfa_states);
+ p->next = dfa_hash[bin];
+ dfa_hash[bin] = p;
+ }
+ return (p->node);
+}
+
+
+/* this reach assumes the closure has been done already on set */
+int
+#ifdef __USE_PROTOS
+reach(unsigned *nfa_list, register int a, unsigned *reach_list)
+#else
+reach(nfa_list, a, reach_list)
+unsigned *nfa_list;
+register int a;
+unsigned *reach_list;
+#endif
+{
+ register unsigned *e;
+ register nfa_node *node;
+ int t=0;
+
+ e = nfa_list;
+ if (e){
+ while (*e != nil){
+ node = NFA(*e);
+ if (set_el(a,node->label)){
+ t=1;
+ *reach_list=NFA_NO(node->trans[0]);
+ ++reach_list;
+ }
+ ++e;
+ }
+ }
+ *reach_list=nil;
+ return t;
+}
+
+/* finds all the nodes that can be reached by epsilon transitions
+ from the set of a nodes and returns puts them back in set b */
+set
+#ifdef __USE_PROTOS
+closure(set *b, unsigned *reach_list)
+#else
+closure(b, reach_list)
+set *b;
+unsigned *reach_list;
+#endif
+{
+ register nfa_node *node,*n; /* current node being examined */
+ register unsigned *e;
+
+ ++operation_no;
+#if 0
+ t = e = set_pdq(*b);
+#else
+ e=reach_list;
+#endif
+ while (*e != nil){
+ node = NFA(*e);
+ set_orel(NFA_NO(node),b);
+ /* mark it done */
+ node->nfa_set = operation_no;
+ if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) &&
+ (n->nfa_set != operation_no)){
+ /* put in b */
+ set_orel(NFA_NO(n),b);
+ close1(n,operation_no,b);
+ }
+ if ((n=node->trans[1]) != NIL_INDEX &&
+ (n->nfa_set != operation_no)){
+ /* put in b */
+ set_orel(NFA_NO(node->trans[1]),b);
+ close1(n,operation_no,b);
+ }
+ ++e;
+ }
+#if 0
+ free(t);
+#endif
+ return *b;
+}
+
+#ifdef __USE_PROTOS
+void close1(nfa_node *node, int o, set *b)
+#else
+void close1(node,o,b)
+nfa_node *node;
+int o; /* marker to avoid cycles */
+set *b;
+#endif
+{
+ register nfa_node *n; /* current node being examined */
+
+ /* mark it done */
+ node->nfa_set = o;
+ if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) &&
+ (n->nfa_set != o)){
+ /* put in b */
+ set_orel(NFA_NO(n),b);
+ close1(n,o,b);
+ }
+ if ((n=node->trans[1]) != NIL_INDEX &&
+ (n->nfa_set != o)){
+ /* put in b */
+ set_orel(NFA_NO(node->trans[1]),b);
+ close1(n,o,b);
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.1 b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.1
new file mode 100644
index 00000000..3a1694ee
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.1
@@ -0,0 +1,79 @@
+.TH dlg 1 "April 1994" "DLG" "PCCTS Manual Pages"
+.SH NAME
+dlg \- DFA Lexical Analyzer Generator
+.SH SYNTAX
+.LP
+\fBdlg\fR [\fIoptions\fR] \fIlexical_spec\fR [\fIoutput_file\fR]
+.SH DESCRIPTION
+.B dlg
+is a tool that produces fast deterministic finite automata for recognizing
+regular expressions in input.
+.SH OPTIONS
+.IP "\fB-CC\fR"
+Generate C++ output. The \fIoutput_file\fP is not specified in this
+case.
+.IP "\fB-C\fR[\fP level\fR]
+Where \fPlevel\fR is the compression level used. 0 indications no
+compression, 1 removes all unused characters from the transition from table,
+and 2 maps equivalent characters into the same character classes. It is
+suggested that level -C2 is used, since it will significantly reduce the size
+of the dfa produced for lexical analyzer.
+.IP "\fB-m\fP
+Produces the header file for the lexical mode with a name other than
+the default name of "mode.h".
+.IP \fB-i\fP
+An interactive, or as interactive as possible, parser is produced. A character
+is only obtained when required to decide which state to go to. Some care
+must be taken to obtain accept states that do not require look ahead at the
+next character to determine if that is the stop state. Any regular expression
+with a Kleene closure at the end is guaranteed to require another character
+of look ahead.
+.IP "\fB-cl\fP class
+Specify a class name for DLG to generate. The default is DLGLexer.
+'class' will be a subclass of DLGLexerBase; only used for -CC.
+.IP \fB-ci\fP
+The automaton will treat upper and lower case characters identically.
+This is accomplished in the automaton; the characters in the lexical
+buffer are unmodified.
+.IP \fB-cs\fP
+Upper and lower case characters are treated as distinct. This is the
+default.
+.IP "\fB-o\fP dir
+Directory where output files should go (default="."). This is very
+nice for keeping the source directory clear of ANTLR and DLG spawn.
+.IP \fB-Wambiguity\fP
+Warns if more than one regular expression could match the same character
+sequence. The warnings give the numbers of the expressions in the dlg
+lexical specification file. The numbering of the expressions starts at one.
+Multiple warnings may be print for the same expressions.
+.IP \-
+Used in place of file names to get input from standard in or send output
+to standard out.
+.SH "SPECIAL CONSIDERATIONS"
+.PP
+\fIDlg\fP works... we think. There is no implicit guarantee of
+anything. We reserve no \fBlegal\fP rights to the software known as
+the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the
+public domain. An individual or company may do whatever they wish
+with source code distributed with PCCTS or the code generated by
+PCCTS, including the incorporation of PCCTS, or its output, into
+commercial software. We encourage users to develop software with
+PCCTS. However, we do ask that credit is given to us for developing
+PCCTS. By "credit", we mean that if you incorporate our source code
+into one of your programs (commercial product, research project, or
+otherwise) that you acknowledge this fact somewhere in the
+documentation, research report, etc... If you like PCCTS and have
+developed a nice tool with the output, please mention that you
+developed it using PCCTS. As long as these guidelines are followed, we
+expect to continue enhancing this system and expect to make other
+tools available as they are completed.
+.SH FILES
+.B mode.h
+,
+.B dlgauto.h
+,
+.B dlgdef.h
+.SH SEE ALSO
+.BR antlr (1),
+.BR pccts (1)
+.SH BUGS
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.h
new file mode 100644
index 00000000..030c2caa
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.h
@@ -0,0 +1,250 @@
+/* dlg header file
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+/* MR1 Move pcctscfg.h to top of file */
+
+#include "pcctscfg.h"
+
+/* turn off warnings for unreferenced labels */
+
+#ifdef _MSC_VER
+#pragma warning(disable:4102)
+#endif
+
+#include "set.h"
+
+#define TRUE 1
+#define FALSE 0
+
+/***** output related stuff *******************/
+#define IN input_stream
+#define OUT output_stream
+
+#define MAX_MODES 50 /* number of %%names allowed */
+#define MAX_ON_LINE 10
+
+#define NFA_MIN 64 /* minimum nfa_array size */
+#define DFA_MIN 64 /* minimum dfa_array size */
+
+#define DEFAULT_CLASSNAME "DLGLexer"
+
+/* these macros allow the size of the character set to be easily changed */
+/* NOTE: do NOT change MIN_CHAR since EOF is the lowest char, -1 */
+#define MIN_CHAR (-1) /* lowest possible character possible on input */
+#define MAX_CHAR 255 /* highest possible character possible on input */
+#define CHAR_RANGE (1+(MAX_CHAR) - (MIN_CHAR))
+
+/* indicates that the not an "array" reference */
+#define NIL_INDEX 0
+
+/* size of hash table used to find dfa_states quickly */
+#define HASH_SIZE 211
+
+#define nfa_node struct _nfa_node
+nfa_node {
+ int node_no;
+ int nfa_set;
+ int accept; /* what case to use */
+ nfa_node *trans[2];
+ set label; /* one arc always labelled with epsilon */
+};
+
+#define dfa_node struct _dfa_node
+dfa_node {
+ int node_no;
+ int dfa_set;
+ int alternatives; /* used for interactive mode */
+ /* are more characters needed */
+ int done;
+ set nfa_states;
+ int trans[1];/* size of transition table depends on
+ * number of classes required for automata.
+ */
+
+
+};
+
+/******** macros for accessing the NFA and DFA nodes ****/
+#define NFA(x) (nfa_array[x])
+#define DFA(x) (dfa_array[x])
+#define DFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX)
+#define NFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX)
+
+/******** wrapper for memory checking ***/
+/*#define malloc(x) dlg_malloc((x),__FILE__,__LINE__)*/
+
+/*#define calloc(x,y) dlg_calloc((x),(y),__FILE__,__LINE__)*/
+
+/******** antlr attributes *************/
+typedef struct {
+ unsigned char letter;
+ nfa_node *l,*r;
+ set label;
+ } Attrib;
+
+#define zzcr_attr(attr, token, text) { \
+ (attr)->letter = text[0]; (attr)->l = NULL; \
+ (attr)->r = NULL; (attr)->label = empty; \
+}
+#define zzd_attr(a) set_free((a)->label);
+
+/******************** Variable ******************************/
+extern char program[]; /* tells what program this is */
+extern char version[]; /* tells what version this is */
+extern char *file_str[]; /* file names being used */
+extern int err_found; /* flag to indicate error occurred */
+extern int action_no; /* last action function printed */
+extern int func_action; /* should actions be turned into functions?*/
+extern set used_chars; /* used to label trans. arcs */
+extern set used_classes; /* classes or chars used to label trans. arcs */
+extern int class_no; /* number of classes used */
+extern set class_sets[]; /* shows char. in each class */
+extern set normal_chars; /* mask off unused portion of set */
+extern int comp_level; /* what compression level to use */
+extern int interactive; /* interactive scanner (avoid lookahead)*/
+extern int mode_counter; /* keeps track of the number of %%name */
+extern int dfa_basep[]; /* start of each group of dfa */
+extern int dfa_class_nop[];/* number of transition arcs in */
+ /* each dfa in each mode */
+extern int nfa_allocated;
+extern int dfa_allocated;
+extern nfa_node **nfa_array; /* start of nfa "array" */
+extern dfa_node **dfa_array; /* start of dfa "array" */
+extern int operation_no; /* unique number for each operation */
+extern FILE *input_stream; /* where description read from */
+extern FILE *output_stream; /* where to put the output */
+extern FILE *mode_stream; /* where to put the mode output */
+extern FILE *class_stream;
+extern char *mode_file; /* name of file for mode output */
+extern int gen_ansi; /* produce ansi compatible code */
+extern int case_insensitive;/* ignore case of input spec. */
+extern int warn_ambig; /* show if regular expressions ambiguous */
+extern int gen_cpp;
+extern char *cl_file_str;
+extern int firstLexMember; /* MR1 */
+extern char *OutputDirectory;
+extern char *class_name;
+
+/******************** Functions ******************************/
+#ifdef __USE_PROTOS
+extern char *dlg_malloc(int, char *, int); /* wrapper malloc */
+extern char *dlg_calloc(int, int, char *, int); /* wrapper calloc */
+extern int reach(unsigned *, register int, unsigned *);
+extern set closure(set *, unsigned *);
+extern dfa_node *new_dfa_node(set);
+extern nfa_node *new_nfa_node(void);
+extern dfa_node *dfastate(set);
+extern dfa_node **nfa_to_dfa(nfa_node *);
+extern void internal_error(char *, char *, int); /* MR9 23-Sep-97 */
+extern FILE *read_stream(char *); /* opens file for reading */
+extern FILE *write_stream(char *); /* opens file for writing */
+extern void make_nfa_model_node(void);
+extern void make_dfa_model_node(int);
+extern char *ClassName(char *);
+extern char *OutMetaName(char *);
+extern void error(char*, int);
+extern void warning(char*, int);
+extern void p_head(void);
+extern void p_class_hdr(void);
+extern void p_includes(void);
+extern void p_tables(void);
+extern void p_tail(void); /* MR1 */
+extern void p_class_def1(void); /* MR1 */
+extern void new_automaton_mode(void); /* MR1 */
+extern int relabel(nfa_node *,int); /* MR1 */
+extern void p_shift_table(int); /* MR1 */
+extern void p_bshift_table(void); /* MR1 */
+extern void p_class_table(void); /* MR1 */
+extern void p_mode_def(char *,int); /* MR1 */
+extern void init(void); /* MR1 */
+extern void p_class_def2(void); /* MR1 */
+extern void clear_hash(void); /* MR1 */
+extern void p_alternative_table(void); /* MR1 */
+extern void p_node_table(void); /* MR1 */
+extern void p_dfa_table(void); /* MR1 */
+extern void p_accept_table(void); /* MR1 */
+extern void p_action_table(void); /* MR1 */
+extern void p_base_table(void); /* MR1 */
+extern void p_single_node(int,int); /* MR1 */
+extern char * minsize(int); /* MR1 */
+extern void close1(nfa_node *,int,set *); /* MR1 */
+extern void partition(nfa_node *,int); /* MR1 */
+extern void intersect_nfa_labels(nfa_node *,set *); /* MR1 */
+extern void r_intersect(nfa_node *,set *); /* MR1 */
+extern void label_node(nfa_node *); /* MR1 */
+extern void label_with_classes(nfa_node *); /* MR1 */
+
+#else
+extern char *dlg_malloc(); /* wrapper malloc */
+extern char *dlg_calloc(); /* wrapper calloc */
+extern int reach();
+extern set closure();
+extern dfa_node *new_dfa_node();
+extern nfa_node *new_nfa_node();
+extern dfa_node *dfastate();
+extern dfa_node **nfa_to_dfa();
+extern void internal_error(); /* MR9 23-Sep-97 */
+extern FILE *read_stream(); /* opens file for reading */
+extern FILE *write_stream(); /* opens file for writing */
+extern void make_nfa_model_node();
+extern void make_dfa_model_node();
+extern char *ClassName();
+extern char *OutMetaName();
+extern void error();
+extern void warning();
+extern void p_head(); /* MR9 */
+extern void p_class_hdr(); /* MR9 */
+extern void p_includes(); /* MR9 */
+extern void p_tables(); /* MR9 */
+extern void p_tail(); /* MR1 */
+extern void p_class_def1(); /* MR1 */
+extern void new_automaton_mode(); /* MR1 */
+extern int relabel(); /* MR1 */
+extern void p_shift_table(); /* MR1 */
+extern void p_bshift_table(); /* MR1 */
+extern void p_class_table(); /* MR1 */
+extern void p_mode_def(); /* MR1 */
+extern void init(); /* MR1 */
+extern void p_class_def2(); /* MR1 */
+extern void clear_hash(); /* MR1 */
+extern void p_alternative_table(); /* MR1 */
+extern void p_node_table(); /* MR1 */
+extern void p_dfa_table(); /* MR1 */
+extern void p_accept_table(); /* MR1 */
+extern void p_action_table(); /* MR1 */
+extern void p_base_table(); /* MR1 */
+extern void p_single_node(); /* MR1 */
+extern char * minsize(); /* MR1 */
+extern void close1(); /* MR1 */
+extern void partition(); /* MR1 */
+extern void intersect_nfa_labels(); /* MR1 */
+extern void r_intersect(); /* MR1 */
+extern void label_node(); /* MR1 */
+extern void label_with_classes(); /* MR1 */
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.r b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.r
new file mode 100644
index 00000000..d2348385
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg.r
@@ -0,0 +1,270 @@
+/*
+ File: dlgMPW.r
+ Target: dlg 133MR
+ Created: Monday, June 15, 1998 4:44:11 AM
+ Author: Kenji Tanaka (kentar@osa.att.ne.jp)
+*/
+
+#include "cmdo.r"
+
+resource 'cmdo' (128, "Dlg") {
+ { /* array dialogs: 1 elements */
+ /* [1] */
+ 295,
+ "DLG -- Purdue Compiler Construction Tool"
+ " Set (PCCTS) lexical analyzer generator.",
+ { /* array itemArray: 18 elements */
+ /* [1] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {35, 175, 50, 225},
+ "On",
+ "-CC",
+ "When this control is checked, DLG generates "
+ "a scanner using C++ classes rather than "
+ "C functions."
+ },
+ /* [2] */
+ Or {
+ { /* array OrArray: 1 elements */
+ /* [1] */
+ 1
+ }
+ },
+ RegularEntry {
+ "Lexer Class Name:",
+ {35, 225, 50, 355},
+ {35, 355, 51, 450},
+ "DLGLexer",
+ keepCase,
+ "-cl",
+ "This entry specifies the name DLG uses for the C++ lexer class."
+ },
+ /* [3] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {25, 165, 60, 460},
+ "C++ Code Generation"
+ },
+ /* [4] */
+ NotDependent {
+
+ },
+ Files {
+ InputFile,
+ RequiredFile {
+ {37, 25, 56, 135},
+ "Input File",
+ "",
+ "Choose the lexical description file for "
+ "DLG to process."
+ },
+ Additional {
+ "",
+ "",
+ "",
+ "",
+ { /* array TypesArray: 1 elements */
+ /* [1] */
+ text
+ }
+ }
+ },
+ /* [5] */
+ Or {
+ { /* array OrArray: 1 elements */
+ /* [1] */
+ -1
+ }
+ },
+ Files {
+ OutputFile,
+ RequiredFile {
+ {66, 25, 85, 135},
+ "Output File",
+ "",
+ "Choose the name of the file that will hold the DLG-produced scanner."
+ },
+ NoMore {
+
+ }
+ },
+ /* [6] */
+ Or {
+ { /* array OrArray: 2 elements */
+ /* [1] */
+ 1,
+ /* [2] */
+ 5
+ }
+ },
+ Dummy {
+
+ },
+ /* [7] */
+ NotDependent {
+
+ },
+ Redirection {
+ DiagnosticOutput,
+ {90, 25}
+ },
+ /* [8] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {25, 20, 132, 145},
+ "Files"
+ },
+ /* [9] */
+ NotDependent {
+
+ },
+ Files {
+ DirOnly,
+ OptionalFile {
+ {68, 175, 84, 305},
+ {88, 175, 107, 305},
+ "Output Directory",
+ ":",
+ "-o",
+ "",
+ "Choose the directory where DLG will put "
+ "its output.",
+ dim,
+ "Output DirectoryI",
+ "",
+ ""
+ },
+ NoMore {
+
+ }
+ },
+ /* [10] */
+ NotDependent {
+
+ },
+ RegularEntry {
+ "Mode File Name:",
+ {68, 315, 83, 450},
+ {88, 315, 104, 450},
+ "mode.h",
+ keepCase,
+ "-m",
+ "This entry specifies the name DLG uses for its lexical mode output file."
+ },
+ /* [11] */
+ NotDependent {
+
+ },
+ RadioButtons {
+ { /* array radioArray: 3 elements */
+ /* [1] */
+ {134, 175, 149, 255}, "None", "", Set, "When this option is selected, DLG will not "
+ "compress its tables.",
+ /* [2] */
+ {134, 265, 149, 345}, "Level 1", "-C1", NotSet, "When this option is selected, DLG will "
+ "remove all unused characters from the transition-from table.",
+ /* [3] */
+ {134, 360, 149, 450}, "Level 2", "-C2", NotSet, "When this option is selected, DLG will "
+ "perform level 1 compression plus it will "
+ "map equivalent characters into the same "
+ "character classes."
+ }
+ },
+ /* [12] */
+ NotDependent {
+
+ },
+ TextBox {
+ gray,
+ {124, 165, 156, 460},
+ "Table Compression"
+ },
+ /* [13] */
+ NotDependent {
+
+ },
+ CheckOption {
+ Set,
+ {165, 20, 180, 145},
+ "Case Sensitive",
+ "-ci",
+ "When this control is checked, the DLG automaton "
+ "will treat upper and lower case "
+ "characters identically."
+ },
+ /* [14] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {165, 150, 180, 300},
+ "Interactive Scanner",
+ "-i",
+ "When this control is checked, DLG will generate "
+ "as interactive a scanner as possible."
+ },
+ /* [15] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {165, 310, 180, 460},
+ "Ambiguity Warnings",
+ "-Wambiguity",
+ "When this control is checked, DLG warns "
+ "if more than one regular expression could "
+ "match the same character sequence."
+ },
+ /* [16] */
+ NotDependent {
+
+ },
+ VersionDialog {
+ VersionString {
+ "1.33MR"
+ },
+ "PCCTS was written by Terence Parr, Russell "
+ "Quong, Will Cohen, and Hank Dietz: 1989-1998. "
+ "MPW port by Scott Haney.",
+ noDialog
+ },
+ /* [17] */
+ And {
+ { /* array AndArray: 2 elements */
+ /* [1] */
+ 4,
+ /* [2] */
+ 6
+ }
+ },
+ DoItButton {
+
+ },
+ /* [18] */
+ NotDependent {
+
+ },
+ CheckOption {
+ NotSet,
+ {142, 20, 157, 148},
+ "Generate ANSI C",
+ "-ga",
+ "When this control is checked, DLG generates "
+ "ANSI C compatible code."
+ }
+ }
+ }
+};
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg1.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg1.txt
new file mode 100644
index 00000000..79f6690a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg1.txt
@@ -0,0 +1,132 @@
+
+
+
+dlg(1) PCCTS Manual Pages dlg(1)
+
+
+
+NAME
+ dlg - DFA Lexical Analyzer Generator
+
+SYNTAX
+ dlg [_o_p_t_i_o_n_s] _l_e_x_i_c_a_l__s_p_e_c [_o_u_t_p_u_t__f_i_l_e]
+
+DESCRIPTION
+ dlg is a tool that produces fast deterministic finite auto-
+ mata for recognizing regular expressions in input.
+
+OPTIONS
+ -CC Generate C++ output. The _o_u_t_p_u_t__f_i_l_e is not specified
+ in this case.
+
+ -C[ level]
+ Where level is the compression level used. 0 indica-
+ tions no compression, 1 removes all unused characters
+ from the transition from table, and 2 maps equivalent
+ characters into the same character classes. It is sug-
+ gested that level -C2 is used, since it will signifi-
+ cantly reduce the size of the dfa produced for lexical
+ analyzer.
+
+ -m Produces the header file for the lexical mode with a
+ name other than the default name of "mode.h".
+
+ -i An interactive, or as interactive as possible, parser
+ is produced. A character is only obtained when
+ required to decide which state to go to. Some care
+ must be taken to obtain accept states that do not
+ require look ahead at the next character to determine
+ if that is the stop state. Any regular expression with
+ a Kleene closure at the end is guaranteed to require
+ another character of look ahead.
+
+ -cl class
+ Specify a class name for DLG to generate. The default
+ is DLGLexer.
+
+ -ci The automaton will treat upper and lower case charac-
+ ters identically. This is accomplished in the automa-
+ ton; the characters in the lexical buffer are unmodi-
+ fied.
+
+ -cs Upper and lower case characters are treated as dis-
+ tinct. This is the default.
+
+ -o dir
+ Directory where output files should go (default=".").
+ This is very nice for keeping the source directory
+ clear of ANTLR and DLG spawn.
+
+ -Wambiguity
+ Warns if more than one regular expression could match
+ the same character sequence. The warnings give the
+ numbers of the expressions in the dlg lexical specifi-
+ cation file. The numbering of the expressions starts
+ at one. Multiple warnings may be print for the same
+ expressions.
+
+ - Used in place of file names to get input from standard
+ in or send output to standard out.
+
+SPECIAL CONSIDERATIONS
+ _D_l_g works... we think. There is no implicit guarantee of
+ anything. We reserve no legal rights to the software known
+ as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS
+ is in the public domain. An individual or company may do
+ whatever they wish with source code distributed with PCCTS
+ or the code generated by PCCTS, including the incorporation
+ of PCCTS, or its output, into commercial software. We
+ encourage users to develop software with PCCTS. However, we
+ do ask that credit is given to us for developing PCCTS. By
+ "credit", we mean that if you incorporate our source code
+ into one of your programs (commercial product, research pro-
+ ject, or otherwise) that you acknowledge this fact somewhere
+ in the documentation, research report, etc... If you like
+ PCCTS and have developed a nice tool with the output, please
+ mention that you developed it using PCCTS. As long as these
+ guidelines are followed, we expect to continue enhancing
+ this system and expect to make other tools available as they
+ are completed.
+
+FILES
+ mode.h , dlgauto.h , dlgdef.h
+
+SEE ALSO
+ antlr(1), pccts(1)
+
+BUGS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_a.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_a.c
new file mode 100644
index 00000000..c3d4e7b6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_a.c
@@ -0,0 +1,1414 @@
+
+/* parser.dlg -- DLG Description of scanner
+ *
+ * Generated from: dlg_p.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include <ctype.h>
+#include "dlg.h"
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+LOOKAHEAD
+
+void
+#ifdef __USE_PROTOS
+zzerraction(void)
+#else
+zzerraction()
+#endif
+{
+ (*zzerr)("invalid token");
+ zzadvance();
+ zzskip();
+}
+/*
+ * D L G tables
+ *
+ * Generated from: parser.dlg
+ *
+ * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz
+ * Purdue University Electrical Engineering
+ * DLG Version 1.33MR33
+ */
+
+#include "mode.h"
+
+
+
+
+int func_action; /* should actions be turned into functions?*/
+int lex_mode_counter = 0; /* keeps track of the number of %%names */
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via <<%%lexmember...>> */
+/* MR1 */
+int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */
+int lexAction = 0; /* <<%%lexaction ...>> MR1 */
+int parserClass = 0; /* <<%%parserclass ...>> MR1 */
+int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */
+char theClassName[100]; /* MR11 */
+char *pClassName=theClassName; /* MR11 */
+int firstLexMember=1; /* MR1 */
+
+#ifdef __USE_PROTOS
+void xxputc(int c) { /* MR1 */
+#else
+ void xxputc(c) /* MR1 */
+ int c; /* MR1 */
+ { /* MR1 */
+#endif
+ if (parserClass) { /* MR1 */
+ *pClassName++=c; /* MR1 */
+ *pClassName=0; /* MR1 */
+ } else if (lexMember || lexPrefix) { /* MR1 */
+ if (class_stream != NULL) fputc(c,class_stream); /* MR1 */
+ } else { /* MR1 */
+ fputc(c,OUT); /* MR1 */
+ }; /* MR1 */
+ } /* MR1 */
+
+#ifdef __USE_PROTOS
+ void xxprintf(char *format,char *string) { /* MR1 */
+#else
+ void xxprintf(format,string) /* MR1 */
+ char *format; /* MR1 */
+ char *string; /* MR1 */
+ { /* MR1 */
+#endif
+ if (lexMember || lexPrefix || parserClass) { /* MR1 */
+ if (class_stream != NULL) /* MR1 */
+ fprintf(class_stream,format,string); /* MR1 */
+ } else { /* MR1 */
+ fprintf(OUT,format,string); /* MR1 */
+ }; /* MR1 */
+ } /* MR1 */
+
+static void act1()
+{
+ NLA = 1;
+ }
+
+
+static void act2()
+{
+ NLA = 2;
+ zzskip();
+ }
+
+
+static void act3()
+{
+ NLA = 3;
+ zzline++; zzskip(); DAWDLE;
+ }
+
+
+static void act4()
+{
+ NLA = L_EOF;
+ }
+
+
+static void act5()
+{
+ NLA = PER_PER;
+ }
+
+
+static void act6()
+{
+ NLA = NAME_PER_PER;
+ p_mode_def(&zzlextext[2],lex_mode_counter++);
+ }
+
+
+static void act7()
+{
+ NLA = LEXMEMBER;
+ lexMember=1; /* MR1 */
+ if (firstLexMember != 0) { /* MR1 */
+ firstLexMember=0; /* MR1 */
+ p_class_def1(); /* MR1 */
+ }; /* MR1 */
+ zzmode(ACT); /* MR1 */
+ }
+
+
+static void act8()
+{
+ NLA = LEXACTION;
+ lexAction=1;zzmode(ACT);
+ }
+
+
+static void act9()
+{
+ NLA = PARSERCLASS;
+ parserClass=1; /* MR1 */
+ zzmode(ACT); /* MR1 */
+ }
+
+
+static void act10()
+{
+ NLA = LEXPREFIX;
+ lexPrefix=1;zzmode(ACT);
+ }
+
+
+static void act11()
+{
+ NLA = ACTION;
+ if (func_action)
+ fprintf(OUT,"\n%s %sact%d()\n{ ",
+ gen_cpp?"ANTLRTokenType":"static void",
+ gen_cpp?ClassName("::"):"", ++action_no);
+ zzmode(ACT); zzskip();
+ }
+
+
+static void act12()
+{
+ NLA = GREAT_GREAT;
+ }
+
+
+static void act13()
+{
+ NLA = L_BRACE;
+ }
+
+
+static void act14()
+{
+ NLA = R_BRACE;
+ }
+
+
+static void act15()
+{
+ NLA = L_PAR;
+ }
+
+
+static void act16()
+{
+ NLA = R_PAR;
+ }
+
+
+static void act17()
+{
+ NLA = L_BRACK;
+ }
+
+
+static void act18()
+{
+ NLA = R_BRACK;
+ }
+
+
+static void act19()
+{
+ NLA = ZERO_MORE;
+ }
+
+
+static void act20()
+{
+ NLA = ONE_MORE;
+ }
+
+
+static void act21()
+{
+ NLA = OR;
+ }
+
+
+static void act22()
+{
+ NLA = RANGE;
+ }
+
+
+static void act23()
+{
+ NLA = NOT;
+ }
+
+
+static void act24()
+{
+ NLA = OCTAL_VALUE;
+ {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}
+ }
+
+
+static void act25()
+{
+ NLA = HEX_VALUE;
+ {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}
+ }
+
+
+static void act26()
+{
+ NLA = DEC_VALUE;
+ {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}
+ }
+
+
+static void act27()
+{
+ NLA = TAB;
+ zzlextext[0] = '\t';
+ }
+
+
+static void act28()
+{
+ NLA = NL;
+ zzlextext[0] = '\n';
+ }
+
+
+static void act29()
+{
+ NLA = CR;
+ zzlextext[0] = '\r';
+ }
+
+
+static void act30()
+{
+ NLA = BS;
+ zzlextext[0] = '\b';
+ }
+
+
+static void act31()
+{
+ NLA = CONTINUATION;
+ zzline++; zzskip();
+ }
+
+
+static void act32()
+{
+ NLA = LIT;
+ zzlextext[0] = zzlextext[1];
+ }
+
+
+static void act33()
+{
+ NLA = REGCHAR;
+ }
+
+static unsigned char shift0[257] = {
+ 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 1, 2, 40, 40, 1, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 1, 40, 40, 40, 40, 4, 40,
+ 40, 30, 31, 34, 35, 40, 37, 40, 40, 23,
+ 24, 24, 24, 24, 24, 24, 24, 25, 25, 40,
+ 40, 26, 40, 27, 40, 3, 21, 21, 21, 21,
+ 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 20,
+ 22, 22, 32, 39, 33, 40, 22, 40, 11, 9,
+ 12, 21, 6, 19, 22, 22, 14, 22, 22, 5,
+ 8, 16, 15, 17, 22, 10, 18, 13, 22, 22,
+ 22, 7, 22, 22, 28, 36, 29, 38, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40
+};
+
+
+static void act34()
+{
+ NLA = 1;
+ error("unterminated action", zzline); zzmode(START);
+ }
+
+
+static void act35()
+{
+ NLA = ACTION;
+ if (func_action) fprintf(OUT,"}\n\n");
+ zzmode(START);
+ /* MR1 */
+ /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+ /* MR1 via <<%%lexmember ...>> */
+ /* MR1 This is a consequence of not saving actions */
+ /* MR1 */
+ /* MR1 */ parserClass=0;
+ /* MR1 */ lexPrefix=0;
+ /* MR1 */ lexAction=0;
+ /* MR1 */ lexMember=0;
+ }
+
+
+static void act36()
+{
+ NLA = 34;
+ xxputc(zzlextext[0]); zzskip();
+ }
+
+
+static void act37()
+{
+ NLA = 35;
+ xxputc('>'); zzskip();
+ }
+
+
+static void act38()
+{
+ NLA = 36;
+ xxputc('\\'); zzskip();
+ }
+
+
+static void act39()
+{
+ NLA = 37;
+ xxputc(zzlextext[0]); ++zzline; zzskip();
+ }
+
+
+static void act40()
+{
+ NLA = 38;
+ zzmode(ACTION_COMMENTS); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ }
+
+
+static void act41()
+{
+ NLA = 39;
+ zzmode(ACTION_CPP_COMMENTS); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ }
+
+
+static void act42()
+{
+ NLA = 40;
+ xxputc(zzlextext[0]); zzskip();
+ }
+
+static unsigned char shift1[257] = {
+ 0, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 3, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 5, 6, 6, 6, 6, 4, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 1, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 2, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6
+};
+
+
+static void act43()
+{
+ NLA = 1;
+ }
+
+
+static void act44()
+{
+ NLA = 41;
+ zzmode(ACT); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ }
+
+
+static void act45()
+{
+ NLA = 42;
+ zzline++; xxputc(zzlextext[0]); zzskip();
+ }
+
+
+static void act46()
+{
+ NLA = 43;
+ xxputc(zzlextext[0]); zzskip();
+ }
+
+static unsigned char shift2[257] = {
+ 0, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 3, 4, 4, 3, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 1, 4, 4, 4, 4, 2, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4
+};
+
+
+static void act47()
+{
+ NLA = 1;
+ }
+
+
+static void act48()
+{
+ NLA = 44;
+ zzmode(ACT); zzline++; /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ }
+
+
+static void act49()
+{
+ NLA = 45;
+ xxputc(zzlextext[0]); zzskip();
+ }
+
+static unsigned char shift3[257] = {
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 1, 2, 2, 1, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2
+};
+
+#define DfaStates 94
+typedef unsigned char DfaState;
+
+static DfaState st0[42] = {
+ 1, 2, 3, 4, 5, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 6, 94
+};
+
+static DfaState st1[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st2[42] = {
+ 94, 21, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st3[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st4[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st5[42] = {
+ 94, 94, 94, 94, 22, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st6[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st7[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 23, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st8[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 24, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st9[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st10[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st11[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st12[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st13[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st14[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st15[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st16[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st17[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st18[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st19[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st20[42] = {
+ 94, 25, 26, 25, 25, 25, 25, 25, 25, 27,
+ 28, 25, 25, 29, 25, 25, 30, 25, 25, 25,
+ 25, 25, 25, 31, 32, 32, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 94
+};
+
+static DfaState st21[42] = {
+ 94, 21, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st22[42] = {
+ 94, 94, 94, 94, 94, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st23[42] = {
+ 94, 94, 94, 94, 34, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st24[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st25[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st26[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st27[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st28[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st29[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st30[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st31[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 35, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 35, 94, 94, 36, 36, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st32[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 37, 37, 37, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st33[42] = {
+ 94, 94, 94, 94, 94, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st34[42] = {
+ 94, 94, 94, 94, 39, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st35[42] = {
+ 94, 94, 94, 94, 94, 94, 40, 94, 94, 40,
+ 94, 40, 40, 94, 94, 94, 94, 94, 94, 40,
+ 94, 40, 94, 40, 40, 40, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st36[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 36, 36, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st37[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 37, 37, 37, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st38[42] = {
+ 94, 94, 94, 94, 94, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st39[42] = {
+ 94, 94, 94, 94, 94, 41, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 42, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st40[42] = {
+ 94, 94, 94, 94, 94, 94, 40, 94, 94, 40,
+ 94, 40, 40, 94, 94, 94, 94, 94, 94, 40,
+ 94, 40, 94, 40, 40, 40, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st41[42] = {
+ 94, 94, 94, 94, 94, 94, 43, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st42[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 44, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st43[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 45, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st44[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 46, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st45[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 47, 94,
+ 94, 48, 94, 94, 94, 94, 94, 49, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st46[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 50, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st47[42] = {
+ 94, 94, 94, 94, 94, 94, 51, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st48[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 52, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st49[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 53, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st50[42] = {
+ 94, 94, 94, 94, 94, 94, 54, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st51[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 55, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st52[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 56, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st53[42] = {
+ 94, 94, 94, 94, 94, 94, 57, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st54[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 58, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st55[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 59,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st56[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 60, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st57[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 61,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st58[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 62, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st59[42] = {
+ 94, 94, 94, 94, 94, 94, 63, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st60[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 64, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st61[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 65, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st62[42] = {
+ 94, 94, 94, 94, 94, 66, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st63[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 67, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st64[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 68, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st65[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 69, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st66[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 70, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st67[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st68[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st69[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st70[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 71, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st71[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 72, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st72[42] = {
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94
+};
+
+static DfaState st73[8] = {
+ 74, 75, 76, 77, 78, 79, 79, 94
+};
+
+static DfaState st74[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st75[8] = {
+ 94, 80, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st76[8] = {
+ 94, 81, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st77[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st78[8] = {
+ 94, 94, 94, 94, 82, 83, 94, 94
+};
+
+static DfaState st79[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st80[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st81[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st82[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st83[8] = {
+ 94, 94, 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st84[6] = {
+ 85, 86, 87, 88, 87, 94
+};
+
+static DfaState st85[6] = {
+ 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st86[6] = {
+ 94, 94, 89, 94, 94, 94
+};
+
+static DfaState st87[6] = {
+ 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st88[6] = {
+ 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st89[6] = {
+ 94, 94, 94, 94, 94, 94
+};
+
+static DfaState st90[4] = {
+ 91, 92, 93, 94
+};
+
+static DfaState st91[4] = {
+ 94, 94, 94, 94
+};
+
+static DfaState st92[4] = {
+ 94, 94, 94, 94
+};
+
+static DfaState st93[4] = {
+ 94, 94, 94, 94
+};
+
+
+DfaState *dfa[94] = {
+ st0,
+ st1,
+ st2,
+ st3,
+ st4,
+ st5,
+ st6,
+ st7,
+ st8,
+ st9,
+ st10,
+ st11,
+ st12,
+ st13,
+ st14,
+ st15,
+ st16,
+ st17,
+ st18,
+ st19,
+ st20,
+ st21,
+ st22,
+ st23,
+ st24,
+ st25,
+ st26,
+ st27,
+ st28,
+ st29,
+ st30,
+ st31,
+ st32,
+ st33,
+ st34,
+ st35,
+ st36,
+ st37,
+ st38,
+ st39,
+ st40,
+ st41,
+ st42,
+ st43,
+ st44,
+ st45,
+ st46,
+ st47,
+ st48,
+ st49,
+ st50,
+ st51,
+ st52,
+ st53,
+ st54,
+ st55,
+ st56,
+ st57,
+ st58,
+ st59,
+ st60,
+ st61,
+ st62,
+ st63,
+ st64,
+ st65,
+ st66,
+ st67,
+ st68,
+ st69,
+ st70,
+ st71,
+ st72,
+ st73,
+ st74,
+ st75,
+ st76,
+ st77,
+ st78,
+ st79,
+ st80,
+ st81,
+ st82,
+ st83,
+ st84,
+ st85,
+ st86,
+ st87,
+ st88,
+ st89,
+ st90,
+ st91,
+ st92,
+ st93
+};
+
+
+DfaState accepts[95] = {
+ 0, 1, 2, 3, 4, 33, 33, 33, 33, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 0, 2, 5, 11, 12, 32, 31, 30, 29, 27,
+ 28, 24, 26, 6, 0, 0, 24, 26, 6, 0,
+ 25, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 8, 10,
+ 0, 0, 9, 0, 34, 36, 38, 39, 42, 42,
+ 35, 37, 41, 40, 0, 43, 46, 46, 45, 44,
+ 0, 47, 48, 49, 0
+};
+
+void (*actions[50])() = {
+ zzerraction,
+ act1,
+ act2,
+ act3,
+ act4,
+ act5,
+ act6,
+ act7,
+ act8,
+ act9,
+ act10,
+ act11,
+ act12,
+ act13,
+ act14,
+ act15,
+ act16,
+ act17,
+ act18,
+ act19,
+ act20,
+ act21,
+ act22,
+ act23,
+ act24,
+ act25,
+ act26,
+ act27,
+ act28,
+ act29,
+ act30,
+ act31,
+ act32,
+ act33,
+ act34,
+ act35,
+ act36,
+ act37,
+ act38,
+ act39,
+ act40,
+ act41,
+ act42,
+ act43,
+ act44,
+ act45,
+ act46,
+ act47,
+ act48,
+ act49
+};
+
+static DfaState dfa_base[] = {
+ 0,
+ 73,
+ 84,
+ 90
+};
+
+static unsigned char *b_class_no[] = {
+ shift0,
+ shift1,
+ shift2,
+ shift3
+};
+
+
+
+#define ZZSHIFT(c) (b_class_no[zzauto][1+c])
+#define MAX_MODE 4
+#include "dlgauto.h"
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.c
new file mode 100644
index 00000000..d689afa0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.c
@@ -0,0 +1,970 @@
+/*
+ * A n t l r T r a n s l a t i o n H e a d e r
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ *
+ * ..\bin\antlr dlg_p.g -gh
+ *
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include <ctype.h>
+#include "dlg.h"
+#define zzSET_SIZE 8
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "mode.h"
+
+/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */
+
+#ifndef PCCTS_PURIFY
+#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s));
+#endif
+
+ANTLR_INFO
+
+
+/* MR20 G. Hobbelt
+Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled
+*/
+
+#ifdef __TURBOC__
+#pragma warn -aus /* unused assignment of 'xxx' */
+#endif
+
+#ifdef VBOX
+# ifdef _MSC_VER
+# pragma warning(disable : 4068) /* Unguarded '#pragma clang' below */
+# endif
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wunknown-pragmas"
+# endif
+#endif
+
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+
+int action_no = 0; /* keep track of actions outputted */
+int nfa_allocated = 0; /* keeps track of number of nfa nodes */
+nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */
+nfa_node nfa_model_node; /* model to initialize new nodes */
+set used_chars; /* used to label trans. arcs */
+set used_classes; /* classes or chars used to label trans. arcs */
+set normal_chars; /* mask to get rid elements that aren't used
+in set */
+int flag_paren = FALSE;
+int flag_brace = FALSE;
+int mode_counter = 0; /* keep track of number of %%names */
+
+
+
+void
+#ifdef __USE_PROTOS
+grammar(void)
+#else
+grammar()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ p_head(); p_class_hdr(); func_action = FALSE;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (setwd1[LA(1)]&0x1) ) {
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ if ( (LA(1)==LEXACTION) ) {
+ zzmatch(LEXACTION); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==LEXMEMBER) ) {
+ zzmatch(LEXMEMBER); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==LEXPREFIX) ) {
+ zzmatch(LEXPREFIX); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==PARSERCLASS) ) {
+ zzmatch(PARSERCLASS); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==ACTION) ) {
+ }
+ else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ }
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ zzmatch(ACTION); zzCONSUME;
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ if ( gen_cpp ) p_includes();
+ start_states();
+ func_action = FALSE; p_tables(); p_tail();
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==ACTION) ) {
+ zzmatch(ACTION); zzCONSUME;
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(1);
+ if (firstLexMember != 0) p_class_def1();
+ zzCONSUME;
+
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x2);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+start_states(void)
+#else
+start_states()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==PER_PER) ) {
+ zzmatch(PER_PER); zzCONSUME;
+ do_conversion();
+ }
+ else {
+ if ( (LA(1)==NAME_PER_PER) ) {
+ zzmatch(NAME_PER_PER); zzCONSUME;
+ do_conversion();
+ {
+ zzBLOCK(zztasp3);
+ zzMake0;
+ {
+ while ( (LA(1)==NAME_PER_PER) ) {
+ zzmatch(NAME_PER_PER); zzCONSUME;
+ do_conversion();
+ zzLOOP(zztasp3);
+ }
+ zzEXIT(zztasp3);
+ }
+ }
+ }
+ else {zzFAIL(1,zzerr2,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzmatch(PER_PER); zzCONSUME;
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x4);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+do_conversion(void)
+#else
+do_conversion()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ new_automaton_mode(); func_action = TRUE;
+ rule_list();
+
+ dfa_class_nop[mode_counter] =
+ relabel(zzaArg(zztasp1,1 ).l,comp_level);
+ if (comp_level)
+ p_shift_table(mode_counter);
+ dfa_basep[mode_counter] = dfa_allocated+1;
+ make_dfa_model_node(dfa_class_nop[mode_counter]);
+ nfa_to_dfa(zzaArg(zztasp1,1 ).l);
+ ++mode_counter;
+ func_action = FALSE;
+#ifdef HASH_STAT
+ fprint_hash_stats(stderr);
+#endif
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x8);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+rule_list(void)
+#else
+rule_list()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (setwd1[LA(1)]&0x10) ) {
+ rule();
+ zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (setwd1[LA(1)]&0x20) ) {
+ rule();
+ {nfa_node *t1;
+ t1 = new_nfa_node();
+ (t1)->trans[0]=zzaRet.l;
+ (t1)->trans[1]=zzaArg(zztasp2,1 ).l;
+ /* all accept nodes "dead ends" */
+ zzaRet.l=t1; zzaRet.r=NULL;
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ }
+ else {
+ if ( (setwd1[LA(1)]&0x40) ) {
+ zzaRet.l = new_nfa_node(); zzaRet.r = NULL;
+ warning("no regular expressions", zzline);
+ }
+ else {zzFAIL(1,zzerr3,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x80);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+rule(void)
+#else
+rule()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (setwd2[LA(1)]&0x1) ) {
+ reg_expr();
+ zzmatch(ACTION);
+ if (zzaArg(zztasp1,1 ).r != NULL) {
+ zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; (zzaArg(zztasp1,1 ).r)->accept=action_no;
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==ACTION) ) {
+ zzmatch(ACTION);
+ zzaRet.l = NULL; zzaRet.r = NULL;
+ error("no expression for action ", zzline);
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x2);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+reg_expr(void)
+#else
+reg_expr()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ and_expr();
+ zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==OR) ) {
+ zzmatch(OR); zzCONSUME;
+ and_expr();
+ {nfa_node *t1, *t2;
+ t1 = new_nfa_node(); t2 = new_nfa_node();
+ (t1)->trans[0]=zzaRet.l;
+ (t1)->trans[1]=zzaArg(zztasp2,2 ).l;
+ /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2;
+ if (zzaArg(zztasp2,2 ).r) {
+ (zzaArg(zztasp2,2 ).r)->trans[1]=t2; /* MR20 */
+ }
+ zzaRet.l=t1; zzaRet.r=t2;
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x4);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+and_expr(void)
+#else
+and_expr()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ repeat_expr();
+
+ zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (setwd2[LA(1)]&0x8) ) {
+ repeat_expr();
+ if (zzaRet.r != NULL) {
+ (zzaRet.r)->trans[1]=zzaArg(zztasp2,1 ).l;
+ zzaRet.r=zzaArg(zztasp2,1 ).r;
+ }
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x10);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+repeat_expr(void)
+#else
+repeat_expr()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (setwd2[LA(1)]&0x20) ) {
+ expr();
+ zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==ZERO_MORE) ) {
+ zzmatch(ZERO_MORE);
+ { nfa_node *t1,*t2;
+ /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l;
+ t1 = new_nfa_node(); t2 = new_nfa_node();
+ t1->trans[0]=zzaRet.l;
+ t1->trans[1]=t2;
+ /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2;
+ zzaRet.l=t1;zzaRet.r=t2;
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==ONE_MORE) ) {
+ zzmatch(ONE_MORE);
+ if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd2[LA(1)]&0x40) ) {
+ }
+ else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==ZERO_MORE) ) {
+ zzmatch(ZERO_MORE);
+ error("no expression for *", zzline);
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==ONE_MORE) ) {
+ zzmatch(ONE_MORE);
+ error("no expression for +", zzline);
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x80);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+expr(void)
+#else
+expr()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ zzaRet.l = new_nfa_node();
+ zzaRet.r = new_nfa_node();
+ if ( (LA(1)==L_BRACK) ) {
+ zzmatch(L_BRACK); zzCONSUME;
+ atom_list();
+ zzmatch(R_BRACK);
+
+ /* MR23 */ if (zzaRet.l != NULL) {
+ (zzaRet.l)->trans[0] = zzaRet.r;
+ (zzaRet.l)->label = set_dup(zzaArg(zztasp1,2 ).label);
+ set_orin(&used_chars,(zzaRet.l)->label);
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==NOT) ) {
+ zzmatch(NOT); zzCONSUME;
+ zzmatch(L_BRACK); zzCONSUME;
+ atom_list();
+ zzmatch(R_BRACK);
+
+ /* MR23 */ if (zzaRet.l != NULL) {
+ (zzaRet.l)->trans[0] = zzaRet.r;
+ (zzaRet.l)->label = set_dif(normal_chars,zzaArg(zztasp1,3 ).label);
+ set_orin(&used_chars,(zzaRet.l)->label);
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==L_PAR) ) {
+ zzmatch(L_PAR); zzCONSUME;
+ reg_expr();
+ zzmatch(R_PAR);
+
+ /* MR23 */ if (zzaRet.l != NULL) {
+ (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l;
+ if (zzaArg(zztasp1,2 ).r) {
+ (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r; /* MR20 */
+ }
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==L_BRACE) ) {
+ zzmatch(L_BRACE); zzCONSUME;
+ reg_expr();
+ zzmatch(R_BRACE);
+
+ /* MR23 */ if (zzaRet.l != NULL) {
+ (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l;
+ (zzaRet.l)->trans[1] = zzaRet.r;
+ if (zzaArg(zztasp1,2 ).r) {
+ (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r; /* MR20 */
+ }
+ }
+ zzCONSUME;
+
+ }
+ else {
+ if ( (setwd3[LA(1)]&0x1) ) {
+ atom();
+
+ /* MR23 */ if (zzaRet.l != NULL) {
+ (zzaRet.l)->trans[0] = zzaRet.r;
+ (zzaRet.l)->label = set_dup(zzaArg(zztasp1,1 ).label);
+ set_orin(&used_chars,(zzaRet.l)->label);
+ }
+ }
+ else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x2);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+atom_list(void)
+#else
+atom_list()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ set_free(zzaRet.label);
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (setwd3[LA(1)]&0x4) ) {
+ near_atom();
+ set_orin(&(zzaRet.label),zzaArg(zztasp2,1 ).label);
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x8);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+near_atom(void)
+#else
+near_atom()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ register int i;
+ register int i_prime;
+ anychar();
+ zzaRet.letter=zzaArg(zztasp1,1 ).letter; zzaRet.label=set_of(zzaArg(zztasp1,1 ).letter);
+ i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR;
+ if (case_insensitive && islower(i_prime))
+ set_orel(toupper(i_prime)-MIN_CHAR,
+ &(zzaRet.label));
+ if (case_insensitive && isupper(i_prime))
+ set_orel(tolower(i_prime)-MIN_CHAR,
+ &(zzaRet.label));
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==RANGE) ) {
+ zzmatch(RANGE); zzCONSUME;
+ anychar();
+ if (case_insensitive){
+ i_prime = zzaRet.letter+MIN_CHAR;
+ zzaRet.letter = (islower(i_prime) ?
+ toupper(i_prime) : i_prime)-MIN_CHAR;
+ i_prime = zzaArg(zztasp2,2 ).letter+MIN_CHAR;
+ zzaArg(zztasp2,2 ).letter = (islower(i_prime) ?
+ toupper(i_prime) : i_prime)-MIN_CHAR;
+ }
+ /* check to see if range okay */
+ {
+ int debugLetter1 = zzaRet.letter;
+ int debugLetter2 = zzaArg(zztasp2,2 ).letter;
+ }
+ if (zzaRet.letter > zzaArg(zztasp2,2 ).letter
+ && zzaArg(zztasp2,2 ).letter != 0xff){ /* MR16 */
+ error("invalid range ", zzline);
+ }
+ for (i=zzaRet.letter; i<= (int)zzaArg(zztasp2,2 ).letter; ++i){
+ set_orel(i,&(zzaRet.label));
+ i_prime = i+MIN_CHAR;
+ if (case_insensitive && islower(i_prime))
+ set_orel(toupper(i_prime)-MIN_CHAR,
+ &(zzaRet.label));
+ if (case_insensitive && isupper(i_prime))
+ set_orel(tolower(i_prime)-MIN_CHAR,
+ &(zzaRet.label));
+ }
+ }
+ else {
+ if ( (setwd3[LA(1)]&0x10) ) {
+ }
+ else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x20);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+atom(void)
+#else
+atom()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ register int i_prime;
+ anychar();
+ zzaRet.label = set_of(zzaArg(zztasp1,1 ).letter);
+ i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR;
+ if (case_insensitive && islower(i_prime))
+ set_orel(toupper(i_prime)-MIN_CHAR,
+ &(zzaRet.label));
+ if (case_insensitive && isupper(i_prime))
+ set_orel(tolower(i_prime)-MIN_CHAR,
+ &(zzaRet.label));
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x40);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+anychar(void)
+#else
+anychar()
+#endif
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (LA(1)==REGCHAR) ) {
+ zzmatch(REGCHAR);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==OCTAL_VALUE) ) {
+ zzmatch(OCTAL_VALUE);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==HEX_VALUE) ) {
+ zzmatch(HEX_VALUE);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==DEC_VALUE) ) {
+ zzmatch(DEC_VALUE);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==TAB) ) {
+ zzmatch(TAB);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==NL) ) {
+ zzmatch(NL);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==CR) ) {
+ zzmatch(CR);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==BS) ) {
+ zzmatch(BS);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==LIT) ) {
+ zzmatch(LIT);
+ zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==L_EOF) ) {
+ zzmatch(L_EOF);
+ zzaRet.letter = 0;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ /* empty action */
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd3, 0x80);
+ }
+}
+
+/* adds a new nfa to the binary tree and returns a pointer to it */
+nfa_node *
+#ifdef __USE_PROTOS
+new_nfa_node(void)
+#else
+new_nfa_node()
+#endif
+{
+ register nfa_node *t;
+ static int nfa_size=0; /* elements nfa_array[] can hold */
+
+ ++nfa_allocated;
+ if (nfa_size<=nfa_allocated){
+ /* need to redo array */
+ if (!nfa_array){
+ /* need some to do initial allocation */
+ nfa_size=nfa_allocated+NFA_MIN;
+ nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)*
+ nfa_size);
+ }else{
+ /* need more space */
+ nfa_size=2*(nfa_allocated+1);
+ nfa_array=(nfa_node **) realloc(nfa_array,
+ sizeof(nfa_node*)*nfa_size);
+ }
+ }
+ /* fill out entry in array */
+ t = (nfa_node*) malloc(sizeof(nfa_node));
+ nfa_array[nfa_allocated] = t;
+ *t = nfa_model_node;
+ t->node_no = nfa_allocated;
+ return t;
+}
+
+
+/* initialize the model node used to fill in newly made nfa_nodes */
+void
+#ifdef __USE_PROTOS
+make_nfa_model_node(void)
+#else
+make_nfa_model_node()
+#endif
+{
+ nfa_model_node.node_no = -1; /* impossible value for real nfa node */
+ nfa_model_node.nfa_set = 0;
+ nfa_model_node.accept = 0; /* error state default*/
+ nfa_model_node.trans[0] = NULL;
+ nfa_model_node.trans[1] = NULL;
+ nfa_model_node.label = empty;
+}
+
+#if defined(DEBUG) || defined(_DEBUG)
+
+/* print out the pointer value and the node_number */
+void
+#ifdef __USE_PROTOS
+fprint_dfa_pair(FILE *f, nfa_node *p)
+#else
+fprint_dfa_pair(f, p)
+FILE *f;
+nfa_node *p;
+#endif
+{
+ if (p){
+ fprintf(f, "%x (%d)", p, p->node_no);
+ }else{
+ fprintf(f, "(nil)");
+ }
+}
+
+/* print out interest information on a set */
+void
+#ifdef __USE_PROTOS
+fprint_set(FILE *f, set s)
+#else
+fprint_set(f,s)
+FILE *f;
+set s;
+#endif
+{
+ unsigned int *x;
+
+ fprintf(f, "n = %d,", s.n);
+ if (s.setword){
+ fprintf(f, "setword = %x, ", s.setword);
+ /* print out all the elements in the set */
+ x = set_pdq(s);
+ while (*x!=nil){
+ fprintf(f, "%d ", *x);
+ ++x;
+ }
+ }else{
+ fprintf(f, "setword = (nil)");
+ }
+}
+
+/* code to be able to dump out the nfas
+return 0 if okay dump
+return 1 if screwed up
+*/
+int
+#ifdef __USE_PROTOS
+dump_nfas(int first_node, int last_node)
+#else
+dump_nfas(first_node, last_node)
+int first_node;
+int last_node;
+#endif
+{
+ register int i;
+ nfa_node *t;
+
+ for (i=first_node; i<=last_node; ++i){
+ t = NFA(i);
+ if (!t) break;
+ fprintf(stderr, "nfa_node %d {\n", t->node_no);
+ fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set);
+ fprintf(stderr, "\taccept\t=\t%d\n", t->accept);
+ fprintf(stderr, "\ttrans\t=\t(");
+ fprint_dfa_pair(stderr, t->trans[0]);
+ fprintf(stderr, ",");
+ fprint_dfa_pair(stderr, t->trans[1]);
+ fprintf(stderr, ")\n");
+ fprintf(stderr, "\tlabel\t=\t{ ");
+ fprint_set(stderr, t->label);
+ fprintf(stderr, "\t}\n");
+ fprintf(stderr, "}\n\n");
+ }
+ return 0;
+}
+#endif
+
+/* DLG-specific syntax error message generator
+* (define USER_ZZSYN when compiling so don't get 2 definitions)
+*/
+void
+#ifdef __USE_PROTOS
+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)
+#else
+zzsyn(text, tok, egroup, eset, etok, k, bad_text)
+char *text, *egroup, *bad_text;
+int tok;
+int etok;
+int k;
+SetWordType *eset;
+#endif
+{
+fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline);
+fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);
+if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
+if ( k==1 ) fprintf(stderr, " missing");
+else
+{
+fprintf(stderr, "; \"%s\" not", bad_text);
+if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
+}
+if ( zzset_deg(eset)>0 ) zzedecode(eset);
+else fprintf(stderr, " %s", zztokens[etok]);
+if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);
+fprintf(stderr, "\n");
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.g b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.g
new file mode 100644
index 00000000..10154fb5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/dlg_p.g
@@ -0,0 +1,616 @@
+/* This is the parser for the dlg
+ * This is a part of the Purdue Compiler Construction Tool Set
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#header <<
+#include <ctype.h>
+#include "dlg.h"
+>>
+
+<<
+
+/* MR20 G. Hobbelt
+ Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled
+*/
+
+#ifdef __TURBOC__
+#pragma warn -aus /* unused assignment of 'xxx' */
+#endif
+
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+
+int action_no = 0; /* keep track of actions outputted */
+int nfa_allocated = 0; /* keeps track of number of nfa nodes */
+nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */
+nfa_node nfa_model_node; /* model to initialize new nodes */
+set used_chars; /* used to label trans. arcs */
+set used_classes; /* classes or chars used to label trans. arcs */
+set normal_chars; /* mask to get rid elements that aren't used
+ in set */
+int flag_paren = FALSE;
+int flag_brace = FALSE;
+int mode_counter = 0; /* keep track of number of %%names */
+
+>>
+
+#lexaction <<
+int func_action; /* should actions be turned into functions?*/
+int lex_mode_counter = 0; /* keeps track of the number of %%names */
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via <<%%lexmember...>> */
+/* MR1 */
+int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */
+int lexAction = 0; /* <<%%lexaction ...>> MR1 */
+int parserClass = 0; /* <<%%parserclass ...>> MR1 */
+int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */
+char theClassName[100]; /* MR11 */
+char *pClassName=theClassName; /* MR11 */
+int firstLexMember=1; /* MR1 */
+
+#ifdef __USE_PROTOS
+void xxputc(int c) { /* MR1 */
+#else
+void xxputc(c) /* MR1 */
+ int c; /* MR1 */
+{ /* MR1 */
+#endif
+ if (parserClass) { /* MR1 */
+ *pClassName++=c; /* MR1 */
+ *pClassName=0; /* MR1 */
+ } else if (lexMember || lexPrefix) { /* MR1 */
+ if (class_stream != NULL) fputc(c,class_stream); /* MR1 */
+ } else { /* MR1 */
+ fputc(c,OUT); /* MR1 */
+ }; /* MR1 */
+} /* MR1 */
+
+#ifdef __USE_PROTOS
+void xxprintf(char *format,char *string) { /* MR1 */
+#else
+void xxprintf(format,string) /* MR1 */
+ char *format; /* MR1 */
+ char *string; /* MR1 */
+{ /* MR1 */
+#endif
+ if (lexMember || lexPrefix || parserClass) { /* MR1 */
+ if (class_stream != NULL) /* MR1 */
+ fprintf(class_stream,format,string); /* MR1 */
+ } else { /* MR1 */
+ fprintf(OUT,format,string); /* MR1 */
+ }; /* MR1 */
+} /* MR1 */
+>>
+
+#token "[\r\t\ ]+" << zzskip(); >> /* Ignore white */
+#token "\n" << zzline++; zzskip(); DAWDLE; >> /* Track Line # */
+#token L_EOF "\@"
+#token PER_PER "\%\%"
+#token NAME_PER_PER "\%\%[a-zA-Z_][a-zA-Z0-9_]*"
+ << p_mode_def(&zzlextext[2],lex_mode_counter++); >>
+
+#token LEXMEMBER "\<\<\%\%lexmember" /* MR1 */
+ <<lexMember=1; /* MR1 */
+ if (firstLexMember != 0) { /* MR1 */
+ firstLexMember=0; /* MR1 */
+ p_class_def1(); /* MR1 */
+ }; /* MR1 */
+ zzmode(ACT); /* MR1 */
+ >> /* MR1 */
+#token LEXACTION "\<\<\%\%lexaction" /* MR1 */
+ <<lexAction=1;zzmode(ACT);>> /* MR1 */
+#token PARSERCLASS "\<\<\%\%parserclass" /* MR1 */
+ <<parserClass=1; /* MR1 */
+ zzmode(ACT); /* MR1 */
+ >> /* MR1 */
+#token LEXPREFIX "\<\<\%\%lexprefix" /* MR1 */
+ <<lexPrefix=1;zzmode(ACT);>> /* MR1 */
+
+#token ACTION "\<\<"
+ << if (func_action)
+ fprintf(OUT,"\n%s %sact%d()\n{ ",
+ gen_cpp?"ANTLRTokenType":"static void",
+ gen_cpp?ClassName("::"):"", ++action_no);
+ zzmode(ACT); zzskip();
+ >>
+#token GREAT_GREAT "\>\>"
+#token L_BRACE "\{"
+#token R_BRACE "\}"
+#token L_PAR "\("
+#token R_PAR "\)"
+#token L_BRACK "\["
+#token R_BRACK "\]"
+#token ZERO_MORE "\*"
+#token ONE_MORE "\+"
+#token OR "\|"
+#token RANGE "\-"
+#token NOT "\~"
+#token OCTAL_VALUE "\\0[0-7]*"
+ << {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}>>
+#token HEX_VALUE "\\0[Xx][0-9a-fA-F]+"
+ << {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}>>
+#token DEC_VALUE "\\[1-9][0-9]*"
+ << {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}>>
+#token TAB "\\t" << zzlextext[0] = '\t';>>
+#token NL "\\n" << zzlextext[0] = '\n';>>
+#token CR "\\r" << zzlextext[0] = '\r';>>
+#token BS "\\b" << zzlextext[0] = '\b';>>
+
+/* MR1 */
+/* MR1 10-Apr-97 MR1 Allow #token regular expressions to cross lines */
+/* MR1 */
+#token CONTINUATION "\\ \n" << zzline++; zzskip();>> /* MR1 */
+
+/* NOTE: this takes ANYTHING after the \ */
+#token LIT "\\~[tnrb]" << zzlextext[0] = zzlextext[1];>>
+
+/* NOTE: this takes ANYTHING that doesn't match the other tokens */
+#token REGCHAR "~[\\]"
+
+
+grammar : << p_head(); p_class_hdr(); func_action = FALSE;>>
+ ( {LEXACTION | LEXMEMBER | LEXPREFIX | PARSERCLASS } ACTION)* /* MR1 */
+ <<if ( gen_cpp ) p_includes();>>
+ start_states
+ << func_action = FALSE; p_tables(); p_tail(); >>
+ (ACTION)* "@"
+ << if (firstLexMember != 0) p_class_def1(); >> /* MR1 */
+ ;
+
+start_states : ( PER_PER do_conversion
+ | NAME_PER_PER do_conversion (NAME_PER_PER do_conversion)*)
+ PER_PER
+ ;
+
+do_conversion : <<new_automaton_mode(); func_action = TRUE;>>
+ rule_list
+ <<
+ dfa_class_nop[mode_counter] =
+ relabel($1.l,comp_level);
+ if (comp_level)
+ p_shift_table(mode_counter);
+ dfa_basep[mode_counter] = dfa_allocated+1;
+ make_dfa_model_node(dfa_class_nop[mode_counter]);
+ nfa_to_dfa($1.l);
+ ++mode_counter;
+ func_action = FALSE;
+#ifdef HASH_STAT
+ fprint_hash_stats(stderr);
+#endif
+ >>
+ ;
+
+rule_list : rule <<$$.l=$1.l; $$.r=$1.r;>>
+ (rule
+ <<{nfa_node *t1;
+ t1 = new_nfa_node();
+ (t1)->trans[0]=$$.l;
+ (t1)->trans[1]=$1.l;
+ /* all accept nodes "dead ends" */
+ $$.l=t1; $$.r=NULL;
+ }
+ >>
+ )*
+ | /* empty */
+ <<$$.l = new_nfa_node(); $$.r = NULL;
+ warning("no regular expressions", zzline);
+ >>
+ ;
+
+rule : reg_expr ACTION
+/* MR23 */ << if ($1.r != NULL) {
+ $$.l=$1.l; $$.r=$1.r; ($1.r)->accept=action_no;
+ }
+ >>
+ | ACTION
+ <<$$.l = NULL; $$.r = NULL;
+ error("no expression for action ", zzline);
+ >>
+ ;
+
+reg_expr : and_expr <<$$.l=$1.l; $$.r=$1.r;>>
+ (OR and_expr
+ <<{nfa_node *t1, *t2;
+ t1 = new_nfa_node(); t2 = new_nfa_node();
+ (t1)->trans[0]=$$.l;
+ (t1)->trans[1]=$2.l;
+/* MR23 */ if ($$.r != NULL) ($$.r)->trans[1]=t2;
+ if ($2.r) {
+ ($2.r)->trans[1]=t2; /* MR20 */
+ }
+ $$.l=t1; $$.r=t2;
+ }
+ >>
+ )*
+ ;
+
+and_expr : repeat_expr
+ <<
+ $$.l=$1.l; $$.r=$1.r;
+ >>
+ (repeat_expr
+/* MR23 */ << if ($$.r != NULL) {
+ ($$.r)->trans[1]=$1.l;
+ $$.r=$1.r;
+ }
+ >>
+ )*
+ ;
+
+repeat_expr : expr <<$$.l=$1.l; $$.r=$1.r;>>
+ { ZERO_MORE
+ <<{ nfa_node *t1,*t2;
+/* MR23 */ if ($$.r != NULL) ($$.r)->trans[0] = $$.l;
+ t1 = new_nfa_node(); t2 = new_nfa_node();
+ t1->trans[0]=$$.l;
+ t1->trans[1]=t2;
+/* MR23 */ if ($$.r != NULL) ($$.r)->trans[1]=t2;
+ $$.l=t1;$$.r=t2;
+ }
+ >>
+ | ONE_MORE
+/* MR23 */ <<if ($$.r != NULL) ($$.r)->trans[0] = $$.l;>>
+ }
+ | ZERO_MORE
+ << error("no expression for *", zzline);>>
+ | ONE_MORE
+ << error("no expression for +", zzline);>>
+ ;
+
+expr : << $$.l = new_nfa_node();
+ $$.r = new_nfa_node();
+ >>
+ L_BRACK atom_list R_BRACK
+ <<
+/* MR23 */ if ($$.l != NULL) {
+ ($$.l)->trans[0] = $$.r;
+ ($$.l)->label = set_dup($2.label);
+ set_orin(&used_chars,($$.l)->label);
+ }
+ >>
+ | NOT L_BRACK atom_list R_BRACK
+ <<
+/* MR23 */ if ($$.l != NULL) {
+ ($$.l)->trans[0] = $$.r;
+ ($$.l)->label = set_dif(normal_chars,$3.label);
+ set_orin(&used_chars,($$.l)->label);
+ }
+ >>
+ | L_PAR reg_expr R_PAR
+ <<
+/* MR23 */ if ($$.l != NULL) {
+ ($$.l)->trans[0] = $2.l;
+ if ($2.r) {
+ ($2.r)->trans[1] = $$.r; /* MR20 */
+ }
+ }
+ >>
+ | L_BRACE reg_expr R_BRACE
+ <<
+/* MR23 */ if ($$.l != NULL) {
+ ($$.l)->trans[0] = $2.l;
+ ($$.l)->trans[1] = $$.r;
+ if ($2.r) {
+ ($2.r)->trans[1] = $$.r; /* MR20 */
+ }
+ }
+ >>
+ | atom
+ <<
+/* MR23 */ if ($$.l != NULL) {
+ ($$.l)->trans[0] = $$.r;
+ ($$.l)->label = set_dup($1.label);
+ set_orin(&used_chars,($$.l)->label);
+ }
+ >>
+ ;
+
+atom_list : << set_free($$.label); >>
+ (near_atom <<set_orin(&($$.label),$1.label);>>)*
+ ;
+
+near_atom : << register int i;
+ register int i_prime;
+ >>
+ anychar
+ <<$$.letter=$1.letter; $$.label=set_of($1.letter);
+ i_prime = $1.letter + MIN_CHAR;
+ if (case_insensitive && islower(i_prime))
+ set_orel(toupper(i_prime)-MIN_CHAR,
+ &($$.label));
+ if (case_insensitive && isupper(i_prime))
+ set_orel(tolower(i_prime)-MIN_CHAR,
+ &($$.label));
+ >>
+ { RANGE anychar
+ << if (case_insensitive){
+ i_prime = $$.letter+MIN_CHAR;
+ $$.letter = (islower(i_prime) ?
+ toupper(i_prime) : i_prime)-MIN_CHAR;
+ i_prime = $2.letter+MIN_CHAR;
+ $2.letter = (islower(i_prime) ?
+ toupper(i_prime) : i_prime)-MIN_CHAR;
+ }
+ /* check to see if range okay */
+ {
+ int debugLetter1 = $$.letter;
+ int debugLetter2 = $2.letter;
+ }
+ if ($$.letter > $2.letter
+ && $2.letter != 0xff){ /* MR16 */
+ error("invalid range ", zzline);
+ }
+ for (i=$$.letter; i<= (int)$2.letter; ++i){
+ set_orel(i,&($$.label));
+ i_prime = i+MIN_CHAR;
+ if (case_insensitive && islower(i_prime))
+ set_orel(toupper(i_prime)-MIN_CHAR,
+ &($$.label));
+ if (case_insensitive && isupper(i_prime))
+ set_orel(tolower(i_prime)-MIN_CHAR,
+ &($$.label));
+ }
+ >>
+ }
+ ;
+
+atom : << register int i_prime;>>
+ anychar
+ <<$$.label = set_of($1.letter);
+ i_prime = $1.letter + MIN_CHAR;
+ if (case_insensitive && islower(i_prime))
+ set_orel(toupper(i_prime)-MIN_CHAR,
+ &($$.label));
+ if (case_insensitive && isupper(i_prime))
+ set_orel(tolower(i_prime)-MIN_CHAR,
+ &($$.label));
+ >>
+ ;
+
+anychar : REGCHAR <<$$.letter = $1.letter - MIN_CHAR;>>
+ | OCTAL_VALUE <<$$.letter = $1.letter - MIN_CHAR;>>
+ | HEX_VALUE <<$$.letter = $1.letter - MIN_CHAR;>>
+ | DEC_VALUE <<$$.letter = $1.letter - MIN_CHAR;>>
+ | TAB <<$$.letter = $1.letter - MIN_CHAR;>>
+ | NL <<$$.letter = $1.letter - MIN_CHAR;>>
+ | CR <<$$.letter = $1.letter - MIN_CHAR;>>
+ | BS <<$$.letter = $1.letter - MIN_CHAR;>>
+ | LIT <<$$.letter = $1.letter - MIN_CHAR;>>
+ /* NOTE: LEX_EOF is ALWAYS shifted to 0 = MIN_CHAR - MIN_CHAR*/
+ | L_EOF <<$$.letter = 0;>>
+ ;
+
+<</* empty action */>>
+
+#lexclass ACT
+#token "@" << error("unterminated action", zzline); zzmode(START); >>
+#token ACTION "\>\>"
+ << if (func_action) fprintf(OUT,"}\n\n");
+ zzmode(START);
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via <<%%lexmember ...>> */
+/* MR1 This is a consequence of not saving actions */
+/* MR1 */
+/* MR1 */ parserClass=0;
+/* MR1 */ lexPrefix=0;
+/* MR1 */ lexAction=0;
+/* MR1 */ lexMember=0;
+ >>
+#token "\>" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */
+#token "\\\>" << xxputc('>'); zzskip(); >> /* MR1 */
+#token "\\" << xxputc('\\'); zzskip(); >> /* MR1 */
+#token "\n" << xxputc(zzlextext[0]); ++zzline; zzskip(); >> /* MR1 */
+#token "/\*" << zzmode(ACTION_COMMENTS); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >> /* MR1 */
+#token "//" << zzmode(ACTION_CPP_COMMENTS); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >> /* MR1 */
+#token "~[]" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */
+ /* MR1 */
+#lexclass ACTION_COMMENTS /* MR1 */
+#token "\*/" << zzmode(ACT); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >> /* MR1 */
+#token "[\n\r]" << zzline++; xxputc(zzlextext[0]); zzskip();>> /* MR1 */
+#token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */
+ /* MR1 */
+#lexclass ACTION_CPP_COMMENTS /* MR1 */
+#token "[\n\r]" << zzmode(ACT); zzline++; /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >> /* MR1 */
+#token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */
+
+<<
+/* adds a new nfa to the binary tree and returns a pointer to it */
+nfa_node *
+#ifdef __USE_PROTOS
+new_nfa_node(void)
+#else
+new_nfa_node()
+#endif
+{
+ register nfa_node *t;
+ static int nfa_size=0; /* elements nfa_array[] can hold */
+
+ ++nfa_allocated;
+ if (nfa_size<=nfa_allocated){
+ /* need to redo array */
+ if (!nfa_array){
+ /* need some to do initial allocation */
+ nfa_size=nfa_allocated+NFA_MIN;
+ nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)*
+ nfa_size);
+ }else{
+ /* need more space */
+ nfa_size=2*(nfa_allocated+1);
+ nfa_array=(nfa_node **) realloc(nfa_array,
+ sizeof(nfa_node*)*nfa_size);
+ }
+ }
+ /* fill out entry in array */
+ t = (nfa_node*) malloc(sizeof(nfa_node));
+ nfa_array[nfa_allocated] = t;
+ *t = nfa_model_node;
+ t->node_no = nfa_allocated;
+ return t;
+}
+
+
+/* initialize the model node used to fill in newly made nfa_nodes */
+void
+#ifdef __USE_PROTOS
+make_nfa_model_node(void)
+#else
+make_nfa_model_node()
+#endif
+{
+ nfa_model_node.node_no = -1; /* impossible value for real nfa node */
+ nfa_model_node.nfa_set = 0;
+ nfa_model_node.accept = 0; /* error state default*/
+ nfa_model_node.trans[0] = NULL;
+ nfa_model_node.trans[1] = NULL;
+ nfa_model_node.label = empty;
+}
+>>
+
+<<
+#if defined(DEBUG) || defined(_DEBUG)
+
+/* print out the pointer value and the node_number */
+void
+#ifdef __USE_PROTOS
+fprint_dfa_pair(FILE *f, nfa_node *p)
+#else
+fprint_dfa_pair(f, p)
+FILE *f;
+nfa_node *p;
+#endif
+{
+ if (p){
+ fprintf(f, "%x (%d)", p, p->node_no);
+ }else{
+ fprintf(f, "(nil)");
+ }
+}
+
+/* print out interest information on a set */
+void
+#ifdef __USE_PROTOS
+fprint_set(FILE *f, set s)
+#else
+fprint_set(f,s)
+FILE *f;
+set s;
+#endif
+{
+ unsigned int *x;
+
+ fprintf(f, "n = %d,", s.n);
+ if (s.setword){
+ fprintf(f, "setword = %x, ", s.setword);
+ /* print out all the elements in the set */
+ x = set_pdq(s);
+ while (*x!=nil){
+ fprintf(f, "%d ", *x);
+ ++x;
+ }
+ }else{
+ fprintf(f, "setword = (nil)");
+ }
+}
+
+/* code to be able to dump out the nfas
+ return 0 if okay dump
+ return 1 if screwed up
+ */
+int
+#ifdef __USE_PROTOS
+dump_nfas(int first_node, int last_node)
+#else
+dump_nfas(first_node, last_node)
+int first_node;
+int last_node;
+#endif
+{
+ register int i;
+ nfa_node *t;
+
+ for (i=first_node; i<=last_node; ++i){
+ t = NFA(i);
+ if (!t) break;
+ fprintf(stderr, "nfa_node %d {\n", t->node_no);
+ fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set);
+ fprintf(stderr, "\taccept\t=\t%d\n", t->accept);
+ fprintf(stderr, "\ttrans\t=\t(");
+ fprint_dfa_pair(stderr, t->trans[0]);
+ fprintf(stderr, ",");
+ fprint_dfa_pair(stderr, t->trans[1]);
+ fprintf(stderr, ")\n");
+ fprintf(stderr, "\tlabel\t=\t{ ");
+ fprint_set(stderr, t->label);
+ fprintf(stderr, "\t}\n");
+ fprintf(stderr, "}\n\n");
+ }
+ return 0;
+}
+#endif
+>>
+
+<<
+/* DLG-specific syntax error message generator
+ * (define USER_ZZSYN when compiling so don't get 2 definitions)
+ */
+void
+#ifdef __USE_PROTOS
+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)
+#else
+zzsyn(text, tok, egroup, eset, etok, k, bad_text)
+char *text, *egroup, *bad_text;
+int tok;
+int etok;
+int k;
+SetWordType *eset;
+#endif
+{
+ fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline);
+ fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);
+ if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
+ if ( k==1 ) fprintf(stderr, " missing");
+ else
+ {
+ fprintf(stderr, "; \"%s\" not", bad_text);
+ if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
+ }
+ if ( zzset_deg(eset)>0 ) zzedecode(eset);
+ else fprintf(stderr, " %s", zztokens[etok]);
+ if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);
+ fprintf(stderr, "\n");
+}
+>>
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/err.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/err.c
new file mode 100644
index 00000000..896c4477
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/err.c
@@ -0,0 +1,99 @@
+/*
+ * A n t l r S e t s / E r r o r F i l e H e a d e r
+ *
+ * Generated from: dlg_p.g
+ *
+ * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001
+ * Parr Research Corporation
+ * with Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include <ctype.h>
+#include "dlg.h"
+#define zzSET_SIZE 8
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "err.h"
+
+ANTLRChar *zztokens[46]={
+ /* 00 */ "Invalid",
+ /* 01 */ "@",
+ /* 02 */ "[\\r\\t\\ ]+",
+ /* 03 */ "\\n",
+ /* 04 */ "L_EOF",
+ /* 05 */ "PER_PER",
+ /* 06 */ "NAME_PER_PER",
+ /* 07 */ "LEXMEMBER",
+ /* 08 */ "LEXACTION",
+ /* 09 */ "PARSERCLASS",
+ /* 10 */ "LEXPREFIX",
+ /* 11 */ "ACTION",
+ /* 12 */ "GREAT_GREAT",
+ /* 13 */ "L_BRACE",
+ /* 14 */ "R_BRACE",
+ /* 15 */ "L_PAR",
+ /* 16 */ "R_PAR",
+ /* 17 */ "L_BRACK",
+ /* 18 */ "R_BRACK",
+ /* 19 */ "ZERO_MORE",
+ /* 20 */ "ONE_MORE",
+ /* 21 */ "OR",
+ /* 22 */ "RANGE",
+ /* 23 */ "NOT",
+ /* 24 */ "OCTAL_VALUE",
+ /* 25 */ "HEX_VALUE",
+ /* 26 */ "DEC_VALUE",
+ /* 27 */ "TAB",
+ /* 28 */ "NL",
+ /* 29 */ "CR",
+ /* 30 */ "BS",
+ /* 31 */ "CONTINUATION",
+ /* 32 */ "LIT",
+ /* 33 */ "REGCHAR",
+ /* 34 */ "\\>",
+ /* 35 */ "\\\\>",
+ /* 36 */ "\\",
+ /* 37 */ "\\n",
+ /* 38 */ "/\\*",
+ /* 39 */ "//",
+ /* 40 */ "~[]",
+ /* 41 */ "\\*/",
+ /* 42 */ "[\\n\\r]",
+ /* 43 */ "~[]",
+ /* 44 */ "[\\n\\r]",
+ /* 45 */ "~[]"
+};
+SetWordType zzerr1[8] = {0x80,0xf,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr2[8] = {0x60,0x0,0x0,0x0, 0x0,0x0,0x0,0x0};
+SetWordType zzerr3[8] = {0x70,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType setwd1[46] = {0x0,0x6,0x0,0x0,0x30,0xc8,0xc8,
+ 0x1,0x1,0x1,0x1,0x35,0x0,0x30,0x0,
+ 0x30,0x0,0x30,0x0,0x30,0x30,0x0,0x0,
+ 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+ 0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr4[8] = {0x10,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType zzerr5[8] = {0x10,0xe8,0xbb,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType zzerr6[8] = {0x10,0xa0,0x9a,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType setwd2[46] = {0x0,0x0,0x0,0x0,0xeb,0x2,0x2,
+ 0x0,0x0,0x0,0x0,0xd6,0x0,0xeb,0xd4,
+ 0xeb,0xd4,0xeb,0x0,0xcb,0xcb,0xd0,0x0,
+ 0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,
+ 0x0,0xeb,0xeb,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0};
+SetWordType zzerr7[8] = {0x10,0xa0,0x82,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType zzerr8[8] = {0x10,0x0,0x44,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType zzerr9[8] = {0x10,0x0,0x0,0x7f, 0x3,0x0,0x0,0x0};
+SetWordType setwd3[46] = {0x0,0x0,0x0,0x0,0xf7,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0xc2,0x0,0xc2,0xc2,
+ 0xc2,0xc2,0xc2,0xb8,0xc2,0xc2,0xc2,0x80,
+ 0xc2,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
+ 0x0,0xf7,0xf7,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0};
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/main.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/main.c
new file mode 100644
index 00000000..20d0bffe
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/main.c
@@ -0,0 +1,281 @@
+/* Main function for dlg version
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "stdpccts.h"
+
+char program[] = "dlg";
+char version[] = "1.33MR33"; /* MRXXX */
+int numfiles = 0;
+char *file_str[2] = {NULL, NULL};
+char *mode_file = "mode.h";
+char *class_name = DEFAULT_CLASSNAME;
+char *OutputDirectory = TopDirectory;
+
+/* Option variables */
+int comp_level = 0;
+int interactive = FALSE;
+int case_insensitive = FALSE;
+int warn_ambig = FALSE;
+int gen_cpp = FALSE;
+
+#ifdef __USE_PROTOS
+static int ci_strequ(char *a,char *b)
+#else
+static int ci_strequ(a,b)
+ char *a;
+ char *b;
+#endif
+{
+ for ( ;*a != 0 && *b != 0; a++, b++) {
+ if (toupper(*a) != toupper(*b)) return 0;
+ }
+ return (*a == *b);
+}
+
+/* Option List Stuff */
+#ifdef __USE_PROTOS
+void p_comp0(void) {comp_level = 0;}
+void p_comp1(void) {comp_level = 1;}
+void p_comp2(void) {comp_level = 2;}
+void p_stdio(void) { file_str[numfiles++] = NULL;}
+void p_file(char *s) { file_str[numfiles++] = s;}
+void p_cl_name(char *s, char *t)
+ {
+ if ( gen_cpp ) {
+ class_name = t;
+ }
+ else {
+ warning("-cl only valid in C++ mode; -cl ignored...",0);
+ }
+ }
+void p_mode_file(char *s, char *t){mode_file=t;}
+void p_outdir(char *s,char *t) {OutputDirectory=t;}
+void p_ansi(void) {gen_ansi = TRUE;}
+void p_interactive(void) {interactive = TRUE;}
+void p_case_s(void) { case_insensitive = FALSE; }
+void p_case_i(void) { case_insensitive = TRUE; }
+void p_warn_ambig(void) { warn_ambig = TRUE; }
+void p_cpp(void) { gen_cpp = TRUE; }
+#else
+void p_comp0() {comp_level = 0;}
+void p_comp1() {comp_level = 1;}
+void p_comp2() {comp_level = 2;}
+void p_stdio() { file_str[numfiles++] = NULL;}
+void p_file(s) char *s; { file_str[numfiles++] = s;}
+void p_cl_name(s,t)
+ char *s, *t;
+ {
+ if ( gen_cpp ) {
+ class_name = t;
+ }
+ else {
+ warning("-cl only valid in C++ mode; -cl ignored...",0);
+ }
+ }
+void p_mode_file(s,t) char *s,*t;{mode_file=t;}
+void p_outdir(s,t) char *s,*t;{OutputDirectory=t;}
+void p_ansi() {gen_ansi = TRUE;}
+void p_interactive() {interactive = TRUE;}
+void p_case_s() { case_insensitive = FALSE; }
+void p_case_i() { case_insensitive = TRUE; }
+void p_warn_ambig() { warn_ambig = TRUE; }
+void p_cpp() { gen_cpp = TRUE; }
+#endif
+
+#ifdef __cplusplus
+typedef void (*WildFunc)(...);
+#else
+typedef void (*WildFunc)();
+#endif
+
+typedef struct {
+ char *option;
+ int arg;
+ WildFunc process;
+ char *descr;
+ } Opt;
+
+Opt options[] = {
+ { "-CC", 0, (WildFunc)p_cpp, "Generate C++ output" },
+ { "-C0", 0, (WildFunc)p_comp0, "No compression (default)" },
+ { "-C1", 0, (WildFunc)p_comp1, "Compression level 1" },
+ { "-C2", 0, (WildFunc)p_comp2, "Compression level 2" },
+ { "-ga", 0, (WildFunc)p_ansi, "Generate ansi C"},
+ { "-Wambiguity", 0, (WildFunc)p_warn_ambig, "Warn if expressions ambiguous"},
+ { "-m", 1, (WildFunc)p_mode_file, "Rename lexical mode output file"},
+ { "-i", 0, (WildFunc)p_interactive, "Build interactive scanner (not valid for C++ mode)"},
+ { "-ci", 0, (WildFunc)p_case_i, "Make lexical analyzer case insensitive"},
+ { "-cl", 1, (WildFunc)p_cl_name, "Rename lexer class (DLGLexer); only used for -CC"},
+ { "-cs", 0, (WildFunc)p_case_s, "Make lexical analyzer case sensitive (default)"},
+ { "-o", 1, (WildFunc)p_outdir, OutputDirectoryOption},
+ { "-", 0, (WildFunc)p_stdio, "Use standard i/o rather than file"},
+ { "*", 0, (WildFunc)p_file, ""}, /* anything else is a file */
+ { NULL, 0, NULL }
+ };
+
+#ifdef __USE_PROTOS
+void ProcessArgs(int argc, char **argv, Opt *options)
+#else
+void ProcessArgs(argc, argv, options)
+int argc;
+char **argv;
+Opt *options;
+#endif
+{
+ Opt *p;
+
+ while ( argc-- > 0 )
+ {
+ p = options;
+ while ( p->option != NULL )
+ {
+ if ( strcmp(p->option, "*") == 0 ||
+ ci_strequ(p->option,*argv) )
+ {
+ if ( p->arg )
+ {
+ (*p->process)( *argv, *(argv+1) );
+ argv++;
+ argc--;
+ }
+ else
+ (*p->process)( *argv );
+ break;
+ }
+ p++;
+ }
+ argv++;
+ }
+}
+
+#ifdef __USE_PROTOS
+int main(int argc, char *argv[])
+#else
+int main(argc, argv)
+int argc;
+char *argv[];
+#endif
+{
+ init();
+ fprintf(stderr, "%s Version %s 1989-2001\n", &(program[0]),
+ &(version[0]));
+ if ( argc == 1 )
+ {
+ Opt *p = options;
+ fprintf(stderr, "%s [options] f1 f2 ... fn\n",argv[0]);
+ while ( *(p->option) != '*' )
+ {
+ fprintf(stderr, "\t%s %s\t%s\n",
+ p->option,
+ (p->arg)?"___":" ",
+ p->descr);
+ p++;
+ }
+ }else{
+ ProcessArgs(argc-1, &(argv[1]), options);
+ if (interactive && gen_cpp) {
+ fprintf(stderr,"\n");
+/*** MR21a This statement is wrong ! ***/
+#if 0
+*** fprintf(stderr,"Interactive lexer option (\"-i\") has no effect when in C++ mode\n");
+*** fprintf(stderr,"because of extra buffering provided by ANTLRTokenBuffer class.\n");
+*** fprintf(stderr,"\n");
+#endif
+ }
+ input_stream = read_stream(file_str[0]);
+ if (input_stream) {
+ /* don't overwrite unless input okay */
+ if ( gen_cpp ) {
+ output_stream = write_stream(ClassName(CPP_FILE_SUFFIX));
+ if ( file_str[1]!=NULL ) {
+ warning("output file implicit in C++ mode; ignored...",0);
+ }
+ class_stream = write_stream(ClassName(".h"));
+ mode_stream = class_stream;
+ }
+ else {
+ output_stream = write_stream(file_str[1]);
+ mode_stream = write_stream(mode_file);
+ }
+ }
+ /* make sure that error reporting routines in grammar
+ know what the file really is */
+ /* make sure that reading and writing somewhere */
+ if (input_stream && output_stream && mode_stream){
+ ANTLR(grammar(), input_stream);
+ }
+ p_class_def2(); /* MR1 */
+ }
+ if ( output_stream!=NULL ) fclose(output_stream);
+ if ( !gen_cpp && mode_stream!=NULL ) fclose(mode_stream);
+ if ( class_stream!=NULL ) fclose(class_stream);
+ exit(PCCTS_EXIT_SUCCESS);
+ return 0; /* get rid of warning message MR1 */
+}
+
+/* initialize all the variables */
+void
+#ifdef __USE_PROTOS
+init(void)
+#else
+init()
+#endif
+{
+ register int i;
+
+#ifdef SPECIAL_INITS
+ special_inits(); /* MR1 */
+#endif
+ used_chars = empty;
+ used_classes = empty;
+ /* make the valid character set */
+ normal_chars = empty;
+ /* NOTE: MIN_CHAR is EOF */
+ /* NOTE: EOF is not quite a valid char, it is special. Skip it*/
+ for (i = 1; i<CHAR_RANGE; ++i){
+ set_orel(i,&normal_chars);
+ }
+ make_nfa_model_node();
+ clear_hash();
+ /* NOTE: need to set this flag before the lexer starts getting */
+ /* tokens */
+ func_action = FALSE;
+}
+
+/* stuff that needs to be reset when a new automaton is being built */
+void
+#ifdef __USE_PROTOS
+new_automaton_mode(void) /* MR1 */
+#else
+new_automaton_mode() /* MR1 */
+#endif
+{
+ set_free(used_chars);
+ clear_hash();
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile
new file mode 100644
index 00000000..a82a952a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile
@@ -0,0 +1,164 @@
+#
+# Makefile for DLG 1.33
+# Terence Parr
+# Purdue University, U of MN, Parr Research Corporation
+# 1989-1994
+#
+# Ported to IBM C-Set/2 and Microsoft 6.0 by
+# Ed Harfmann
+# Micro Data Base Systems
+# Lafayette, Indiana
+#
+SET=../support/set
+PCCTS_H=../h
+
+##
+## Uncomment the appropriate section to build
+##
+
+#
+# OS/2 & DOS 16 bit using MSC 6.0
+#
+#CC=cl
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN
+#OUT_OBJ = -Fo
+#LIBS=/NOD:LLIBCE LLIBCEP
+#OBJ_EXT = obj
+#
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# link @<<
+#$** /NOI
+#$@ /STACK:16384
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# bind $@ c:\os2\doscalls.lib
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for DOS
+#
+#CC=bcc
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= emu mathl cl
+#OBJ_EXT = obj
+#
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# tlink @&&|
+#C0L $**
+#$@ /Tde /c
+#
+#$(LIBS)
+#$(DEF_FILE) $(LFLAGS) ;
+#|
+# copy *.exe ..\bin
+#
+
+#
+# C-Set/2 for OS/2
+#
+#CC=icc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 /DUSER_ZZSYN
+#OUT_OBJ = -Fo
+#LIBS=
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT=obj
+#
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# link386 @<<
+#$** /NOI
+#$@ /STACK:32768
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for OS/2
+#
+#CC=bcc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= c2 os2
+#
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT = obj
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# tlink @&&|
+#c02 $** -c
+#dlg.exe
+#
+#C2 os2
+#
+#|
+# copy *.exe ..\bin
+#
+
+#
+# UNIX
+#
+ifeq ($(CXX), llvm)
+BUILD_CC?=$(CLANG_BIN)clang
+else
+BUILD_CC?=cc
+endif
+COPT=-O
+ANTLR=${BIN_DIR}/antlr
+DLG=${BIN_DIR}/dlg
+BUILD_CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -DZZLEXBUFSIZE=65536
+BUILD_CPPFLAGS=
+OBJ_EXT=o
+OUT_OBJ = -o
+OBJ = dlg_p.o dlg_a.o main.o err.o set.o support.o output.o \
+ relabel.o automata.o
+
+$(BIN_DIR)/dlg : $(OBJ) $(SRC)
+ $(BUILD_CC) $(BUILD_CFLAGS) -o $(BIN_DIR)/dlg $(OBJ)
+
+SRC = dlg_p.c dlg_a.c main.c err.c $(SET)/set.c support.c output.c \
+ relabel.c automata.c
+
+#dlg_p.c parser.dlg err.c tokens.h : dlg_p.g
+# $(ANTLR) dlg_p.g
+
+#dlg_a.c mode.h : parser.dlg
+# $(DLG) -C2 parser.dlg dlg_a.c
+
+dlg_p.$(OBJ_EXT) : dlg_p.c dlg.h tokens.h mode.h
+ $(BUILD_CC) $(BUILD_CFLAGS) -c dlg_p.c
+
+dlg_a.$(OBJ_EXT) : dlg_a.c dlg.h tokens.h mode.h
+ $(BUILD_CC) $(BUILD_CFLAGS) -c dlg_a.c
+
+main.$(OBJ_EXT) : main.c dlg.h
+ $(BUILD_CC) $(BUILD_CFLAGS) -c main.c
+
+set.$(OBJ_EXT) : $(SET)/set.c
+ $(BUILD_CC) -c $(BUILD_CFLAGS) $(SET)/set.c
+
+%.o : %.c
+ $(BUILD_CC) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $< -o $@
+
+lint:
+ lint *.c
+
+#clean up all the intermediate files
+clean:
+ rm -f $(BIN_DIR)/dlg *.$(OBJ_EXT) core
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile.cygwin b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile.cygwin
new file mode 100644
index 00000000..ec1a6907
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile.cygwin
@@ -0,0 +1,157 @@
+#
+# Makefile for DLG 1.33
+# Terence Parr
+# Purdue University, U of MN, Parr Research Corporation
+# 1989-1994
+#
+# Ported to IBM C-Set/2 and Microsoft 6.0 by
+# Ed Harfmann
+# Micro Data Base Systems
+# Lafayette, Indiana
+#
+SET=../support/set
+PCCTS_H=../h
+
+##
+## Uncomment the appropriate section to build
+##
+
+#
+# OS/2 & DOS 16 bit using MSC 6.0
+#
+#CC=cl
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN
+#OUT_OBJ = -Fo
+#LIBS=/NOD:LLIBCE LLIBCEP
+#OBJ_EXT = obj
+#
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# link @<<
+#$** /NOI
+#$@ /STACK:16384
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# bind $@ c:\os2\doscalls.lib
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for DOS
+#
+#CC=bcc
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= emu mathl cl
+#OBJ_EXT = obj
+#
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# tlink @&&|
+#C0L $**
+#$@ /Tde /c
+#
+#$(LIBS)
+#$(DEF_FILE) $(LFLAGS) ;
+#|
+# copy *.exe ..\bin
+#
+
+#
+# C-Set/2 for OS/2
+#
+#CC=icc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 /DUSER_ZZSYN
+#OUT_OBJ = -Fo
+#LIBS=
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT=obj
+#
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# link386 @<<
+#$** /NOI
+#$@ /STACK:32768
+#
+#$(LIBS: = +^
+#)
+#$(DEF_FILE) $(LFLAGS) ;
+#<<
+# copy *.exe ..\bin
+#
+
+#
+# Borland C++ for OS/2
+#
+#CC=bcc
+#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -DUSER_ZZSYN
+#OUT_OBJ = -o
+#LIBS= c2 os2
+#
+#ANTLR=..\bin\antlr
+#DLG=..\bin\dlg
+#OBJ_EXT = obj
+#dlg.exe : dlg_p.obj dlg_a.obj main.obj err.obj set.obj support.obj \
+# output.obj relabel.obj automata.obj
+# tlink @&&|
+#c02 $** -c
+#dlg.exe
+#
+#C2 os2
+#
+#|
+# copy *.exe ..\bin
+#
+
+#
+# UNIX
+#
+BIN_DIR=../../../../bin
+CC=cc
+COPT=-O
+ANTLR=$(BIN_DIR)/antlr.exe
+DLG=${BIN_DIR}/dlg.exe
+CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -DZZLEXBUFSIZE=65536
+OBJ_EXT=o
+OUT_OBJ = -o
+OBJ = dlg_p.o dlg_a.o main.o err.o set.o support.o output.o \
+ relabel.o automata.o
+
+dlg : $(OBJ) $(SRC)
+ $(CC) $(CFLAGS) -o $(BIN_DIR)/dlg.exe $(OBJ)
+
+SRC = dlg_p.c dlg_a.c main.c err.c $(SET)/set.c support.c output.c \
+ relabel.c automata.c
+
+#dlg_p.c parser.dlg err.c tokens.h : dlg_p.g
+# $(ANTLR) dlg_p.g
+
+#dlg_a.c mode.h : parser.dlg
+# $(DLG) -C2 parser.dlg dlg_a.c
+
+dlg_p.$(OBJ_EXT) : dlg_p.c dlg.h tokens.h mode.h
+ $(CC) $(CFLAGS) -c dlg_p.c
+
+dlg_a.$(OBJ_EXT) : dlg_a.c dlg.h tokens.h mode.h
+ $(CC) $(CFLAGS) -c dlg_a.c
+
+main.$(OBJ_EXT) : main.c dlg.h
+ $(CC) $(CFLAGS) -c main.c
+
+set.$(OBJ_EXT) : $(SET)/set.c
+ $(CC) -c $(CFLAGS) $(SET)/set.c
+
+lint:
+ lint *.c
+
+#clean up all the intermediate files
+clean:
+ rm -f *.$(OBJ_EXT) core
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile1 b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile1
new file mode 100644
index 00000000..462e89bc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/makefile1
@@ -0,0 +1,63 @@
+#
+# Makefile for DLG 1.33
+# Terence Parr
+# Purdue University, U of MN, Parr Research Corporation
+# 1989-1994
+#
+# Ported to IBM C-Set/2 and Microsoft 6.0 by
+# Ed Harfmann
+# Micro Data Base Systems
+# Lafayette, Indiana
+#
+SET=../support/set
+PCCTS_H=../h
+
+##
+## Uncomment the appropriate section to build
+##
+
+
+#
+# UNIX
+#
+CC=cc
+ANTLR=../bin/antlr
+DLG=../bin/dlg
+ANSI=-ansi
+CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) $(ANSI) -DZZLEXBUFSIZE=32000
+OBJ_EXT=o
+OUT_OBJ = -o
+OBJ = dlg_p.o dlg_a.o main.o err.o set.o support.o output.o \
+ relabel.o automata.o
+
+dlg : $(OBJ) $(SRC)
+ $(CC) $(CFLAGS) -o dlg $(OBJ)
+ mv dlg ../bin
+
+SRC = dlg_p.c dlg_a.c main.c err.c $(SET)/set.c support.c output.c \
+ relabel.c automata.c
+
+dlg_p.c parser.dlg err.c tokens.h : dlg_p.g
+ $(ANTLR) dlg_p.g
+
+dlg_a.c mode.h : parser.dlg
+ $(DLG) -C2 parser.dlg dlg_a.c
+
+dlg_p.$(OBJ_EXT) : dlg_p.c dlg.h tokens.h mode.h
+ $(CC) $(CFLAGS) -c dlg_p.c
+
+dlg_a.$(OBJ_EXT) : dlg_a.c dlg.h tokens.h mode.h
+ $(CC) $(CFLAGS) -c dlg_a.c
+
+main.$(OBJ_EXT) : main.c dlg.h
+ $(CC) $(CFLAGS) -c main.c
+
+set.$(OBJ_EXT) : $(SET)/set.c
+ $(CC) -c $(CFLAGS) $(SET)/set.c
+
+lint:
+ lint *.c
+
+#clean up all the intermediate files
+clean:
+ rm -f *.$(OBJ_EXT) core
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/mode.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/mode.h
new file mode 100644
index 00000000..5dc2c289
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/mode.h
@@ -0,0 +1,4 @@
+#define START 0
+#define ACT 1
+#define ACTION_COMMENTS 2
+#define ACTION_CPP_COMMENTS 3
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/output.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/output.c
new file mode 100644
index 00000000..6ede57b6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/output.c
@@ -0,0 +1,865 @@
+/* output.c, output generator for dlg
+ *
+ * Output Notes:
+ *
+ * DfaStates == number of dfa nodes in automaton (just a #define)
+ * DfaState == type large enough to index every node in automaton
+ * <256 unsigned char, <65536 unsigned short, etc.
+ *
+ * Thus, the elements in each of the automaton states (st%d) are type DfaState
+ * and are size appropriately, since they must be able to index the next
+ * automaton state.
+ *
+ * dfa[] == a linear array that points to all the automaton states (st%d)
+ * (dfa_base[] should be the same, but isn't right now)
+ *
+ * accepts[] == Taking a closer look at this one, it probably shouldn't be type
+ * DfaState because there is no real requirement that the number of
+ * accepts states is less than the number of dfa state. However, if
+ * the number of accept states was more than the number of DFA states
+ * then the lexical specification would be really ambiguous.
+ *
+ * Another note. Is that is should be possible to fold accepts[] and
+ * actions[] together. If this is done, I would suggest get rid of
+ * accept[] and make actions[] have an entry for each state (st%d) in
+ * the automaton.
+ *
+ * dfa_base[] == starting location for each lexical mode. This should be
+ * Dfastate type (but isn't right now), since it points to the states
+ * in the automaton.
+ *
+ * dfa_class_no[] == indicates the number of columns each lexical mode has.
+ *
+ * b_class_no[] == pointer to the start of the translation array used to
+ * convert from input character to character class. This could cause
+ * problems if there are more than 256 classes
+ *
+ * shift%d[] == the actual translation arrays that convert the input character
+ * into the character class. These will have to change if there are
+ * more than 256 character classes.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "dlg.h"
+#ifdef MEMCHK
+#include "trax.h"
+#else
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif /* __STDC__ */
+#endif
+
+#ifdef VBOX
+void p_set(set label);
+void s_p_nfa(nfa_node *p);
+#endif /* VBOX */
+
+static char *mode_name[MAX_MODES];
+static int mode_number[MAX_MODES];
+static int cur_mode=0;
+
+int operation_no = 0; /* used to mark nodes so that infinite loops avoided */
+int dfa_basep[MAX_MODES]; /* start of each group of states */
+int dfa_class_nop[MAX_MODES]; /* number of elements in each group of states*/
+
+int gen_ansi = FALSE; /* allows ansi code to be generated */
+
+FILE *input_stream; /* where to read description from */
+FILE *output_stream; /* where to put the output */
+FILE *mode_stream; /* where to put the mode.h stuff */
+FILE *class_stream; /* where to put the scan.h stuff (if gen_cpp) */
+
+/* NOTE: This section is MACHINE DEPENDENT */
+#define DIF_SIZE 4
+#if defined(PC) && !defined(PC32)
+unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffful, 0x7ffffffful }; /* MR20 */
+char t0[] = "unsigned char";
+char t1[] = "unsigned short";
+char t2[] = "unsigned int";
+char t3[] = "unsigned long";
+char *typevar[DIF_SIZE] = { t0, t1, t2, t3};
+#else
+unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffffffful, 0x7ffffffful }; /* MR20 */
+char t0[] = "unsigned char";
+char t1[] = "unsigned short";
+char t2[] = "unsigned int";
+char t3[] = "unsigned long";
+char *typevar[DIF_SIZE] = { t0, t1, t2, t3};
+#endif
+
+/* Added by TJP August 1994 */
+/* Take in MyLexer and return MyLexer_h */
+
+static char *
+#ifdef __USE_PROTOS
+gate_symbol(char *name)
+#else
+gate_symbol(name)
+char *name;
+#endif
+{
+ static char buf[100];
+ sprintf(buf, "%s_h", name);
+ return buf;
+}
+
+/* Added by TJP August 1994 */
+static char *
+#ifdef __USE_PROTOS
+mystrdup(char *s)
+#else
+mystrdup(s)
+char *s;
+#endif
+{
+ char *p = (char *)malloc(strlen(s)+1);
+ strcpy(p, s);
+ return p;
+}
+
+#ifdef __USE_PROTOS
+void p_class_hdr(void)
+#else
+void p_class_hdr()
+#endif
+{
+ if ( class_stream == NULL ) return;
+ fprintf(class_stream, "#ifndef %s\n", gate_symbol(ClassName("")));
+ fprintf(class_stream, "#define %s\n", gate_symbol(ClassName("")));
+ fprintf(class_stream, "/*\n");
+ fprintf(class_stream, " * D L G L e x e r C l a s s D e f i n i t i o n\n");
+ fprintf(class_stream, " *\n");
+ fprintf(class_stream, " * Generated from:");
+ fprintf(class_stream, " %s", file_str[0]);
+ fprintf(class_stream, "\n");
+ fprintf(class_stream, " *\n");
+ fprintf(class_stream, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n");
+ fprintf(class_stream, " * Purdue University Electrical Engineering\n");
+ fprintf(class_stream, " * DLG Version %s\n", version);
+ fprintf(class_stream, " */\n\n");
+ fprintf(class_stream, "\n");
+ fprintf(class_stream, "#include \"%s\"\n", DLEXERBASE_H);
+}
+
+/* MR1 */
+/* MR1 16-Apr-97 Split printing of class header up into several parts */
+/* MR1 so that #lexprefix <<...>>and #lexmember <<...>> */
+/* MR1 can be inserted in the appropriate spots */
+/* MR1 */
+
+#ifdef __USE_PROTOS
+void p_class_def1(void)
+#else
+void p_class_def1()
+#endif
+{
+ if ( class_stream == NULL ) return;
+ fprintf(class_stream, "\nclass %s : public DLGLexerBase {\n", ClassName(""));
+ fprintf(class_stream, "public:\n");
+}
+
+#ifdef __USE_PROTOS
+void p_class_def2(void)
+#else
+void p_class_def2()
+#endif
+{
+ int i, m;
+ if ( class_stream == NULL ) return;
+ fprintf(class_stream, "public:\n");
+ fprintf(class_stream, "\tstatic const int MAX_MODE;\n");
+ fprintf(class_stream, "\tstatic const int DfaStates;\n");
+ for (i=0; i<cur_mode; i++) {
+ fprintf(class_stream, "\tstatic const int %s;\n", mode_name[i]);
+ }
+
+ fprintf(class_stream, "\ttypedef %s DfaState;\n\n", minsize(dfa_allocated));
+ fprintf(class_stream, "\t%s(DLGInputStream *in,\n",ClassName(""));
+ fprintf(class_stream, "\t\tunsigned bufsize=2000)\n");
+ fprintf(class_stream, "\t\t: DLGLexerBase(in, bufsize, %d)\n", interactive);
+ fprintf(class_stream, "\t{\n");
+ fprintf(class_stream, "\t;\n");
+ fprintf(class_stream, "\t}\n");
+ fprintf(class_stream, "\tvoid mode(int);\n");
+ fprintf(class_stream, "\tANTLRTokenType nextTokenType(void);\n");
+ fprintf(class_stream, "\tvoid advance(void);\n");
+ fprintf(class_stream, "protected:\n");
+ for (i=1; i<=action_no; ++i) {
+ fprintf(class_stream, "\tANTLRTokenType act%d();\n", i);
+ }
+
+ for(m=0; m<(mode_counter-1); ++m){
+ for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)
+ fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);
+ }
+ for(i=dfa_basep[m]; i<=dfa_allocated; ++i)
+ fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);
+
+ fprintf(class_stream, "\tstatic DfaState *dfa[%d];\n", dfa_allocated);
+ fprintf(class_stream, "\tstatic DfaState dfa_base[];\n");
+/* fprintf(class_stream, "\tstatic int dfa_base_no[];\n"); */
+ fprintf(class_stream, "\tstatic unsigned char *b_class_no[];\n");
+ fprintf(class_stream, "\tstatic DfaState accepts[%d];\n",dfa_allocated+1);
+ fprintf(class_stream, "\tstatic DLGChar alternatives[%d];\n",dfa_allocated+1);
+ /* WARNING: should be ANTLRTokenType for action table, but g++ 2.5.6 is hosed */
+ fprintf(class_stream, "\tstatic ANTLRTokenType (%s::*actions[%d])();\n", ClassName(""), action_no+1);
+ for(m=0; m<mode_counter; ++m) {
+ fprintf(class_stream, "\tstatic unsigned char shift%d[%d];\n",
+ m, CHAR_RANGE);
+ }
+ if (comp_level)
+ fprintf(class_stream, "\tint ZZSHIFT(int c) { return b_class_no[automaton][1+c]; }\n");
+ else
+ fprintf(class_stream, "\tint ZZSHIFT(int c) { return 1+c; }\n");
+
+/* MR1 */
+/* MR1 11-APr-97 Kludge to allow inclusion of user-defined code in */
+/* MR1 DLGLexer class header */
+/* MR1 Deprecated in favor of 133MR1 addition #lexmember <<>> */
+/* MR1 */
+/* MR1 */ fprintf(class_stream,"//\n");
+/* MR1 */ fprintf(class_stream,
+/* MR1 */ "// 133MR1 Deprecated feature to allow inclusion of ");
+/* MR1 */ fprintf(class_stream,
+/* MR1 */ "user-defined code in DLG class header\n");
+/* MR1 */ fprintf(class_stream,"//\n");
+/* MR1 */
+/* MR1 */ fprintf(class_stream,"#ifdef DLGLexerIncludeFile\n");
+/* MR1 */ fprintf(class_stream,"#include DLGLexerIncludeFile\n");
+/* MR1 */ fprintf(class_stream,"#endif\n");
+
+ fprintf(class_stream, "};\n");
+
+ fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n",
+ ClassName(""), ClassName(""));
+
+ fprintf(class_stream, "#endif\n");
+}
+
+/* generate required header on output */
+
+#ifdef __USE_PROTOS
+void p_head(void)
+#else
+void p_head()
+#endif
+{
+ fprintf(OUT, "/*\n");
+ fprintf(OUT, " * D L G tables\n");
+ fprintf(OUT, " *\n");
+ fprintf(OUT, " * Generated from:");
+ fprintf(OUT, " %s", file_str[0]);
+ fprintf(OUT, "\n");
+ fprintf(OUT, " *\n");
+ fprintf(OUT, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n");
+ fprintf(OUT, " * Purdue University Electrical Engineering\n");
+ fprintf(OUT, " * DLG Version %s\n", version);
+ fprintf(OUT, " */\n\n");
+ if ( gen_cpp) fprintf(OUT, "#include \"pcctscfg.h\"\n");
+ if ( gen_cpp ) fprintf(OUT, "#include \"pccts_stdio.h\"\n");
+ if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file);
+ fprintf(OUT,"\n");
+}
+
+#ifdef __USE_PROTOS
+void p_includes(void)
+#else
+void p_includes()
+#endif
+{
+ fprintf(OUT, "#include \"%s\"\n", APARSER_H);
+ fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H);
+ fprintf(OUT, "#include \"%s\"\n", ClassName(".h"));
+}
+
+/* generate code to tie up any loose ends */
+
+#ifdef __USE_PROTOS
+void p_tail(void) /* MR1 */
+#else
+void p_tail() /* MR1 */
+#endif
+{
+ if ( gen_cpp ) {
+ if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 )
+ fprintf(OUT, "#define DLGLexer %s\n", ClassName(""));
+ fprintf(OUT, "#include \"%s\"\n", DLEXER_H); /* MR23 Rename DLexer.cpp to DLexer.h */
+ return;
+ }
+ fprintf(OUT, "\n");
+ fprintf(OUT, "\n");
+ if (comp_level)
+ fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n");
+ else
+ fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n");
+ if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter);
+ fprintf(OUT, "#include \"dlgauto.h\"\n");
+}
+
+
+/* output the table of DFA for general use */
+
+#ifdef __USE_PROTOS
+void p_tables()
+#else
+void p_tables()
+#endif
+{
+ if ( !gen_cpp ) {
+ fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated);
+ fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated));
+ }
+
+ if ( gen_cpp ) {
+ int i;
+ fprintf(OUT, "\n");
+ fprintf(OUT, "const int %s::MAX_MODE=%d;\n",
+ ClassName(""),
+ mode_counter);
+ fprintf(OUT, "const int %s::DfaStates=%d;\n",
+ ClassName(""),
+ dfa_allocated);
+ for (i=0; i<cur_mode; i++) {
+ fprintf(OUT, "const int %s::%s=%d;\n",
+ ClassName(""), mode_name[i], mode_number[i]);
+ }
+ fprintf(OUT, "\n");
+ }
+
+ p_node_table();
+ p_dfa_table();
+ p_accept_table();
+ p_action_table();
+ p_base_table();
+ p_class_table();
+ if (comp_level)
+ p_bshift_table();
+ if (interactive || gen_cpp )
+ p_alternative_table();
+}
+
+
+/* figures out the smallest variable type that will hold the transitions
+ */
+
+#ifdef __USE_PROTOS
+char *minsize(int elements)
+#else
+char *minsize(elements)
+int elements;
+#endif
+{
+ int i = 0;
+
+ while ((unsigned long) elements > typesize[i]) /* MR20 */
+ ++i;
+ return typevar[i];
+}
+
+
+#ifdef __USE_PROTOS
+void p_node_table(void)
+#else
+void p_node_table()
+#endif
+{
+ register int i;
+ register int m = 0;
+
+ for(m=0; m<(mode_counter-1); ++m){
+ for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)
+ p_single_node(i,dfa_class_nop[m]);
+ }
+ for(i=dfa_basep[m]; i<=dfa_allocated; ++i)
+ p_single_node(i,dfa_class_nop[m]);
+}
+
+
+#ifdef __USE_PROTOS
+void p_single_node(int i,int classes)
+#else
+void p_single_node(i,classes)
+int i,classes;
+#endif
+{
+ register int j;
+ register int trans, items_on_line;
+
+#if 1
+ /* extra state (classes+1) for invalid characters */
+ fprintf(OUT, "%sDfaState %sst%d[%d] = {\n ",
+ gen_cpp?ClassName("::"):"static ",
+ gen_cpp?ClassName("::"):"",(i-1), (classes+1));
+#else
+ fprintf(OUT, "static DfaState st%d[%d] = {\n ", (i-1), classes);
+#endif
+ items_on_line = MAX_ON_LINE;
+ for(j=0; j<classes; ++j){
+ DAWDLE;
+ trans = DFA(i)->trans[j];
+ if (trans == NIL_INDEX)
+ trans = dfa_allocated+1;
+ /* all of DFA moved down one in array */
+ fprintf(OUT, "%d", trans-1);
+ fprintf(OUT, ", ");
+ if (!(--items_on_line)){
+ fprintf(OUT, "\n ");
+ items_on_line = MAX_ON_LINE;
+ }
+ }
+#if 1
+ /* put in jump to error state */
+ fprintf(OUT, "%d\n};\n\n", dfa_allocated);
+#else
+ fprintf(OUT, "\n};\n\n");
+#endif
+}
+
+
+#ifdef __USE_PROTOS
+void p_dfa_table(void)
+#else
+void p_dfa_table()
+#endif
+{
+ register int i;
+
+ fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n",
+ gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated);
+ for (i=0; i<(dfa_allocated-1); ++i){
+ fprintf(OUT, "\tst%d,\n", i);
+ }
+ fprintf(OUT, "\tst%d\n", i);
+ fprintf(OUT, "};\n\n");
+}
+
+
+#ifdef __USE_PROTOS
+void p_accept_table(void)
+#else
+void p_accept_table()
+#endif
+{
+ register int i = 1;
+ register int items_on_line = 0;
+ int true_interactive = TRUE;
+
+ /* make sure element for one past (zzerraction) -WEC 12/16/92 */
+ fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n ",
+ gen_cpp?ClassName("::"):"",
+ gen_cpp?ClassName("::"):"",
+ dfa_allocated+1);
+ /* don't do anything if no dfa nodes */
+ if (i>dfa_allocated) goto skip_accepts;
+ for (;;) {
+ int accept=0; /* MR14a - Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) */
+ set accept_set;
+ set nfa_states;
+ unsigned int *t, *nfa_i;
+ unsigned int *q, *regular_expr;
+
+ accept_set = empty;
+ nfa_states = DFA(i)->nfa_states;
+ t = nfa_i = set_pdq(nfa_states);
+ /* NOTE: picks lowest accept because accepts monotonic */
+ /* with respect to nfa node numbers and set_pdq */
+ /* returns in that order */
+ while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){
+ nfa_i++;
+ }
+
+ /* figure out if more than one accept state there */
+ if (warn_ambig ){
+ set_orel(accept, &accept_set);
+ while(*nfa_i != nil){
+ set_orel(NFA(*nfa_i)->accept, &accept_set);
+ nfa_i++;
+ }
+ /* remove error action from consideration */
+ set_rm(0, accept_set);
+
+ if( set_deg(accept_set)>1){
+ fprintf(stderr, "dlg warning: ambiguous regular expression ");
+ q = regular_expr = set_pdq(accept_set);
+ while(*regular_expr != nil){
+ fprintf(stderr," %d ", *regular_expr);
+ ++regular_expr;
+ }
+ fprintf(stderr, "\n");
+ free(q);
+ }
+ }
+
+ if ((DFA(i)->alternatives) && (accept != 0)){
+ true_interactive = FALSE;
+ }
+ fprintf(OUT, "%d, ", accept);
+
+ /* free up memory before we "break" below -ATG 4/6/95 */
+ free(t);
+ set_free(accept_set);
+
+ if ((++i)>dfa_allocated)
+ break;
+ if ((++items_on_line)>=MAX_ON_LINE){
+ fprintf(OUT,"\n ");
+ items_on_line = 0;
+ }
+/*
+ free(t);
+ set_free(accept_set);
+*/
+ }
+ /* make sure element for one past (zzerraction) -WEC 12/16/92 */
+skip_accepts:
+ fprintf(OUT, "0\n};\n\n");
+}
+
+
+#ifdef __USE_PROTOS
+void p_action_table(void)
+#else
+void p_action_table()
+#endif
+{
+ register int i;
+ char* theClassName = ClassName("");
+
+ if ( gen_cpp )
+ fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName,
+ theClassName, action_no+1);
+ else
+ fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1);
+ if ( gen_cpp )
+/* fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/
+ fprintf(OUT, "\t&%s::erraction,\n", theClassName);
+ else
+ fprintf(OUT, "\tzzerraction,\n");
+ for (i=1; i<action_no; ++i) {
+ if ( gen_cpp )
+/* fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d,\n", theClassName, theClassName, i);*/
+ fprintf(OUT,"\t&%s::act%d,\n", theClassName, i);
+ else
+ fprintf(OUT,"\tact%d,\n", i);
+ DAWDLE;
+ }
+ if ( gen_cpp )
+/* fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d\n", theClassName, theClassName, i);*/
+ fprintf(OUT,"\t&%s::act%d\n", theClassName, i);
+ else
+ fprintf(OUT,"\tact%d\n", i);
+ fprintf(OUT, "};\n\n");
+}
+
+
+#ifdef __USE_PROTOS
+void p_shift_table(int m) /* MR1 */
+#else
+void p_shift_table(m) /* MR1 */
+int m;
+#endif
+{
+ register int i = 0, j;
+ register int items_on_line = 0;
+
+ fprintf(OUT, "%s unsigned char %sshift%d[%d] = {\n ",
+ gen_cpp?"":"static",
+ gen_cpp?ClassName("::"):"", m, CHAR_RANGE);
+ for (;;) {
+ /* find which partition character i is in */
+ for (j=0; j<dfa_class_nop[mode_counter]; ++j){
+ if (set_el(i,class_sets[j]))
+ break;
+ }
+ fprintf(OUT,"%d",j);
+ if ((++i)>=CHAR_RANGE)
+ break;
+ fprintf(OUT,", ");
+ if ((++items_on_line)>=MAX_ON_LINE){
+ fprintf(OUT,"\n ");
+ items_on_line = 0;
+ }
+ }
+ fprintf(OUT, "\n};\n\n");
+}
+
+
+#ifdef __USE_PROTOS
+void p_base_table(void)
+#else
+void p_base_table()
+#endif
+{
+ register int m;
+
+ fprintf(OUT, "%sDfaState %sdfa_base[] = {\n",
+ gen_cpp?ClassName("::"):"static ",
+ gen_cpp?ClassName("::"):"");
+ for(m=0; m<(mode_counter-1); ++m)
+ fprintf(OUT, "\t%d,\n", dfa_basep[m]-1);
+ fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1);
+}
+
+
+#ifdef __USE_PROTOS
+void p_class_table(void) /* MR1 */
+#else
+void p_class_table() /* MR1 */
+#endif
+{
+#if 0
+ register int m;
+
+ fprintf(OUT,"%s int %sdfa_class_no[] = {\n",
+ gen_cpp?"":"static",
+ gen_cpp?ClassName("::"):"");
+ for(m=0; m<(mode_counter-1); ++m)
+ fprintf(OUT,"\t%d,\n", dfa_class_nop[m]);
+ fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]);
+#endif
+}
+
+
+#ifdef __USE_PROTOS
+void p_bshift_table(void) /* MR1 */
+#else
+void p_bshift_table() /* MR1 */
+#endif
+{
+ register int m;
+
+ fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n",
+ gen_cpp?"":"static",
+ gen_cpp?ClassName("::"):"");
+ for(m=0; m<(mode_counter-1); ++m)
+ fprintf(OUT, "\tshift%d,\n", m);
+ fprintf(OUT, "\tshift%d\n};\n\n", m);
+}
+
+
+#ifdef __USE_PROTOS
+void p_alternative_table(void) /* MR1 */
+#else
+void p_alternative_table() /* MR1 */
+#endif
+{
+ register int i;
+
+ if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n");
+ if ( gen_cpp )
+ fprintf(OUT, "DLGChar %salternatives[%d] = {\n", /* mr23 vhs %sDfaStates+1 */
+ ClassName("::"),
+ dfa_allocated+1); /* vhs ClassName("::")); */
+ else
+ fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n",
+ minsize(dfa_allocated));
+
+ for(i=1; i<=dfa_allocated; ++i)
+ fprintf(OUT, "\t%d,\n", DFA(i)->alternatives);
+ fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n");
+ fprintf(OUT, "\t0\n};\n\n");
+}
+
+
+#ifdef __USE_PROTOS
+void p_mode_def(char *s,int m) /* MR1 */
+#else
+void p_mode_def(s,m) /* MR1 */
+char *s;
+int m;
+#endif
+{
+ if ( gen_cpp )
+ {
+ mode_name[cur_mode] = mystrdup(s);
+ mode_number[cur_mode] = m;
+ cur_mode++;
+ }
+ else
+ fprintf(mode_stream, "#define %s %d\n", s, m);
+}
+
+#ifdef __USE_PROTOS
+char * ClassName(char *suffix)
+#else
+char * ClassName(suffix)
+char *suffix;
+#endif
+{
+ static char buf[200];
+ extern char *class_name;
+
+ sprintf(buf, "%s%s", class_name, suffix);
+ return buf;
+}
+
+#ifdef DEBUG
+
+/* print out a particular nfa node that is pointed to by p */
+
+#ifdef __USE_PROTOS
+void p_nfa_node(nfa_node *p)
+#else
+void p_nfa_node(p)
+nfa_node *p;
+#endif
+{
+#ifndef VBOX
+ register nfa_node *t;
+#endif
+
+ if (p != NIL_INDEX){
+ printf("NFA state : %d\naccept state : %d\n",
+ NFA_NO(p),p->accept);
+ if (p->trans[0] != NIL_INDEX){
+ printf("trans[0] => %d on ", NFA_NO(p->trans[0]));
+ p_set(p->label);
+ printf("\n");
+ }
+ else
+ printf("trans[0] => nil\n");
+ if (p->trans[1] != NIL_INDEX)
+ printf("trans[1] => %d on epsilon\n",
+ NFA_NO(p->trans[1]));
+ else
+ printf("trans[1] => nil\n");
+ printf("\n");
+ }
+}
+#endif
+
+#ifdef DEBUG
+
+/* code to print out special structures when using a debugger */
+
+#ifdef __USE_PROTOS
+# ifdef VBOX
+void p_nfa(nfa_node *p)
+# else
+void p_nfa(p)
+# endif
+#else
+void p_nfa(nfa_node *p)
+nfa_node *p; /* state number also index into array */
+#endif
+{
+/* each node has a marker on it so it only gets printed once */
+
+ operation_no++; /* get new number */
+ s_p_nfa(p);
+}
+
+#ifdef __USE_PROTOS
+void s_p_nfa(nfa_node *p)
+#else
+void s_p_nfa(p)
+nfa_node *p; /* state number also index into array */
+#endif
+{
+ if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){
+ /* so it is only printed once */
+ p->nfa_set = operation_no;
+ p_nfa_node(p);
+ s_p_nfa(p->trans[0]);
+ s_p_nfa(p->trans[1]);
+ }
+}
+
+#ifdef __USE_PROTOS
+void p_dfa_node(dfa_node *p)
+#else
+void p_dfa_node(p)
+dfa_node *p;
+#endif
+{
+ int i;
+
+ if (p != NIL_INDEX){
+ printf("DFA state :%d\n",NFA_NO(p));
+ if (p->done)
+ printf("done\n");
+ else
+ printf("undone\n");
+ printf("from nfa states : ");
+ p_set(p->nfa_states);
+ printf("\n");
+ /* NOTE: trans arcs stored as ints rather than pointer*/
+ for (i=0; i<class_no; i++){
+ printf("%d ",p->trans[i]);
+ }
+ printf("\n\n");
+ }
+}
+
+#ifdef __USE_PROTOS
+void p_dfa(void)
+#else
+void p_dfa()
+#endif
+{
+/* prints out all the dfa nodes actually allocated */
+
+ int i;
+
+ for (i = 1; i<=dfa_allocated; i++)
+#ifdef VBOX
+ p_dfa_node(DFA(i));
+#else
+ p_dfa_node(NFA(i));
+#endif
+}
+
+
+/* print out numbers in the set label */
+
+#ifdef __USE_PROTOS
+void p_set(set label)
+#else
+void p_set(label)
+set label;
+#endif
+{
+ unsigned *t, *e;
+
+ if (set_nil(label)){
+ printf("epsilon\n");
+ }else{
+ t = e = set_pdq(label);
+ while(*e != nil){
+ printf("%d ", (*e+MIN_CHAR));
+ e++;
+ }
+ printf("\n");
+ free(t);
+ }
+
+}
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/parser.dlg b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/parser.dlg
new file mode 100644
index 00000000..6cae5af4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/parser.dlg
@@ -0,0 +1,398 @@
+<<
+/* parser.dlg -- DLG Description of scanner
+ *
+ * Generated from: dlg_p.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#define ANTLR_VERSION 13333
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include <ctype.h>
+#include "dlg.h"
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+LOOKAHEAD
+
+void
+#ifdef __USE_PROTOS
+zzerraction(void)
+#else
+zzerraction()
+#endif
+{
+ (*zzerr)("invalid token");
+ zzadvance();
+ zzskip();
+}
+>>
+
+<<%%lexaction
+
+int func_action; /* should actions be turned into functions?*/
+int lex_mode_counter = 0; /* keeps track of the number of %%names */
+/* MR1 */
+/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+/* MR1 via <<%%lexmember...>> */
+/* MR1 */
+int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */
+int lexAction = 0; /* <<%%lexaction ...>> MR1 */
+int parserClass = 0; /* <<%%parserclass ...>> MR1 */
+int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */
+char theClassName[100]; /* MR11 */
+char *pClassName=theClassName; /* MR11 */
+int firstLexMember=1; /* MR1 */
+
+#ifdef __USE_PROTOS
+void xxputc(int c) { /* MR1 */
+#else
+ void xxputc(c) /* MR1 */
+ int c; /* MR1 */
+ { /* MR1 */
+#endif
+ if (parserClass) { /* MR1 */
+ *pClassName++=c; /* MR1 */
+ *pClassName=0; /* MR1 */
+ } else if (lexMember || lexPrefix) { /* MR1 */
+ if (class_stream != NULL) fputc(c,class_stream); /* MR1 */
+ } else { /* MR1 */
+ fputc(c,OUT); /* MR1 */
+ }; /* MR1 */
+ } /* MR1 */
+
+#ifdef __USE_PROTOS
+ void xxprintf(char *format,char *string) { /* MR1 */
+#else
+ void xxprintf(format,string) /* MR1 */
+ char *format; /* MR1 */
+ char *string; /* MR1 */
+ { /* MR1 */
+#endif
+ if (lexMember || lexPrefix || parserClass) { /* MR1 */
+ if (class_stream != NULL) /* MR1 */
+ fprintf(class_stream,format,string); /* MR1 */
+ } else { /* MR1 */
+ fprintf(OUT,format,string); /* MR1 */
+ }; /* MR1 */
+ } /* MR1 */
+>>
+
+
+%%START
+
+@
+ <<
+ NLA = 1;
+ >>
+
+[\r\t\ ]+
+ <<
+ NLA = 2;
+ zzskip();
+ >>
+
+\n
+ <<
+ NLA = 3;
+ zzline++; zzskip(); DAWDLE;
+ >>
+
+\@
+ <<
+ NLA = L_EOF;
+ >>
+
+\%\%
+ <<
+ NLA = PER_PER;
+ >>
+
+\%\%[a-zA-Z_][a-zA-Z0-9_]*
+ <<
+ NLA = NAME_PER_PER;
+ p_mode_def(&zzlextext[2],lex_mode_counter++);
+ >>
+
+\<\<\%\%lexmember
+ <<
+ NLA = LEXMEMBER;
+ lexMember=1; /* MR1 */
+ if (firstLexMember != 0) { /* MR1 */
+ firstLexMember=0; /* MR1 */
+ p_class_def1(); /* MR1 */
+ }; /* MR1 */
+ zzmode(ACT); /* MR1 */
+ >>
+
+\<\<\%\%lexaction
+ <<
+ NLA = LEXACTION;
+ lexAction=1;zzmode(ACT);
+ >>
+
+\<\<\%\%parserclass
+ <<
+ NLA = PARSERCLASS;
+ parserClass=1; /* MR1 */
+ zzmode(ACT); /* MR1 */
+ >>
+
+\<\<\%\%lexprefix
+ <<
+ NLA = LEXPREFIX;
+ lexPrefix=1;zzmode(ACT);
+ >>
+
+\<\<
+ <<
+ NLA = ACTION;
+ if (func_action)
+ fprintf(OUT,"\n%s %sact%d()\n{ ",
+ gen_cpp?"ANTLRTokenType":"static void",
+ gen_cpp?ClassName("::"):"", ++action_no);
+ zzmode(ACT); zzskip();
+ >>
+
+\>\>
+ <<
+ NLA = GREAT_GREAT;
+ >>
+
+\{
+ <<
+ NLA = L_BRACE;
+ >>
+
+\}
+ <<
+ NLA = R_BRACE;
+ >>
+
+\(
+ <<
+ NLA = L_PAR;
+ >>
+
+\)
+ <<
+ NLA = R_PAR;
+ >>
+
+\[
+ <<
+ NLA = L_BRACK;
+ >>
+
+\]
+ <<
+ NLA = R_BRACK;
+ >>
+
+\*
+ <<
+ NLA = ZERO_MORE;
+ >>
+
+\+
+ <<
+ NLA = ONE_MORE;
+ >>
+
+\|
+ <<
+ NLA = OR;
+ >>
+
+\-
+ <<
+ NLA = RANGE;
+ >>
+
+\~
+ <<
+ NLA = NOT;
+ >>
+
+\\0[0-7]*
+ <<
+ NLA = OCTAL_VALUE;
+ {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}
+ >>
+
+\\0[Xx][0-9a-fA-F]+
+ <<
+ NLA = HEX_VALUE;
+ {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}
+ >>
+
+\\[1-9][0-9]*
+ <<
+ NLA = DEC_VALUE;
+ {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}
+ >>
+
+\\t
+ <<
+ NLA = TAB;
+ zzlextext[0] = '\t';
+ >>
+
+\\n
+ <<
+ NLA = NL;
+ zzlextext[0] = '\n';
+ >>
+
+\\r
+ <<
+ NLA = CR;
+ zzlextext[0] = '\r';
+ >>
+
+\\b
+ <<
+ NLA = BS;
+ zzlextext[0] = '\b';
+ >>
+
+\\ \n
+ <<
+ NLA = CONTINUATION;
+ zzline++; zzskip();
+ >>
+
+\\~[tnrb]
+ <<
+ NLA = LIT;
+ zzlextext[0] = zzlextext[1];
+ >>
+
+~[\\]
+ <<
+ NLA = REGCHAR;
+ >>
+
+
+%%ACT
+
+@
+ <<
+ NLA = 1;
+ error("unterminated action", zzline); zzmode(START);
+ >>
+
+\>\>
+ <<
+ NLA = ACTION;
+ if (func_action) fprintf(OUT,"}\n\n");
+ zzmode(START);
+ /* MR1 */
+ /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
+ /* MR1 via <<%%lexmember ...>> */
+ /* MR1 This is a consequence of not saving actions */
+ /* MR1 */
+ /* MR1 */ parserClass=0;
+ /* MR1 */ lexPrefix=0;
+ /* MR1 */ lexAction=0;
+ /* MR1 */ lexMember=0;
+ >>
+
+\>
+ <<
+ NLA = 34;
+ xxputc(zzlextext[0]); zzskip();
+ >>
+
+\\\>
+ <<
+ NLA = 35;
+ xxputc('>'); zzskip();
+ >>
+
+\\
+ <<
+ NLA = 36;
+ xxputc('\\'); zzskip();
+ >>
+
+\n
+ <<
+ NLA = 37;
+ xxputc(zzlextext[0]); ++zzline; zzskip();
+ >>
+
+/\*
+ <<
+ NLA = 38;
+ zzmode(ACTION_COMMENTS); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >>
+
+//
+ <<
+ NLA = 39;
+ zzmode(ACTION_CPP_COMMENTS); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >>
+
+~[]
+ <<
+ NLA = 40;
+ xxputc(zzlextext[0]); zzskip();
+ >>
+
+
+%%ACTION_COMMENTS
+
+@
+ <<
+ NLA = 1;
+ >>
+
+\*/
+ <<
+ NLA = 41;
+ zzmode(ACT); /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >>
+
+[\n\r]
+ <<
+ NLA = 42;
+ zzline++; xxputc(zzlextext[0]); zzskip();
+ >>
+
+~[]
+ <<
+ NLA = 43;
+ xxputc(zzlextext[0]); zzskip();
+ >>
+
+
+%%ACTION_CPP_COMMENTS
+
+@
+ <<
+ NLA = 1;
+ >>
+
+[\n\r]
+ <<
+ NLA = 44;
+ zzmode(ACT); zzline++; /* MR1 */
+ xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
+ >>
+
+~[]
+ <<
+ NLA = 45;
+ xxputc(zzlextext[0]); zzskip();
+ >>
+
+%%
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c
new file mode 100644
index 00000000..1a5ac448
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c
@@ -0,0 +1,217 @@
+/* This group of functions does the character class compression.
+ It goes over the dfa and relabels the arcs with the partitions
+ of characters in the NFA. The partitions are stored in the
+ array class.
+
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "dlg.h"
+#ifdef MEMCHK
+#include "trax.h"
+#else
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif /* __STDC__ */
+#endif
+
+int class_no = CHAR_RANGE; /* number of classes for labels */
+int first_el[CHAR_RANGE]; /* first element in each class partition */
+set class_sets[CHAR_RANGE]; /* array holds partitions from class */
+ /* compression */
+
+/* goes through labels on NFA graph and partitions the characters into
+ * character classes. This reduces the amount of space required for each
+ * dfa node, since only one arc is required each class instead of one arc
+ * for each character
+ * level:
+ * 0 no compression done
+ * 1 remove unused characters from classes
+ * 2 compress equivalent characters into same class
+ *
+ * returns the number of character classes required
+ */
+#ifdef __USE_PROTOS
+int relabel(nfa_node* start,int level)
+#else
+int relabel(start,level)
+int level;
+nfa_node *start;
+#endif
+{
+ if (level){
+ set_free(used_classes);
+ partition(start,level);
+ label_with_classes(start);
+ }else{
+ /* classes equivalent to all characters in alphabet */
+ class_no = CHAR_RANGE;
+ }
+ return class_no;
+}
+
+/* makes character class sets for new labels */
+#ifdef __USE_PROTOS
+void partition(nfa_node* start,int level)
+#else
+void partition(start,level)
+nfa_node *start; /* beginning of nfa graph */
+int level; /* compression level to uses */
+#endif
+{
+ set current_class;
+ set unpart_chars;
+ set temp;
+
+ unpart_chars = set_dup(used_chars);
+#if 0
+ /* EOF (-1+1) alway in class 0 */
+ class_sets[0] = set_of(0);
+ first_el[0] = 0;
+ used_classes = set_of(0);
+ temp = set_dif(unpart_chars, class_sets[0]);
+ set_free(unpart_chars);
+ unpart_chars = temp;
+ class_no = 1;
+#else
+ class_no = 0;
+#endif
+ while (!set_nil(unpart_chars)){
+ /* don't look for equivalent labels if c <= 1 */
+ if (level <= 1){
+ current_class = set_of(set_int(unpart_chars));
+ }else{
+ current_class = set_dup(unpart_chars);
+ intersect_nfa_labels(start,&current_class);
+ }
+ set_orel(class_no,&used_classes);
+ first_el[class_no] = set_int(current_class);
+ class_sets[class_no] = current_class;
+ temp = set_dif(unpart_chars,current_class);
+ set_free(unpart_chars);
+ unpart_chars = temp;
+ ++class_no;
+ }
+
+ /* free unpart_chars -ATG 5/6/95 */
+ set_free(unpart_chars);
+
+#if 0
+ /* group all the other unused characters into a class */
+ set_orel(class_no,&used_classes);
+ first_el[class_no] = set_int(current_class);
+ class_sets[class_no] = set_dif(normal_chars,used_chars);
+ ++class_no;
+#endif
+}
+
+
+/* given pointer to beginning of graph and recursively walks it trying
+ * to find a maximal partition. This partition in returned in maximal_class
+ */
+#ifdef __USE_PROTOS
+void intersect_nfa_labels(nfa_node* start,set* maximal_class)
+#else
+void intersect_nfa_labels(start,maximal_class)
+nfa_node *start;
+set *maximal_class;
+#endif
+{
+ /* pick a new operation number */
+ ++operation_no;
+ r_intersect(start,maximal_class);
+}
+
+#ifdef __USE_PROTOS
+void r_intersect(nfa_node* start,set* maximal_class)
+#else
+void r_intersect(start,maximal_class)
+nfa_node *start;
+set * maximal_class;
+#endif
+{
+ set temp;
+
+ if(start && start->nfa_set != operation_no)
+ {
+ start->nfa_set = operation_no;
+ temp = set_and(*maximal_class,start->label);
+ if (!set_nil(temp))
+ {
+ set_free(*maximal_class);
+ *maximal_class = temp;
+ }else{
+ set_free(temp);
+ }
+ r_intersect(start->trans[0],maximal_class);
+ r_intersect(start->trans[1],maximal_class);
+ }
+}
+
+
+/* puts class labels in place of old character labels */
+#ifdef __USE_PROTOS
+void label_with_classes(nfa_node* start)
+#else
+void label_with_classes(start)
+nfa_node *start;
+#endif
+{
+ ++operation_no;
+ label_node(start);
+}
+
+#ifdef __USE_PROTOS
+void label_node(nfa_node *start)
+#else
+void label_node(start)
+nfa_node *start;
+#endif
+{
+ set new_label;
+ register int i;
+
+ /* only do node if it hasn't been done before */
+ if (start && start->nfa_set != operation_no){
+ start->nfa_set = operation_no;
+ new_label = empty;
+ for (i = 0; i<class_no; ++i){
+ /* if one element of class in old_label,
+ all elements are. */
+ if (set_el(first_el[i],start->label))
+ set_orel(i,&new_label);
+ }
+ set_free(start->label);
+ start->label = new_label;
+ /* do any nodes that can be reached from this one */
+ label_node(start->trans[0]);
+ label_node(start->trans[1]);
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/stdpccts.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/stdpccts.h
new file mode 100644
index 00000000..12c1c769
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/stdpccts.h
@@ -0,0 +1,26 @@
+#ifndef STDPCCTS_H
+#define STDPCCTS_H
+/*
+ * stdpccts.h -- P C C T S I n c l u d e
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33MR33
+ */
+
+#ifndef ANTLR_VERSION
+#define ANTLR_VERSION 13333
+#endif
+
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+#include <ctype.h>
+#include "dlg.h"
+#define zzSET_SIZE 8
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "mode.h"
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/support.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/support.c
new file mode 100644
index 00000000..47879da9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/support.c
@@ -0,0 +1,240 @@
+/*
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "dlg.h"
+#ifdef MEMCHK
+#include "trax.h"
+#else
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif /* __STDC__ */
+#endif
+
+int err_found = 0; /* indicates whether problem found */
+
+#ifdef __USE_PROTOS
+void internal_error(char *s, char *file,int line) /* MR9 23-Sep-97 */
+#else
+void internal_error(s,file,line) /* MR9 23-Sep-97 */
+char *s,*file;
+int line;
+#endif
+{
+ fprintf(stderr,s,file,line);
+ exit(PCCTS_EXIT_FAILURE);
+}
+
+#ifdef __USE_PROTOS
+char *dlg_malloc(int bytes,char *file,int line)
+#else
+char *dlg_malloc(bytes,file,line)
+int bytes;
+char *file;
+int line;
+#endif
+{
+ char *t;
+
+ t = (char *) malloc(bytes);
+ if (!t){
+ /* error */
+ internal_error("%s(%d): unable to allocate memory\n",
+ file,line);
+ }
+ return t;
+}
+
+
+#ifdef __USE_PROTOS
+char *dlg_calloc(int n,int bytes,char *file,int line)
+#else
+char *dlg_calloc(n,bytes,file,line)
+int n,bytes;
+char *file;
+int line;
+#endif
+{
+ char *t;
+
+ t = (char *) calloc(n,bytes);
+ if (!t){
+ /* error */
+ internal_error("%s(%d): unable to allocate memory\n",
+ file,line);
+ }
+ return t;
+}
+
+
+#ifdef __USE_PROTOS
+FILE *read_stream(char *name)
+#else
+FILE *read_stream(name)
+char *name;
+#endif
+{
+ FILE *f;
+
+ if (name){
+ if (name[0] == '-') {
+ fprintf(stderr, "dlg: invalid option: '%s'\n", name);
+ f = NULL;
+ }else{
+ f = fopen(name, "r");
+ if (f == NULL){
+ /* couldn't open file */
+ fprintf(stderr,
+ "dlg: Warning: Can't read file %s.\n",
+ name);
+ }
+ }
+ }else{
+ /* open stdin if nothing there */
+ f = stdin;
+ }
+ return f;
+}
+
+#ifdef __USE_PROTOS
+FILE *write_stream(char *name)
+#else
+FILE *write_stream(name)
+char *name;
+#endif
+{
+ FILE *f;
+
+ if (name){
+ if (name[0] == '-') {
+ fprintf(stderr, "dlg: invalid option: '%s'\n", name);
+ f = NULL;
+ }else{
+ f = fopen(OutMetaName(name), "w");
+ if (f == NULL){
+ /* couldn't open file */
+ fprintf(stderr,
+ "dlg: Warning: Can't write to file %s.\n",
+ name);
+ }
+ else
+#ifdef SPECIAL_FOPEN
+ special_fopen_actions(OutMetaName(name)); /* MR1 */
+#else
+ ; /* MR1 */
+#endif
+ }
+ }else{
+ /* open stdout if nothing there */
+ f = stdout;
+ }
+ return f;
+}
+
+
+#ifdef __USE_PROTOS
+void fatal(char *message,int line_no)
+#else
+void fatal(message,line_no)
+char *message;
+int line_no;
+#endif
+{
+ fprintf(stderr,ErrHdr,
+ (file_str[0] ? file_str[0] : "stdin"), line_no);
+ fprintf(stderr, " Fatal: %s\n", message);
+ exit(PCCTS_EXIT_FAILURE);
+}
+
+#ifdef __USE_PROTOS
+void error(char *message,int line_no)
+#else
+void error(message,line_no)
+char *message;
+int line_no;
+#endif
+{
+ fprintf(stderr,ErrHdr,
+ (file_str[0] ? file_str[0] : "stdin"), line_no);
+ fprintf(stderr, " Error: %s\n", message);
+ err_found = 1;
+}
+
+#ifdef __USE_PROTOS
+void warning(char *message,int line_no)
+#else
+void warning(message,line_no)
+char *message;
+int line_no;
+#endif
+{
+ fprintf(stderr,ErrHdr,
+ (file_str[0] ? file_str[0] : "stdin"), line_no);
+ fprintf(stderr, " Warning: %s\n", message);
+}
+
+/* MR10: Jeff Vincent
+ MR10: Changed to remove directory information from n only if
+ MR10: if OutputDirectory was changed by user (-o option)
+*/
+
+#ifdef __USE_PROTOS
+char *OutMetaName(char *n)
+#else
+char *OutMetaName(n)
+char *n;
+#endif
+{
+ static char *dir_sym = DirectorySymbol;
+ static char newname[MaxFileName+1];
+ char *p;
+
+ /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */
+ if (strcmp(OutputDirectory, TopDirectory) == 0)
+ return n;
+
+ /* p will point to filename without path information */
+ if ((p = strrchr(n, *dir_sym)) != NULL)
+ p++;
+ else
+ p = n;
+
+ /* Copy new output directory into newname[] */
+ strcpy(newname, OutputDirectory);
+
+ /* if new output directory does not have trailing dir_sym, add it! */
+ if (newname[strlen(newname)-1] != *dir_sym)
+ strcat(newname, dir_sym);
+
+ /* contatenate FILE NAME ONLY to new output directory */
+ strcat(newname, p);
+
+ return newname;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/tokens.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/tokens.h
new file mode 100644
index 00000000..bfa5b474
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/dlg/tokens.h
@@ -0,0 +1,133 @@
+#ifndef tokens_h
+#define tokens_h
+/* tokens.h -- List of labelled tokens and stuff
+ *
+ * Generated from: dlg_p.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001
+ * Purdue University Electrical Engineering
+ * ANTLR Version 1.33MR33
+ */
+#define zzEOF_TOKEN 1
+#define L_EOF 4
+#define PER_PER 5
+#define NAME_PER_PER 6
+#define LEXMEMBER 7
+#define LEXACTION 8
+#define PARSERCLASS 9
+#define LEXPREFIX 10
+#define ACTION 11
+#define GREAT_GREAT 12
+#define L_BRACE 13
+#define R_BRACE 14
+#define L_PAR 15
+#define R_PAR 16
+#define L_BRACK 17
+#define R_BRACK 18
+#define ZERO_MORE 19
+#define ONE_MORE 20
+#define OR 21
+#define RANGE 22
+#define NOT 23
+#define OCTAL_VALUE 24
+#define HEX_VALUE 25
+#define DEC_VALUE 26
+#define TAB 27
+#define NL 28
+#define CR 29
+#define BS 30
+#define CONTINUATION 31
+#define LIT 32
+#define REGCHAR 33
+
+#ifdef __USE_PROTOS
+void grammar(void);
+#else
+extern void grammar();
+#endif
+
+#ifdef __USE_PROTOS
+void start_states(void);
+#else
+extern void start_states();
+#endif
+
+#ifdef __USE_PROTOS
+void do_conversion(void);
+#else
+extern void do_conversion();
+#endif
+
+#ifdef __USE_PROTOS
+void rule_list(void);
+#else
+extern void rule_list();
+#endif
+
+#ifdef __USE_PROTOS
+void rule(void);
+#else
+extern void rule();
+#endif
+
+#ifdef __USE_PROTOS
+void reg_expr(void);
+#else
+extern void reg_expr();
+#endif
+
+#ifdef __USE_PROTOS
+void and_expr(void);
+#else
+extern void and_expr();
+#endif
+
+#ifdef __USE_PROTOS
+void repeat_expr(void);
+#else
+extern void repeat_expr();
+#endif
+
+#ifdef __USE_PROTOS
+void expr(void);
+#else
+extern void expr();
+#endif
+
+#ifdef __USE_PROTOS
+void atom_list(void);
+#else
+extern void atom_list();
+#endif
+
+#ifdef __USE_PROTOS
+void near_atom(void);
+#else
+extern void near_atom();
+#endif
+
+#ifdef __USE_PROTOS
+void atom(void);
+#else
+extern void atom();
+#endif
+
+#ifdef __USE_PROTOS
+void anychar(void);
+#else
+extern void anychar();
+#endif
+
+#endif
+extern SetWordType zzerr1[];
+extern SetWordType zzerr2[];
+extern SetWordType zzerr3[];
+extern SetWordType setwd1[];
+extern SetWordType zzerr4[];
+extern SetWordType zzerr5[];
+extern SetWordType zzerr6[];
+extern SetWordType setwd2[];
+extern SetWordType zzerr7[];
+extern SetWordType zzerr8[];
+extern SetWordType zzerr9[];
+extern SetWordType setwd3[];
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.cpp
new file mode 100644
index 00000000..85e668fe
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.cpp
@@ -0,0 +1,871 @@
+/* ANTLRParser.C
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include "pcctscfg.h"
+
+#include "pccts_stdlib.h"
+#include "pccts_stdarg.h"
+#include "pccts_string.h"
+#include "pccts_stdio.h"
+
+PCCTS_NAMESPACE_STD
+
+/* I have to put this here due to C++ limitation
+ * that you can't have a 'forward' decl for enums.
+ * I hate C++!!!!!!!!!!!!!!!
+ * Of course, if I could use real templates, this would go away.
+ */
+// MR1
+// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the
+// MR1 ANTLRTokenType enum
+// MR1
+
+enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999}; // MR1
+
+#define ANTLR_SUPPORT_CODE
+
+#include ATOKEN_H
+#include ATOKENBUFFER_H
+#include APARSER_H
+
+static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000; /* MR14 */
+static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000; /* MR14 */
+
+ /* L o o k a h e a d M a c r o s */
+
+/* maximum of 32 bits/unsigned int and must be 8 bits/byte;
+ * we only use 8 bits of it.
+ */
+SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = {
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080
+};
+
+char ANTLRParser::eMsgBuffer[500] = "";
+
+ANTLRParser::
+~ANTLRParser()
+{
+ delete [] token_type;
+ delete [] zzFAILtext; // MR16 Manfred Kogler
+}
+
+ANTLRParser::
+ANTLRParser(ANTLRTokenBuffer *_inputTokens,
+ int k,
+ int use_inf_look,
+ int dlook,
+ int ssize)
+{
+ LLk = k;
+ can_use_inf_look = use_inf_look;
+/* MR14 */ if (dlook != 0) {
+/* MR14 */ panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode");
+/* MR14 */
+/* MR14 */ };
+ demand_look = 0; /* demand_look = dlook; */
+ bsetsize = ssize;
+ guessing = 0;
+ token_tbl = NULL;
+ eofToken = (ANTLRTokenType)1;
+
+ // allocate lookahead buffer
+ token_type = new ANTLRTokenType[LLk];
+ lap = 0;
+ labase = 0;
+#ifdef ZZDEFER_FETCH
+ stillToFetch = 0; // MR19
+#endif
+ dirty = 0;
+ inf_labase = 0; // MR7
+ inf_last = 0; // MR7
+ /* prime lookahead buffer, point to inputTokens */
+ this->inputTokens = _inputTokens;
+ this->inputTokens->setMinTokens(k);
+ _inputTokens->setParser(this); // MR1
+ resynchConsumed=1; // MR8
+ zzFAILtext=NULL; // MR9
+ traceOptionValueDefault=0; // MR10
+ traceReset(); // MR10
+ zzGuessSeq=0; // MR10
+ syntaxErrCount=0; // MR11
+}
+
+void ANTLRParser::init()
+{
+ prime_lookahead();
+ resynchConsumed=1; // MR8
+ traceReset(); // MR10
+}
+
+void ANTLRParser::traceReset()
+{
+ traceOptionValue=traceOptionValueDefault;
+ traceGuessOptionValue=1;
+ traceCurrentRuleName=NULL;
+ traceDepth=0;
+}
+
+
+#ifdef _MSC_VER // MR23
+//Turn off warning:
+//interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning(disable : 4611)
+#endif
+int ANTLRParser::
+guess(ANTLRParserState *st)
+{
+ saveState(st);
+ guessing = 1;
+ return setjmp(guess_start.state);
+}
+#ifdef _MSC_VER // MR23
+#pragma warning(default: 4611)
+#endif
+
+void ANTLRParser::
+saveState(ANTLRParserState *buf)
+{
+ buf->guess_start = guess_start;
+ buf->guessing = guessing;
+ buf->inf_labase = inf_labase;
+ buf->inf_last = inf_last;
+ buf->dirty = dirty;
+ buf->traceOptionValue=traceOptionValue; /* MR10 */
+ buf->traceGuessOptionValue=traceGuessOptionValue; /* MR10 */
+ buf->traceCurrentRuleName=traceCurrentRuleName; /* MR10 */
+ buf->traceDepth=traceDepth; /* MR10 */
+}
+
+void ANTLRParser::
+restoreState(ANTLRParserState *buf)
+{
+ int i;
+ int prevTraceOptionValue;
+
+ guess_start = buf->guess_start;
+ guessing = buf->guessing;
+ inf_labase = buf->inf_labase;
+ inf_last = buf->inf_last;
+ dirty = buf->dirty;
+
+ // restore lookahead buffer from k tokens before restored TokenBuffer position
+ // if demand_look, then I guess we don't look backwards for these tokens.
+ for (i=1; i<=LLk; i++) token_type[i-1] =
+ inputTokens->bufferedToken(i-LLk)->getType();
+ lap = 0;
+ labase = 0;
+
+ /* MR10 */
+
+ prevTraceOptionValue=traceOptionValue;
+ traceOptionValue=buf->traceOptionValue;
+ if ( (prevTraceOptionValue > 0) !=
+ (traceOptionValue > 0)) {
+ if (traceCurrentRuleName != NULL) { /* MR21 */
+ if (traceOptionValue > 0) {
+ /* MR23 */ printMessage(stderr,
+ "trace enable restored in rule %s depth %d\n",
+ traceCurrentRuleName,
+ traceDepth);
+ };
+ if (traceOptionValue <= 0) {
+ /* MR23 */ printMessage(stderr,
+ "trace disable restored in rule %s depth %d\n",
+ traceCurrentRuleName, /* MR21 */
+ traceDepth);
+ };
+ }
+ };
+ traceGuessOptionValue=buf->traceGuessOptionValue;
+ traceCurrentRuleName=buf->traceCurrentRuleName;
+ traceDepth=buf->traceDepth;
+ traceGuessDone(buf);
+}
+
+/* Get the next symbol from the input stream; put it into lookahead buffer;
+ * fill token_type[] fast reference cache also. NLA is the next place where
+ * a lookahead ANTLRAbstractToken should go.
+ */
+void ANTLRParser::
+consume()
+{
+
+#ifdef ZZDEBUG_CONSUME_ACTION
+ zzdebug_consume_action();
+#endif
+
+// MR19 V.H. Simonis
+// Defer Fetch feature
+// Moves action of consume() into LA() function
+
+#ifdef ZZDEFER_FETCH
+ stillToFetch++;
+#else
+ NLA = inputTokens->getToken()->getType();
+ dirty--;
+ lap = (lap+1)&(LLk-1);
+#endif
+
+}
+
+_ANTLRTokenPtr ANTLRParser::
+LT(int i)
+{
+
+// MR19 V.H. Simonis
+// Defer Fetch feature
+// Moves action of consume() into LA() function
+
+#ifdef ZZDEFER_FETCH
+ undeferFetch();
+#endif
+
+#ifdef DEBUG_TOKENBUFFER
+ if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */
+ {
+ char buf[2000]; /* MR20 Was "static" */
+ sprintf(buf, "The minimum number of tokens you requested that the\nANTLRTokenBuffer buffer is not enough to satisfy your\nLT(%d) request; increase 'k' argument to constructor for ANTLRTokenBuffer\n", i);
+ panic(buf);
+ }
+#endif
+ return inputTokens->bufferedToken(i-LLk);
+}
+
+void
+ANTLRParser::
+look(int k)
+{
+ int i, c = k - (LLk-dirty);
+ for (i=1; i<=c; i++) consume();
+}
+
+/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK);
+ */
+void
+ANTLRParser::
+prime_lookahead()
+{
+ int i;
+ for(i=1;i<=LLk; i++) consume();
+ dirty=0;
+ // lap = 0; // MR14 Sinan Karasu (sinan.karasu@boeing.com)
+ // labase = 0; // MR14
+ labase=lap; // MR14
+}
+
+/* check to see if the current input symbol matches '_t'.
+ * During NON demand lookahead mode, dirty will always be 0 and
+ * hence the extra code for consuming tokens in _match is never
+ * executed; the same routine can be used for both modes.
+ */
+int ANTLRParser::
+_match(ANTLRTokenType _t, ANTLRChar **MissText,
+ ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
+ SetWordType **MissSet)
+{
+ if ( dirty==LLk ) {
+ consume();
+ }
+ if ( LA(1)!=_t ) {
+ *MissText=NULL;
+ *MissTok= _t;
+ *BadTok = LT(1);
+ *MissSet=NULL;
+ return 0;
+ }
+ dirty++;
+ labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
+ return 1;
+}
+
+/* check to see if the current input symbol matches '_t'.
+ * Used during exception handling.
+ */
+int ANTLRParser::
+_match_wsig(ANTLRTokenType _t)
+{
+ if ( dirty==LLk ) {
+ consume();
+ }
+ if ( LA(1)!=_t ) return 0;
+ dirty++;
+ labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
+ return 1;
+}
+
+/* check to see if the current input symbol matches any token in a set.
+ * During NON demand lookahead mode, dirty will always be 0 and
+ * hence the extra code for consuming tokens in _match is never
+ * executed; the same routine can be used for both modes.
+ */
+int ANTLRParser::
+_setmatch(SetWordType *tset, ANTLRChar **MissText,
+ ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok,
+ SetWordType **MissSet, SetWordType *tokclassErrset)
+{
+ if ( dirty==LLk ) {
+ consume();
+ }
+ if ( !set_el(LA(1), tset) ) {
+ *MissText=NULL; /* MR23 */
+ *MissTok=(ANTLRTokenType) 0; /* MR23 */
+ *BadTok=LT(1); /* MR23 */
+ *MissSet=tokclassErrset; /* MR23 */
+ return 0;
+ }
+ dirty++;
+ labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
+ return 1;
+}
+
+int ANTLRParser::
+_setmatch_wsig(SetWordType *tset)
+{
+ if ( dirty==LLk ) {
+ consume();
+ }
+ if ( !set_el(LA(1), tset) ) return 0;
+ dirty++;
+ labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
+ return 1;
+}
+
+ /* Exception handling routines */
+//
+// 7-Apr-97 133MR1
+// Change suggested by Eli Sternheim (eli@interhdl.com)
+//
+void ANTLRParser::
+consumeUntil(SetWordType *st)
+{
+ ANTLRTokenType tmp; // MR1
+ const int Eof=1; // MR1
+ while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); } // MR1
+}
+
+//
+// 7-Apr-97 133MR1
+// Change suggested by Eli Sternheim (eli@interhdl.com)
+//
+void ANTLRParser::
+consumeUntilToken(int t)
+{
+ int tmp; // MR1
+ const int Eof=1; // MR1
+ while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); } // MR1
+}
+
+
+ /* Old error stuff */
+
+void ANTLRParser::
+resynch(SetWordType *wd,SetWordType mask)
+{
+
+/* MR8 S.Bochnak@microtool.com.pl */
+/* MR8 Change file scope static "consumed" to instance var */
+
+ /* if you enter here without having consumed a token from last resynch
+ * force a token consumption.
+ */
+/* MR8 */ if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;}
+
+ /* if current token is in resynch set, we've got what we wanted */
+
+/* MR8 */ if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;}
+
+ /* scan until we find something in the resynch set */
+
+ while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();}
+
+/* MR8 */ resynchConsumed=1;
+}
+
+/* standard error reporting function that assumes DLG-based scanners;
+ * you should redefine in subclass to change it or if you use your
+ * own scanner.
+ */
+
+/* MR23 THM There appears to be a parameter "badText" passed to syn()
+ which is not present in the parameter list. This may be
+ because in C mode there is no attribute function which
+ returns the text, so the text representation of the token
+ must be passed explicitly. I think.
+*/
+
+void ANTLRParser::
+syn(_ANTLRTokenPtr /*tok MR23*/, ANTLRChar *egroup, SetWordType *eset,
+ ANTLRTokenType etok, int k)
+{
+ int line;
+
+ line = LT(1)->getLine();
+
+ syntaxErrCount++; /* MR11 */
+
+ /* MR23 If the token is not an EOF token, then use the ->getText() value.
+
+ If the token is the EOF token the text returned by ->getText()
+ may be garbage. If the text from the token table is "@" use
+ "<eof>" instead, because end-users don't know what "@" means.
+ If the text is not "@" then use that text, which must have been
+ supplied by the grammar writer.
+ */
+ const char * errorAt = LT(1)->getText();
+ if (LA(1) == eofToken) {
+ errorAt = parserTokenName(LA(1));
+ if (errorAt[0] == '@') errorAt = "<eof>";
+ }
+ /* MR23 */ printMessage(stderr, "line %d: syntax error at \"%s\"",
+ line, errorAt);
+ if ( !etok && !eset ) {/* MR23 */ printMessage(stderr, "\n"); return;}
+ if ( k==1 ) /* MR23 */ printMessage(stderr, " missing");
+ else
+ {
+ /* MR23 */ printMessage(stderr, "; \"%s\" not", LT(k)->getText()); // MR23 use LT(k) since k>1
+ if ( set_deg(eset)>1 ) /* MR23 */ printMessage(stderr, " in");
+ }
+ if ( set_deg(eset)>0 ) edecode(eset);
+ else /* MR23 */ printMessage(stderr, " %s", token_tbl[etok]);
+ if ( strlen(egroup) > 0 ) /* MR23 */ printMessage(stderr, " in %s", egroup);
+ /* MR23 */ printMessage(stderr, "\n");
+}
+
+/* is b an element of set p? */
+int ANTLRParser::
+set_el(ANTLRTokenType b, SetWordType *p)
+{
+ return( p[DIVWORD(b)] & bitmask[MODWORD(b)] );
+}
+
+int ANTLRParser::
+set_deg(SetWordType *a)
+{
+ /* Fast compute degree of a set... the number
+ of elements present in the set. Assumes
+ that all word bits are used in the set
+ */
+ register SetWordType *p = a;
+ register SetWordType *endp = &(a[bsetsize]);
+ register int degree = 0;
+
+ if ( a == NULL ) return 0;
+ while ( p < endp )
+ {
+ register SetWordType t = *p;
+ register SetWordType *b = &(bitmask[0]);
+ do {
+ if (t & *b) ++degree;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ p++;
+ }
+
+ return(degree);
+}
+
+void ANTLRParser::
+edecode(SetWordType *a)
+{
+ register SetWordType *p = a;
+ register SetWordType *endp = &(p[bsetsize]);
+ register unsigned e = 0;
+
+ if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " {");
+ do {
+ register SetWordType t = *p;
+ register SetWordType *b = &(bitmask[0]);
+ do {
+ if ( t & *b ) /* MR23 */ printMessage(stderr, " %s", token_tbl[e]);
+ e++;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ } while (++p < endp);
+ if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " }");
+}
+
+/* input looks like:
+ * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk)
+ * where the zzMiss stuff is set here to the token that did not match
+ * (and which set wasn't it a member of).
+ */
+
+// MR9 29-Sep-97 Stan Bochnak (S.Bochnak@microTool.com.pl)
+// MR9 Original fix to static allocated text didn't
+// MR9 work because a pointer to it was passed back
+// MR9 to caller. Replace with instance variable.
+
+const int SETWORDCOUNT=20;
+
+void
+ANTLRParser::FAIL(int k, ...)
+{
+//
+// MR1 10-Apr-97
+//
+
+ if (zzFAILtext == NULL) zzFAILtext=new char [1000]; // MR9
+ SetWordType **f=new SetWordType *[SETWORDCOUNT]; // MR1 // MR9
+ SetWordType **miss_set;
+ ANTLRChar **miss_text;
+ _ANTLRTokenPtr *bad_tok;
+ ANTLRChar **bad_text;
+//
+// 7-Apr-97 133MR1
+// err_k is passed as a "int *", not "unsigned *"
+//
+ int *err_k; // MR1
+ int i;
+ va_list ap;
+
+ va_start(ap, k);
+
+ zzFAILtext[0] = '\0';
+ if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer");
+ for (i=1; i<=k; i++) /* collect all lookahead sets */
+ {
+ f[i-1] = va_arg(ap, SetWordType *);
+ }
+ for (i=1; i<=k; i++) /* look for offending token */
+ {
+ if ( i>1 ) strcat(zzFAILtext, " ");
+ strcat(zzFAILtext, LT(i)->getText());
+ if ( !set_el(LA(i), f[i-1]) ) break;
+ }
+ miss_set = va_arg(ap, SetWordType **);
+ miss_text = va_arg(ap, ANTLRChar **);
+ bad_tok = va_arg(ap, _ANTLRTokenPtr *);
+ bad_text = va_arg(ap, ANTLRChar **);
+ err_k = va_arg(ap, int *); // MR1
+ if ( i>k )
+ {
+ /* bad; lookahead is permutation that cannot be matched,
+ * but, the ith token of lookahead is valid at the ith position
+ * (The old LL sub 1 (k) versus LL(k) parsing technique)
+ */
+ *miss_set = NULL;
+ *miss_text = LT(1)->getText();
+ *bad_tok = LT(1);
+ *bad_text = (*bad_tok)->getText();
+ *err_k = k;
+//
+// MR4 20-May-97 erroneously deleted contents of f[]
+// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)
+// MR1 10-Apr-97 release temporary storage
+//
+ delete [] f; // MR1
+ return; // MR1
+ }
+/* MR23 printMessage(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/
+ *miss_set = f[i-1];
+ *miss_text = zzFAILtext;
+ *bad_tok = LT(i);
+ *bad_text = (*bad_tok)->getText();
+ if ( i==1 ) *err_k = 1;
+ else *err_k = k;
+//
+// MR4 20-May-97 erroneously deleted contents of f[]
+// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca)
+// MR1 10-Apr-97 release temporary storage
+//
+ delete [] f; // MR1
+ return; // MR1
+}
+
+int ANTLRParser::
+_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows)
+{
+ if ( dirty==LLk ) consume();
+
+ if ( LA(1)!=tokenWanted )
+ {
+ syntaxErrCount++; /* MR11 */
+ /* MR23 */ printMessage(stderr,
+ "line %d: syntax error at \"%s\" missing %s\n",
+ LT(1)->getLine(),
+ (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
+ token_tbl[tokenWanted]);
+ consumeUntil( whatFollows );
+ return 0;
+ }
+ else {
+ dirty++;
+ labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
+/* if ( !demand_look ) consume(); */
+ return 1;
+ }
+}
+
+
+int ANTLRParser::
+_setmatch_wdfltsig(SetWordType *tokensWanted,
+ ANTLRTokenType tokenTypeOfSet,
+ SetWordType *whatFollows)
+{
+ if ( dirty==LLk ) consume();
+ if ( !set_el(LA(1), tokensWanted) )
+ {
+ syntaxErrCount++; /* MR11 */
+ /* MR23 */ printMessage(stderr,
+ "line %d: syntax error at \"%s\" missing %s\n",
+ LT(1)->getLine(),
+ (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"<eof>":LT(1)->getText(), /* MR21a */
+ token_tbl[tokenTypeOfSet]);
+ consumeUntil( whatFollows );
+ return 0;
+ }
+ else {
+ dirty++;
+ labase = (labase+1)&(LLk-1); // labase maintained even if !demand look
+/* if ( !demand_look ) consume(); */
+ return 1;
+ }
+}
+
+char *ANTLRParser::
+eMsgd(char *err,int d)
+{
+ sprintf(eMsgBuffer, err, d); // dangerous, but I don't care
+ return eMsgBuffer;
+}
+
+char *ANTLRParser::
+eMsg(char *err, char *s)
+{
+ sprintf(eMsgBuffer, err, s);
+ return eMsgBuffer;
+}
+
+char *ANTLRParser::
+eMsg2(char *err,char *s, char *t)
+{
+ sprintf(eMsgBuffer, err, s, t);
+ return eMsgBuffer;
+}
+
+void ANTLRParser::
+panic(const char *msg) // MR20 const
+{
+ /* MR23 */ printMessage(stderr, "ANTLR panic: %s\n", msg);
+ exit(PCCTS_EXIT_FAILURE); // MR1
+}
+
+const ANTLRChar *ANTLRParser:: // MR1
+parserTokenName(int tok) { // MR1
+ return token_tbl[tok]; // MR1
+} // MR1
+
+void ANTLRParser::traceGuessDone(const ANTLRParserState *state) {
+
+ int doIt=0;
+
+ if (traceCurrentRuleName == NULL) return;
+
+ if (traceOptionValue <= 0) {
+ doIt=0;
+ } else if (traceGuessOptionValue <= 0) {
+ doIt=0;
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ /* MR23 */ printMessage(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",
+ state->traceCurrentRuleName,
+ LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
+ state->traceDepth);
+ if (state->guessing != 0) {
+ /* MR23 */ printMessage(stderr," (guess mode continues - an enclosing guess is still active)");
+ } else {
+ /* MR23 */ printMessage(stderr," (guess mode ends)");
+ };
+ /* MR23 */ printMessage(stderr,"\n");
+ };
+}
+
+void ANTLRParser::traceGuessFail() {
+
+ int doIt=0;
+
+ if (traceCurrentRuleName == NULL) return; /* MR21 */
+
+ if (traceOptionValue <= 0) {
+ doIt=0;
+ } else if (guessing && traceGuessOptionValue <= 0) {
+ doIt=0;
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ /* MR23 */ printMessage(stderr,"guess failed in %s\n",traceCurrentRuleName);
+ };
+}
+
+/* traceOption:
+ zero value turns off trace
+*/
+
+void ANTLRParser::tracein(const ANTLRChar * rule) {
+
+ int doIt=0;
+
+ traceDepth++;
+ traceCurrentRuleName=rule;
+
+ if (traceOptionValue <= 0) {
+ doIt=0;
+ } else if (guessing && traceGuessOptionValue <= 0) {
+ doIt=0;
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ /* MR23 */ printMessage(stderr,"enter rule %s {\"%s\"} depth %d",
+ rule,
+ LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
+ traceDepth);
+ if (guessing) /* MR23 */ printMessage(stderr," guessing");
+ /* MR23 */ printMessage(stderr,"\n");
+ };
+ return;
+}
+
+void ANTLRParser::traceout(const ANTLRChar * rule) {
+
+ int doIt=0;
+
+ traceDepth--;
+
+ if (traceOptionValue <= 0) {
+ doIt=0;
+ } else if (guessing && traceGuessOptionValue <= 0) {
+ doIt=0;
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ /* MR23 */ printMessage(stderr,"exit rule %s {\"%s\"} depth %d",
+ rule,
+ LT(1)->getType() == eofToken ? "@" : LT(1)->getText(),
+ traceDepth+1);
+ if (guessing) /* MR23 */ printMessage(stderr," guessing");
+ /* MR23 */ printMessage(stderr,"\n");
+ };
+}
+
+int ANTLRParser::traceOption(int delta) {
+
+ int prevValue=traceOptionValue;
+
+ traceOptionValue=traceOptionValue+delta;
+
+ if (traceCurrentRuleName != NULL) {
+ if (prevValue <= 0 && traceOptionValue > 0) {
+ /* MR23 */ printMessage(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
+ };
+ if (prevValue > 0 && traceOptionValue <= 0) {
+ /* MR23 */ printMessage(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
+ };
+ };
+
+ return prevValue;
+}
+
+int ANTLRParser::traceGuessOption(int delta) {
+
+ int prevValue=traceGuessOptionValue;
+
+ traceGuessOptionValue=traceGuessOptionValue+delta;
+
+ if (traceCurrentRuleName != NULL) {
+ if (prevValue <= 0 && traceGuessOptionValue > 0) {
+ /* MR23 */ printMessage(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
+ };
+ if (prevValue > 0 && traceGuessOptionValue <= 0) {
+ /* MR23 */ printMessage(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth);
+ };
+ };
+ return prevValue;
+}
+
+// MR19 V.H. Simonis Defer Fetch feature
+
+void ANTLRParser::undeferFetch()
+{
+
+#ifdef ZZDEFER_FETCH
+ if (stillToFetch) {
+ for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) {
+ NLA = inputTokens->getToken()->getType();
+ dirty--;
+ lap = (lap+1)&(LLk-1);
+ }
+ stillToFetch = 0;
+ }
+#else
+ return;
+#endif
+
+}
+
+int ANTLRParser::isDeferFetchEnabled()
+{
+#ifdef ZZDEFER_FETCH
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//MR23
+int ANTLRParser::printMessage(FILE* pFile, const char* pFormat, ...)
+{
+ va_list marker;
+ va_start( marker, pFormat );
+ int iRet = printMessageV(pFile, pFormat, marker);
+ va_end( marker );
+ return iRet;
+}
+
+int ANTLRParser::printMessageV(FILE* pFile, const char* pFormat, va_list arglist) // MR23
+{
+ return vfprintf(pFile, pFormat, arglist);
+}
+
+// MR23 Move semantic predicate error handling from macro to virtual function
+//
+// Called by the zzfailed_pred
+
+void ANTLRParser::failedSemanticPredicate(const char* predicate)
+{
+ printMessage(stdout,"line %d: semantic error; failed predicate: '%s'\n",
+ LT(1)->getLine(), predicate);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.h
new file mode 100644
index 00000000..659f8b2c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AParser.h
@@ -0,0 +1,376 @@
+/* ANTLRParser.h
+ *
+ * Define the generic ANTLRParser superclass, which is subclassed to
+ * define an actual parser.
+ *
+ * Before entry into this file: ANTLRTokenType must be set.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef APARSER_H_GATE
+#define APARSER_H_GATE
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+#include "pccts_setjmp.h"
+
+PCCTS_NAMESPACE_STD
+
+#include ATOKEN_H
+#include ATOKENBUFFER_H
+
+#ifdef ZZCAN_GUESS
+#ifndef ZZINF_LOOK
+#define ZZINF_LOOK
+#endif
+#endif
+
+
+#define NLA (token_type[lap&(LLk-1)])/* --> next LA */
+
+typedef unsigned char SetWordType;
+
+/* Define external bit set stuff (for SetWordType) */
+#define EXT_WORDSIZE (sizeof(char)*8)
+#define EXT_LOGWORDSIZE 3
+
+ /* s y n t a c t i c p r e d i c a t e s t u f f */
+
+#ifndef zzUSER_GUESS_HOOK
+#define zzUSER_GUESS_HOOK(seqFrozen,zzrv)
+#endif
+
+#ifndef zzUSER_GUESS_DONE_HOOK
+#define zzUSER_GUESS_DONE_HOOK(seqFrozen)
+#endif
+
+/* MR14 Add zzUSER_GUESS_FAIL_HOOK and related code */
+
+#define zzUSER_GUESS_FAIL_HOOK_INTERNAL zzUSER_GUESS_FAIL_HOOK(SeqFrozen)
+#ifndef zzUSER_GUESS_FAIL_HOOK
+#define zzUSER_GUESS_FAIL_HOOK(zzGuessSeq)
+#endif
+
+
+typedef struct _zzjmp_buf {
+ jmp_buf state;
+ } zzjmp_buf;
+
+/* these need to be macros not member functions */
+#define zzGUESS_BLOCK ANTLRParserState zzst; int zzrv; int _marker; int zzGuessSeqFrozen;
+#define zzNON_GUESS_MODE if ( !guessing )
+#define zzGUESS_FAIL guess_fail();
+
+/* Note: zzGUESS_DONE does not execute longjmp() */
+
+#define zzGUESS_DONE {zzrv=1; inputTokens->rewind(_marker); guess_done(&zzst);zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }
+#define zzGUESS saveState(&zzst); \
+ guessing = 1; \
+ zzGuessSeqFrozen = ++zzGuessSeq; \
+ _marker = inputTokens->mark(); \
+ zzrv = setjmp(guess_start.state); \
+ zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \
+ if ( zzrv ) zzGUESS_DONE
+
+#define zzTRACEdata const ANTLRChar *zzTracePrevRuleName = NULL;
+
+#ifndef zzTRACEIN
+#define zzTRACEIN(r) zzTracePrevRuleName=traceCurrentRuleName;tracein(r);
+#endif
+#ifndef zzTRACEOUT
+#define zzTRACEOUT(r) traceout(r);traceCurrentRuleName=zzTracePrevRuleName;
+#endif
+
+ /* a n t l r p a r s e r d e f */
+
+struct ANTLRParserState {
+ /* class variables */
+ zzjmp_buf guess_start;
+ int guessing;
+
+ int inf_labase;
+ int inf_last;
+
+ int dirty;
+
+ int traceOptionValue; // MR10
+ int traceGuessOptionValue; // MR10
+ const ANTLRChar *traceCurrentRuleName; // MR10
+ int traceDepth; // MR10
+
+};
+
+/* notes:
+ *
+ * multiple inheritance is a cool way to include what stuff is needed
+ * in this structure (like guess stuff). however, i'm not convinced that
+ * multiple inheritance works correctly on all platforms. not that
+ * much space is used--just include all possibly useful members.
+ *
+ * the class should also be a template with arguments for the lookahead
+ * depth and so on. that way, more than one parser can be defined (as
+ * each will probably have different lookahead requirements). however,
+ * am i sure that templates work? no, i'm not sure.
+ *
+ * no attributes are maintained and, hence, the 'asp' variable is not
+ * needed. $i can still be referenced, but it refers to the token
+ * associated with that rule element. question: where are the token's
+ * stored if not on the software stack? in local variables created
+ * and assigned to by antlr.
+ */
+class ANTLRParser {
+protected:
+ /* class variables */
+ static SetWordType bitmask[sizeof(SetWordType)*8];
+ static char eMsgBuffer[500];
+
+protected:
+ int LLk; // number of lookahead symbols (old LL_K)
+ int demand_look;
+ ANTLRTokenType eofToken; // when do I stop during resynch()s
+ int bsetsize; // size of bitsets created by ANTLR in
+ // units of SetWordType
+
+ ANTLRTokenBuffer *inputTokens; //place to get input tokens
+
+ zzjmp_buf guess_start; // where to jump back to upon failure
+ int guessing; // if guessing (using (...)? predicate)
+
+ // infinite lookahead stuff
+ int can_use_inf_look; // set by subclass (generated by ANTLR)
+ int inf_lap;
+ int inf_labase;
+ int inf_last;
+ int *_inf_line;
+
+ const ANTLRChar **token_tbl; // pointer to table of token type strings MR20 const
+
+ int dirty; // used during demand lookahead
+
+ ANTLRTokenType *token_type; // fast reference cache of token.getType()
+// ANTLRLightweightToken **token; // the token with all its attributes
+ int lap;
+ int labase;
+#ifdef ZZDEFER_FETCH
+ int stillToFetch; // MR19 V.H. Simonis
+#endif
+
+private:
+ void fill_inf_look();
+
+protected:
+ virtual void guess_fail() { // MR9 27-Sep-97 make virtual
+ traceGuessFail(); // MR10
+ longjmp(guess_start.state, 1); } // MR9
+ virtual void guess_done(ANTLRParserState *st) { // MR9 27-Sep-97 make virtual
+ restoreState(st); } // MR9
+ virtual int guess(ANTLRParserState *); // MR9 27-Sep-97 make virtual
+ void look(int);
+ int _match(ANTLRTokenType, ANTLRChar **, ANTLRTokenType *,
+ _ANTLRTokenPtr *, SetWordType **);
+ int _setmatch(SetWordType *, ANTLRChar **, ANTLRTokenType *,
+ _ANTLRTokenPtr *, SetWordType **,
+ SetWordType * tokclassErrset /* MR23 */);
+ int _match_wsig(ANTLRTokenType);
+ int _setmatch_wsig(SetWordType *);
+ virtual void consume();
+ virtual void resynch(SetWordType *wd,SetWordType mask); // MR21
+ void prime_lookahead();
+ virtual void tracein(const ANTLRChar *r); // MR10
+ virtual void traceout(const ANTLRChar *r); // MR10
+ static unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);} // x % EXT_WORDSIZE // MR9
+ static unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;} // x / EXT_WORDSIZE // MR9
+ int set_deg(SetWordType *);
+ int set_el(ANTLRTokenType, SetWordType *);
+ virtual void edecode(SetWordType *); // MR1
+ virtual void FAIL(int k, ...); // MR1
+ int traceOptionValue; // MR10
+ int traceGuessOptionValue; // MR10
+ const ANTLRChar *traceCurrentRuleName; // MR10
+ int traceDepth; // MR10
+ void traceReset(); // MR10
+ virtual void traceGuessFail(); // MR10
+ virtual void traceGuessDone(const ANTLRParserState *); // MR10
+ int zzGuessSeq; // MR10
+
+public:
+ ANTLRParser(ANTLRTokenBuffer *,
+ int k=1,
+ int use_inf_look=0,
+ int demand_look=0,
+ int bsetsize=1);
+ virtual ~ANTLRParser();
+
+ virtual void init();
+
+ ANTLRTokenType LA(int i)
+ {
+//
+// MR14 demand look will always be 0 for C++ mode
+//
+//// return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] :
+//// token_type[(lap+(i)-1)&(LLk-1)];
+
+// MR19 V.H. Simonis Defer fetch feature
+
+#ifdef ZZDEFER_FETCH
+ undeferFetch();
+#endif
+ return token_type[(lap+(i)-1)&(LLk-1)];
+ }
+ _ANTLRTokenPtr LT(int i);
+
+ void setEofToken(ANTLRTokenType t) { eofToken = t; }
+ ANTLRTokenType getEofToken() const { return eofToken; } // MR14
+
+ void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); }
+ void garbageCollectTokens() { inputTokens->garbageCollectTokens(); }
+
+ virtual void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup,
+ SetWordType *eset, ANTLRTokenType etok, int k);
+ virtual void saveState(ANTLRParserState *); // MR9 27-Sep-97 make virtual
+ virtual void restoreState(ANTLRParserState *); // MR9 27-Sep-97 make virtual
+
+ virtual void panic(const char *msg); // MR20 const
+
+ static char *eMsgd(char *,int);
+ static char *eMsg(char *,char *);
+ static char *eMsg2(char *,char *,char *);
+
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23
+ virtual int printMessageV(FILE* pFile, const char* pFormat, va_list arglist); // MR23
+
+ void consumeUntil(SetWordType *st);
+ void consumeUntilToken(int t);
+
+ virtual int _setmatch_wdfltsig(SetWordType *tokensWanted,
+ ANTLRTokenType tokenTypeOfSet,
+ SetWordType *whatFollows);
+ virtual int _match_wdfltsig(ANTLRTokenType tokenWanted,
+ SetWordType *whatFollows);
+
+ const ANTLRChar * parserTokenName(int tok); // MR1
+
+ int traceOptionValueDefault; // MR11
+ int traceOption(int delta); // MR11
+ int traceGuessOption(int delta); // MR11
+
+// MR8 5-Aug-97 S.Bochnak@microtool.com.pl
+// MR8 Move resynch static local variable
+// MR8 to class instance
+
+ int syntaxErrCount; // MR12
+ ANTLRTokenStream *getLexer() const { // MR12
+ return inputTokens ? inputTokens->getLexer() : 0; } // MR12
+protected: // MR8
+ int resynchConsumed; // MR8
+ char *zzFAILtext; // workarea required by zzFAIL // MR9
+ void undeferFetch(); // MR19 V.H. Simonis
+ int isDeferFetchEnabled(); // MR19 V.H. Simonis
+ virtual void failedSemanticPredicate(const char* predicate); /* MR23 */
+};
+
+#define zzmatch(_t) \
+ if ( !_match((ANTLRTokenType)_t, &zzMissText, &zzMissTok, \
+ (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail;
+
+#define zzmatch_wsig(_t,handler) \
+ if ( !_match_wsig((ANTLRTokenType)_t) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}
+
+#define zzsetmatch(_ts,_tokclassErrset) \
+ if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \
+ (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail;
+
+#define zzsetmatch_wsig(_ts, handler) \
+ if ( !_setmatch_wsig(_ts) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;}
+
+/* For the dflt signal matchers, a FALSE indicates that an error occurred
+ * just like the other matchers, but in this case, the routine has already
+ * recovered--we do NOT want to consume another token. However, when
+ * the match was successful, we do want to consume hence _signal=0 so that
+ * a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;"
+ * preamble.
+ */
+#define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \
+ if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \
+ _signal = MismatchedToken;
+
+#define zzmatch_wdfltsig(tokenWanted, whatFollows) \
+ if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken;
+
+
+// MR1 10-Apr-97 zzfailed_pred() macro does not backtrack in guess mode.
+// MR1 Identification and correction due to J. Lilley
+//
+// MR23 Call virtual method to report error.
+// MR23 Provide more control over failed predicate action
+// without any need for user to worry about guessing internals.
+
+#ifndef zzfailed_pred
+#define zzfailed_pred(_p,_hasuseraction,_useraction) \
+ if (guessing) { \
+ zzGUESS_FAIL; \
+ } else { \
+ zzfailed_pred_action(_p,_hasuseraction,_useraction) \
+ }
+#endif
+
+// MR23 Provide more control over failed predicate action
+// without any need for user to worry about guessing internals.
+// _hasuseraction == 0 => no user specified error action
+// _hasuseraction == 1 => user specified error action
+
+#ifndef zzfailed_pred_action
+#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \
+ if (_hasuseraction) { _useraction } else { failedSemanticPredicate(_p); }
+#endif
+
+#define zzRULE \
+ SetWordType *zzMissSet=NULL; ANTLRTokenType zzMissTok=(ANTLRTokenType)0; \
+ _ANTLRTokenPtr zzBadTok=NULL; ANTLRChar *zzBadText=(ANTLRChar *)""; \
+ int zzErrk=1,zzpf=0; \
+ zzTRACEdata \
+ ANTLRChar *zzMissText=(ANTLRChar *)"";
+
+#endif
+
+ /* S t a n d a r d E x c e p t i o n S i g n a l s */
+
+#define NoSignal 0
+#define MismatchedToken 1
+#define NoViableAlt 2
+#define NoSemViableAlt 3
+
+/* MR7 Allow more control over signalling */
+/* by adding "Unwind" and "SetSignal" */
+
+#define Unwind 4
+#define setSignal(newValue) *_retsignal=_signal=(newValue)
+#define suppressSignal *_retsignal=_signal=0
+#define exportSignal *_retsignal=_signal
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.cpp
new file mode 100644
index 00000000..a3cf8c0a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.cpp
@@ -0,0 +1,256 @@
+/* Abstract syntax tree manipulation functions
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+#include "pccts_stdarg.h"
+
+PCCTS_NAMESPACE_STD
+
+#define ANTLR_SUPPORT_CODE
+
+#include "ASTBase.h"
+
+/* ensure that tree manipulation variables are current after a rule
+ * reference
+ */
+void
+ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
+{
+ if ( *_sibling == NULL ) return;
+ if ( *_root == NULL ) *_root = *_sibling;
+ else if ( *_root != *_sibling ) (*_root)->_down = *_sibling;
+ if ( *_tail==NULL ) *_tail = *_sibling;
+ while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right;
+}
+
+/* add a child node to the current sibling list */
+void
+ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
+{
+ if ( *_tail != NULL ) (*_tail)->_right = this;
+ else {
+ *_sibling = this;
+ if ( *_root != NULL ) (*_root)->_down = *_sibling;
+ }
+ *_tail = this;
+ if ( *_root == NULL ) *_root = *_sibling;
+}
+
+/* make a new AST node. Make the newly-created
+ * node the root for the current sibling list. If a root node already
+ * exists, make the newly-created node the root of the current root.
+ */
+void
+ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail)
+{
+ if ( *_root != NULL )
+ if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root;
+ *_root = this;
+ (*_root)->_down = *_sibling;
+}
+
+/* Apply preorder_action(), etc.. to root then each sibling */
+//
+// 7-Apr-97 133MR1
+// Fix suggested by Ron House (house@helios.usq.edu.au)
+//
+void
+ASTBase::preorder(void* pData /*= NULL*/ /* MR23 */)
+{
+ ASTBase *tree = this;
+
+ while ( tree!= NULL )
+ {
+ if ( tree->_down != NULL ) {
+ tree->preorder_before_action(pData); // MR1
+ };
+ tree->preorder_action(pData);
+ if ( tree->_down!=NULL )
+ {
+ tree->_down->preorder(pData);
+ tree->preorder_after_action(pData); // MR1
+ }
+ tree = tree->_right;
+ }
+}
+
+/* free all AST nodes in tree; apply func to each before freeing */
+void
+ASTBase::destroy()
+{
+ ASTBase* tree = this;
+ while (tree) {
+ if (tree->_down) tree->_down->destroy();
+
+ ASTBase* cur = tree;
+ tree = tree->_right;
+ delete cur;
+ }
+}
+
+/* build a tree (root child1 child2 ... NULL)
+ * If root is NULL, simply make the children siblings and return ptr
+ * to 1st sibling (child1). If root is not single node, return NULL.
+ *
+ * Siblings that are actually siblins lists themselves are handled
+ * correctly. For example #( NULL, #( NULL, A, B, C), D) results
+ * in the tree ( NULL A B C D ).
+ *
+ * Requires at least two parameters with the last one being NULL. If
+ * both are NULL, return NULL.
+ */
+ASTBase *
+ASTBase::tmake(ASTBase *root, ...)
+{
+ va_list ap;
+ register ASTBase *child, *sibling=NULL, *tail=NULL /*MR23*/, *w;
+
+ va_start(ap, root);
+
+ if ( root != NULL )
+ if ( root->_down != NULL ) {
+ root->reportOverwriteOfDownPointer(); /* MR21 Report problem which almost always an error */
+ return NULL;
+ }
+ child = va_arg(ap, ASTBase *);
+ while ( child != NULL )
+ {
+ for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */
+ if ( sibling == NULL ) {sibling = child; tail = w;}
+ else {tail->_right = child; tail = w;}
+ child = va_arg(ap, ASTBase *);
+ }
+ if ( root==NULL ) root = sibling;
+ else root->_down = sibling;
+ va_end(ap);
+ return root;
+}
+
+#ifndef PCCTS_NOT_USING_SOR
+
+/* tree duplicate */
+// forgot to check for NULL this (TJP July 23,1995)
+ASTBase *
+ASTBase::dup()
+{
+ ASTBase *u, *t=this;
+
+ if ( t == NULL ) return NULL;
+/*
+ u = new ASTBase;
+ *u = *t;
+*/
+ u = (ASTBase *)this->shallowCopy();
+ if ( t->_right!=NULL ) u->_right = t->_right->dup();
+ else u->_right = NULL;
+ if ( t->_down!=NULL ) u->_down = t->_down->dup();
+ else u->_down = NULL;
+ return u;
+}
+#endif
+
+//
+// 7-Apr-97 133MR1
+// Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com)
+//
+/* tree duplicate */
+
+#ifndef PCCTS_NOT_USING_SOR
+
+ASTBase *
+ASTDoublyLinkedBase::dup()
+{
+ ASTDoublyLinkedBase *u, *t=this;
+
+ if ( t == NULL ) return NULL;
+ u = (ASTDoublyLinkedBase *)this->shallowCopy();
+ u->_up = NULL; /* set by calling invocation */
+ u->_left = NULL;
+ if (t->_right!=NULL) { // MR1
+ u->_right=t->_right->dup(); // MR1
+ ((ASTDoublyLinkedBase *)u->_right)->_left = u; // MR1
+ } else { // MR1
+ u->_right = NULL; // MR1
+ }; // MR1
+ if (t->_down!=NULL) { // MR1
+ u->_down = t->_down->dup(); // MR1
+ ((ASTDoublyLinkedBase *)u->_down)->_up = u; // MR1
+ } else { // MR1
+ u->_down = NULL; // MR1
+ }; // MR1
+ return u;
+}
+
+#endif
+
+/*
+ * Set the 'up', and 'left' pointers of all nodes in 't'.
+ * Initial call is double_link(your_tree, NULL, NULL).
+ */
+void
+ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up)
+{
+ ASTDoublyLinkedBase *t = this;
+
+ t->_left = (ASTDoublyLinkedBase *) left;
+ t->_up = (ASTDoublyLinkedBase *) up;
+ if (t->_down != NULL)
+ ((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t);
+ if (t->_right != NULL)
+ ((ASTDoublyLinkedBase *)t->_right)->double_link(t, up);
+}
+
+// MR21 ASTBase::reportOverwriteOfDownPointer
+
+void ASTBase::reportOverwriteOfDownPointer()
+{
+ panic("Attempt to overwrite down pointer in ASTBase::tmake");
+}
+
+// MR21 ASTBase::panic
+
+void ASTBase::panic(const char *msg)
+{
+ /* MR23 */ printMessage(stderr,"ASTBase panic: %s\n", msg);
+ exit(PCCTS_EXIT_FAILURE);
+}
+
+#ifdef PCCTS_NOT_USING_SOR
+//MR23
+int ASTBase::printMessage(FILE* pFile, const char* pFormat, ...)
+{
+ va_list marker;
+ va_start( marker, pFormat );
+ int iRet = vfprintf(pFile, pFormat, marker);
+ va_end( marker );
+ return iRet;
+}
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.h
new file mode 100644
index 00000000..9085fe57
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ASTBase.h
@@ -0,0 +1,122 @@
+/* Abstract syntax tree
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ASTBase_H
+#define ASTBase_H
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+#include "pccts_stdlib.h"
+
+PCCTS_NAMESPACE_STD
+
+#ifndef PCCTS_NOT_USING_SOR
+#include "PCCTSAST.h"
+#endif
+
+/*
+ * Notes:
+ *
+ * To specify a copy constructor, subclass one of these classes and
+ * give the copy constructor. To use dup(), you must define shallowCopy().
+ * shallowCopy() can use either a copy constructor or just copy the node
+ * itself.
+ */
+
+#ifdef PCCTS_NOT_USING_SOR
+class DllExportPCCTS ASTBase {
+#else
+class DllExportPCCTS ASTBase : public PCCTS_AST {
+#endif
+
+protected:
+ ASTBase *_right, *_down;
+
+public:
+
+#ifdef PCCTS_NOT_USING_SOR
+ ASTBase *right() { return _right; }
+ ASTBase *down() { return _down; }
+ void setRight(ASTBase *t) { _right = (ASTBase *)t; }
+ void setDown(ASTBase *t) { _down = (ASTBase *)t; }
+#else
+ PCCTS_AST *right() { return _right; } // define the SORCERER interface
+ PCCTS_AST *down() { return _down; }
+ void setRight(PCCTS_AST *t) { _right = (ASTBase *)t; }
+ void setDown(PCCTS_AST *t) { _down = (ASTBase *)t; }
+#endif
+ ASTBase() { _right = _down = NULL; }
+ virtual ~ASTBase() { ; }
+#ifndef PCCTS_NOT_USING_SOR
+ virtual ASTBase *dup();
+#endif
+ void destroy();
+ void preorder(void* pData = NULL /* MR23 */);
+ static ASTBase *tmake(ASTBase *, ...);
+ static void link(ASTBase **, ASTBase **, ASTBase **);
+ void subchild(ASTBase **, ASTBase **, ASTBase **);
+ void subroot(ASTBase **, ASTBase **, ASTBase **);
+ virtual void preorder_action(void* /*pData*/ = NULL /* MR23 */) { ; }
+ virtual void preorder_before_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " ("); }
+ virtual void preorder_after_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " )"); }
+ virtual void panic(const char *msg); /* MR21 */
+ virtual void reportOverwriteOfDownPointer(); /* MR21 */
+#ifdef PCCTS_NOT_USING_SOR
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23
+#endif
+};
+
+class DllExportPCCTS ASTDoublyLinkedBase : public ASTBase {
+protected:
+ ASTDoublyLinkedBase *_left, *_up;
+
+public:
+ void double_link(ASTBase *left, ASTBase *up);
+
+#ifndef PCCTS_NOT_USING_SOR
+ virtual ASTBase *dup();
+#endif
+
+#ifdef PCCTS_NOT_USING_SOR
+ ASTBase *left() { return _left; }
+ ASTBase *up() { return _up; }
+ void setLeft(ASTBase *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6
+ void setUp(ASTBase *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6
+#else
+ PCCTS_AST *left() { return _left; }
+ PCCTS_AST *up() { return _up; }
+ void setLeft(PCCTS_AST *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6
+ void setUp(PCCTS_AST *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6
+#endif
+
+};
+
+class AST; // announce that this class will be coming along shortly
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtr.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtr.h
new file mode 100644
index 00000000..5ccc8376
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtr.h
@@ -0,0 +1,88 @@
+/* ATokPtr.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Written by Russell Quong June 30, 1995
+ * Adapted by Terence Parr to ANTLR stuff
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ATokPtr_h
+#define ATokPtr_h
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+
+PCCTS_NAMESPACE_STD
+
+// pointer to a reference counted object
+// robust in that an unused ANTLRTokenPtr can point to NULL.
+
+class ANTLRAbstractToken;
+
+class DllExportPCCTS ANTLRTokenPtr {
+public:
+ ANTLRTokenPtr(ANTLRAbstractToken *addr=NULL){ptr_ = addr; ref();}
+ ANTLRTokenPtr(const ANTLRTokenPtr &lhs) {ptr_ = lhs.ptr_; lhs.ref();}
+ ~ANTLRTokenPtr();
+
+ // use ANTLRTokenPtr as a pointer to ANTLRToken
+//
+// 8-Apr-97 MR1 Make operator -> a const member function
+// as well as some other member functions
+//
+ ANTLRAbstractToken *operator-> () const { return ptr_; } // MR1
+//
+// 7-Apr-97 133MR1
+// Fix suggested by Andreas Magnusson
+// (Andreas.Magnusson@mailbox.swipnet.se)
+ ANTLRTokenPtr& operator = (const ANTLRTokenPtr & lhs); // MR1
+ ANTLRTokenPtr& operator = (ANTLRAbstractToken *addr);
+ int operator != (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int
+ { return this->ptr_ != q.ptr_; }
+ int operator == (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int
+ { return this->ptr_ == q.ptr_; }
+ int operator == (const ANTLRAbstractToken *addr) const // MR11
+ { return this->ptr_ == addr; }
+ int operator != (const ANTLRAbstractToken *addr) const // MR11
+ { return this->ptr_ != addr; }
+
+ void ref() const;
+ void deref();
+
+protected:
+ ANTLRAbstractToken *ptr_;
+};
+
+//typedef ANTLRTokenPtr _ANTLRTokenPtr;
+
+/*
+ * Since you cannot redefine operator->() to return one of the user's
+ * token object types, we must down cast. This is a drag. Here's
+ * a macro that helps. template: "mytoken(a-smart-ptr)->myfield".
+ */
+#define mytoken(tk) ((ANTLRToken *)(tk.operator->()))
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtrImpl.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtrImpl.h
new file mode 100644
index 00000000..48d2e18a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokPtrImpl.h
@@ -0,0 +1,90 @@
+/*
+ * ATokPtrImpl.h (formerly ATokPtr.cpp)
+ *
+ * This is #included in ATokBuffer.cpp for historical reasons.
+ * It has been renamed because of problems with the .cpp extension
+ * when used with IDE.
+ *
+ *
+ * ANTLRToken MUST be defined before entry to this file.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Written by Russell Quong June 30, 1995
+ * Adapted by Terence Parr to ANTLR stuff
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include "pcctscfg.h"
+
+PCCTS_NAMESPACE_STD
+
+#include "ATokPtr.h"
+
+void ANTLRTokenPtr::ref() const
+{
+ if (ptr_ != NULL) {
+ ptr_->ref();
+ }
+}
+
+void ANTLRTokenPtr::deref()
+{
+ if (ptr_ != NULL)
+ {
+ ptr_->deref();
+ if ( ptr_->nref()==0 )
+ {
+ delete ptr_;
+ ptr_ = NULL;
+ }
+ }
+}
+
+ANTLRTokenPtr::~ANTLRTokenPtr()
+{
+ deref();
+}
+
+//
+// 8-Apr-97 MR1 Make operator -> a const member function
+// as well as some other member functions
+//
+ANTLRTokenPtr& ANTLRTokenPtr::operator = (const ANTLRTokenPtr & lhs) // MR1
+{
+ lhs.ref(); // protect against "xp = xp"; ie same underlying object
+ deref();
+ ptr_ = lhs.ptr_;
+ return *this;
+}
+
+ANTLRTokenPtr& ANTLRTokenPtr::operator = (ANTLRAbstractToken *addr)
+{
+ if (addr != NULL) {
+ addr->ref();
+ }
+ deref();
+ ptr_ = addr;
+ return *this;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AToken.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AToken.h
new file mode 100644
index 00000000..a6360124
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/AToken.h
@@ -0,0 +1,325 @@
+/* ANTLRToken.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ATOKEN_H_GATE
+#define ATOKEN_H_GATE
+
+#include "pcctscfg.h"
+
+#include "pccts_string.h"
+#include "pccts_stdio.h"
+#include "pccts_stdlib.h"
+#include "pccts_stdarg.h" // MR23
+
+PCCTS_NAMESPACE_STD
+
+// MR9 RJV (JVincent@novell.com) Not needed for variable length strings
+
+//// MR9 #ifndef ANTLRCommonTokenTEXTSIZE
+//// MR9 #define ANTLRCommonTokenTEXTSIZE 100
+//// MR9 #endif
+
+
+/* must define what a char looks like; can make this a class too */
+typedef char ANTLRChar;
+
+/* D E F I N E S M A R T P O I N T E R S */
+
+//#include ATOKPTR_H not tested yet, leave out
+class ANTLRAbstractToken;
+typedef ANTLRAbstractToken *_ANTLRTokenPtr;
+
+class ANTLRAbstractToken {
+public:
+ virtual ~ANTLRAbstractToken() {;}
+ virtual ANTLRTokenType getType() const = 0;
+ virtual void setType(ANTLRTokenType t) = 0;
+ virtual int getLine() const = 0;
+ virtual void setLine(int line) = 0;
+ virtual ANTLRChar *getText() const = 0;
+ virtual void setText(const ANTLRChar *) = 0;
+
+ /* This function will disappear when I can use templates */
+ virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
+ ANTLRChar *text,
+ int line) = 0;
+
+ /* define to satisfy ANTLRTokenBuffer's need to determine whether or
+ not a token object can be destroyed. If nref()==0, no one has
+ a reference, and the object may be destroyed. This function defaults
+ to 1, hence, if you use deleteTokens() message with a token object
+ not derived from ANTLRCommonRefCountToken, the parser will compile
+ but will not delete objects after they leave the token buffer.
+ */
+
+ virtual unsigned nref() const { return 1; } // MR11
+ virtual void ref() {;}
+ virtual void deref() {;}
+
+ virtual void panic(const char *msg) // MR20 const
+ {
+ /* MR23 */ printMessage(stderr, "ANTLRAbstractToken panic: %s\n", msg);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...) // MR23
+ {
+ va_list marker;
+ va_start( marker, pFormat );
+ int iRet = vfprintf(pFile, pFormat, marker);
+ va_end( marker );
+ return iRet;
+ }
+};
+
+/* This class should be subclassed. It cannot store token type or text */
+
+class ANTLRRefCountToken : public ANTLRAbstractToken {
+public:
+#ifdef DBG_REFCOUNTTOKEN
+ static int ctor;
+ static int dtor;
+#endif
+protected:
+ unsigned refcnt_;
+#ifdef DBG_REFCOUNTTOKEN
+ char object[200];
+#endif
+
+public:
+
+ // MR23 - No matter what you do, you're hammered.
+ // Don't give names to formals something breaks.
+ // Give names to formals and don't use them it breaks.
+
+#ifndef DBG_REFCOUNTTOKEN
+ ANTLRRefCountToken(ANTLRTokenType /* t MR23 */, const ANTLRChar * /* s MR23 */)
+#else
+ ANTLRRefCountToken(ANTLRTokenType t, const ANTLRChar * s)
+#endif
+
+#ifndef DBG_REFCOUNTTOKEN
+ {
+ refcnt_ = 0;
+ }
+#else
+ {
+ ctor++;
+ refcnt_ = 0;
+ if ( t==1 ) sprintf(object,"tok_EOF");
+ else sprintf(object,"tok_%s",s);
+ /* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor);
+ }
+#endif
+ ANTLRRefCountToken()
+#ifndef DBG_REFCOUNTTOKEN
+ { refcnt_ = 0; }
+#else
+ {
+ ctor++;
+ refcnt_ = 0;
+ sprintf(object,"tok_blank");
+ /* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor);
+ }
+ virtual ~ANTLRRefCountToken()
+ {
+ dtor++;
+ if ( dtor>ctor ) /* MR23 */ printMessage(stderr, "WARNING: dtor>ctor\n");
+ /* MR23 */ printMessage(stderr, "dtor %s #%d\n", object, dtor);
+ object[0]='\0';
+ }
+#endif
+
+ // reference counting stuff needed by ANTLRTokenPtr.
+ // User should not access these; for C++ language reasons, we had
+ // to make these public. Yuck.
+
+ void ref() { refcnt_++; }
+ void deref() { refcnt_--; }
+ unsigned nref() const { return refcnt_; } // MR11
+
+ virtual ANTLRAbstractToken *makeToken(ANTLRTokenType /*tt MR23*/,
+ ANTLRChar * /*txt MR23*/,
+ int /*line MR23*/)
+ {
+ panic("call to ANTLRRefCountToken::makeToken()\n");
+ return NULL;
+ }
+};
+
+class ANTLRCommonNoRefCountToken : public ANTLRAbstractToken {
+protected:
+ ANTLRTokenType _type;
+ int _line;
+ ANTLRChar *_text; // MR9 RJV
+
+public:
+ ANTLRCommonNoRefCountToken(ANTLRTokenType t, const ANTLRChar *s)
+ { setType(t); _line = 0; _text = NULL; setText(s); }
+ ANTLRCommonNoRefCountToken()
+ { setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); }
+
+ ~ANTLRCommonNoRefCountToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string
+
+ ANTLRTokenType getType() const { return _type; }
+ void setType(ANTLRTokenType t) { _type = t; }
+ virtual int getLine() const { return _line; }
+ void setLine(int line) { _line = line; }
+ ANTLRChar *getText() const { return _text; }
+ int getLength() const { return strlen(getText()); } // MR11
+
+// MR9 RJV: Added code for variable length strings to setText()
+
+ void setText(const ANTLRChar *s)
+ { if (s != _text) {
+ if (_text) delete [] _text;
+ if (s != NULL) {
+ _text = new ANTLRChar[strlen(s)+1];
+ if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed");
+ strcpy(_text,s);
+ } else {
+ _text = new ANTLRChar[1];
+ if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed");
+ strcpy(_text,"");
+ };
+ };
+ }
+
+ virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
+ ANTLRChar *txt,
+ int line)
+ {
+ ANTLRAbstractToken *t = new ANTLRCommonNoRefCountToken;
+ t->setType(tt); t->setText(txt); t->setLine(line);
+ return t;
+ }
+
+// MR9 THM Copy constructor required when heap allocated string is used with copy semantics
+
+ ANTLRCommonNoRefCountToken (const ANTLRCommonNoRefCountToken& from) :
+ ANTLRAbstractToken(from) {
+ setType(from._type);
+ setLine(from._line);
+ _text=NULL;
+ setText(from._text);
+ };
+
+// MR9 THM operator =() required when heap allocated string is used with copy semantics
+
+ virtual ANTLRCommonNoRefCountToken& operator =(const ANTLRCommonNoRefCountToken& rhs) {
+
+////// MR15 WatCom can't hack use of operator =()
+////// Use this: *( (ANTRLAbstractToken *) this)=rhs;
+
+ *( (ANTLRAbstractToken *) this ) = rhs;
+
+ setType(rhs._type);
+ setLine(rhs._line);
+ setText(rhs._text);
+ return *this;
+ };
+};
+
+class ANTLRCommonToken : public ANTLRRefCountToken {
+protected:
+ ANTLRTokenType _type;
+ int _line;
+ ANTLRChar *_text; // MR9 RJV:Added
+
+public:
+ ANTLRCommonToken(ANTLRTokenType t, const ANTLRChar *s) : ANTLRRefCountToken(t,s)
+ { setType(t); _line = 0; _text = NULL; setText(s); } // MR9
+ ANTLRCommonToken()
+ { setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); } // MR9
+
+ virtual ~ANTLRCommonToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string
+
+ ANTLRTokenType getType() const { return _type; }
+ void setType(ANTLRTokenType t) { _type = t; }
+ virtual int getLine() const { return _line; }
+ void setLine(int line) { _line = line; }
+ ANTLRChar *getText() const { return _text; }
+ int getLength() const { return strlen(getText()); } // MR11
+
+// MR9 RJV: Added code for variable length strings to setText()
+
+ void setText(const ANTLRChar *s)
+ { if (s != _text) {
+ if (_text) delete [] _text;
+ if (s != NULL) {
+ _text = new ANTLRChar[strlen(s)+1];
+ if (_text == NULL) panic("ANTLRCommonToken::setText new failed");
+ strcpy(_text,s);
+ } else {
+ _text = new ANTLRChar[1];
+ if (_text == NULL) panic("ANTLRCommonToken::setText new failed");
+ strcpy(_text,"");
+ };
+ };
+ }
+
+ virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt,
+ ANTLRChar *txt,
+ int line)
+ {
+ ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt);
+ t->setLine(line);
+ return t;
+ }
+
+// MR9 THM Copy constructor required when heap allocated string is used with copy semantics
+
+ ANTLRCommonToken (const ANTLRCommonToken& from) :
+ ANTLRRefCountToken(from) {
+ setType(from._type);
+ setLine(from._line);
+ _text=NULL;
+ setText(from._text);
+ };
+
+// MR9 THM operator =() required when heap allocated string is used with copy semantics
+
+ virtual ANTLRCommonToken& operator =(const ANTLRCommonToken& rhs) {
+
+////// MR15 WatCom can't hack use of operator =()
+////// Use this instead: *( (ANTRLRRefCountToken *) this)=rhs;
+
+ *( (ANTLRRefCountToken *) this) = rhs;
+
+ setType(rhs._type);
+ setLine(rhs._line);
+ setText(rhs._text);
+ return *this;
+ };
+};
+
+// used for backward compatibility
+typedef ANTLRCommonToken ANTLRCommonBacktrackingToken;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.cpp
new file mode 100644
index 00000000..86073d54
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.cpp
@@ -0,0 +1,374 @@
+/* ANTLRTokenBuffer.cpp
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+typedef int ANTLRTokenType; // fool AToken.h into compiling
+
+class ANTLRParser; /* MR1 */
+
+#define ANTLR_SUPPORT_CODE
+
+#include "pcctscfg.h"
+
+#include ATOKENBUFFER_H
+#include APARSER_H // MR23
+
+typedef ANTLRAbstractToken *_ANTLRTokenPtr;
+
+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
+static unsigned char test[1000];
+#endif
+
+#ifdef DBG_REFCOUNTTOKEN
+int ANTLRRefCountToken::ctor = 0; /* MR23 */
+int ANTLRRefCountToken::dtor = 0; /* MR23 */
+#endif
+
+ANTLRTokenBuffer::
+ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */
+{
+ this->input = _input;
+ this->k = _k;
+ buffer_size = chunk_size = _chunk_size_formal;
+ buffer = (_ANTLRTokenPtr *)
+ calloc(chunk_size+1,sizeof(_ANTLRTokenPtr ));
+ if ( buffer == NULL ) {
+ panic("cannot alloc token buffer");
+ }
+ buffer++; // leave the first elem empty so tp-1 is valid ptr
+
+ tp = &buffer[0];
+ last = tp-1;
+ next = &buffer[0];
+ num_markers = 0;
+ end_of_buffer = &buffer[buffer_size-1];
+ threshold = &buffer[(int)(buffer_size/2)]; // MR23 - Used to be 1.0/2.0 !
+ _deleteTokens = 1; // assume we delete tokens
+ parser=NULL; // MR5 - uninitialized reference
+}
+
+static void f() {;}
+ANTLRTokenBuffer::
+~ANTLRTokenBuffer()
+{
+ f();
+ // Delete all remaining tokens (from 0..last inclusive)
+ if ( _deleteTokens )
+ {
+ _ANTLRTokenPtr *z;
+ for (z=buffer; z<=last; z++)
+ {
+ (*z)->deref();
+// z->deref();
+#ifdef DBG_REFCOUNTTOKEN
+ /* MR23 */ printMessage(stderr, "##########dtor: deleting token '%s' (ref %d)\n",
+ ((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
+#endif
+ if ( (*z)->nref()==0 )
+ {
+ delete (*z);
+ }
+ }
+ }
+
+ if ( buffer!=NULL ) free((char *)(buffer-1));
+}
+
+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
+#include "pccts_stdio.h"
+PCCTS_NAMESPACE_STD
+#endif
+
+_ANTLRTokenPtr ANTLRTokenBuffer::
+getToken()
+{
+ if ( tp <= last ) // is there any buffered lookahead still to be read?
+ {
+ return *tp++; // read buffered lookahead
+ }
+ // out of buffered lookahead, get some more "real"
+ // input from getANTLRToken()
+ if ( num_markers==0 )
+ {
+ if( next > threshold )
+ {
+#ifdef DBG_TBUF
+/* MR23 */ printMessage(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);
+#endif
+ makeRoom();
+ }
+ }
+ else {
+ if ( next > end_of_buffer )
+ {
+#ifdef DBG_TBUF
+/* MR23 */ printMessage(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);
+#endif
+ extendBuffer();
+ }
+ }
+ *next = getANTLRToken();
+ (*next)->ref(); // say we have a copy of this pointer in buffer
+ last = next;
+ next++;
+ tp = last;
+ return *tp++;
+}
+
+void ANTLRTokenBuffer::
+rewind(int pos)
+{
+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
+ /* MR23 */ printMessage(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]);
+ test[pos]--;
+#endif
+ tp = &buffer[pos];
+ num_markers--;
+}
+
+/*
+ * This function is used to specify that the token pointers read
+ * by the ANTLRTokenBuffer should be buffered up (to be reused later).
+ */
+int ANTLRTokenBuffer::
+mark()
+{
+#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
+ test[tp-buffer]++;
+ /* MR23 */ printMessage(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]);
+#endif
+ num_markers++;
+ return tp - buffer;
+}
+
+/*
+ * returns the token pointer n positions ahead.
+ * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
+ * This is used in conjunction with the ANTLRParser lookahead buffer.
+ *
+ * No markers are set or anything. A bunch of input is buffered--that's all.
+ * The tp pointer is left alone as the lookahead has not been advanced
+ * with getToken(). The next call to getToken() will find a token
+ * in the buffer and won't have to call getANTLRToken().
+ *
+ * If this is called before a consume() is done, how_many_more_i_need is
+ * set to 'n'.
+ */
+_ANTLRTokenPtr ANTLRTokenBuffer::
+bufferedToken(int n)
+{
+// int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;
+ int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1;
+ // Make sure that at least n tokens are available in the buffer
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr, "bufferedToken(%d)\n", n);
+#endif
+ for (int i=1; i<=how_many_more_i_need; i++)
+ {
+ if ( next > end_of_buffer ) // buffer overflow?
+ {
+ extendBuffer();
+ }
+ *next = getANTLRToken();
+ (*next)->ref(); // say we have a copy of this pointer in buffer
+ last = next;
+ next++;
+ }
+ return tp[n - 1];
+}
+
+/* If no markers are set, the none of the input needs to be saved (except
+ * for the lookahead Token pointers). We save only k-1 token pointers as
+ * we are guaranteed to do a getANTLRToken() right after this because otherwise
+ * we wouldn't have needed to extend the buffer.
+ *
+ * If there are markers in the buffer, we need to save things and so
+ * extendBuffer() is called.
+ */
+void ANTLRTokenBuffer::
+makeRoom()
+{
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr, "in makeRoom.................\n");
+ /* MR23 */ printMessage(stderr, "num_markers==%d\n", num_markers);
+#endif
+/*
+ if ( num_markers == 0 )
+ {
+*/
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr, "moving lookahead and resetting next\n");
+
+ _ANTLRTokenPtr *r;
+ /* MR23 */ printMessage(stderr, "tbuf = [");
+ for (r=buffer; r<=last; r++)
+ {
+ if ( *r==NULL ) /* MR23 */ printMessage(stderr, " xxx");
+ else /* MR23 */ printMessage(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText());
+ }
+ /* MR23 */ printMessage(stderr, " ]\n");
+
+ /* MR23 */ printMessage(stderr,
+ "before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer);
+#endif
+
+ // Delete all tokens from 0..last-(k-1) inclusive
+ if ( _deleteTokens )
+ {
+ _ANTLRTokenPtr *z;
+ for (z=buffer; z<=last-(k-1); z++)
+ {
+ (*z)->deref();
+// z->deref();
+#ifdef DBG_REFCOUNTTOKEN
+ /* MR23 */ printMessage(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n",
+ ((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
+#endif
+ if ( (*z)->nref()==0 )
+ {
+ delete (*z);
+ }
+ }
+ }
+
+ // reset the buffer to initial conditions, but move k-1 symbols
+ // to the beginning of buffer and put new input symbol at k
+ _ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1;
+// ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1;
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr, "lookahead buffer = [");
+#endif
+ for (int i=1; i<=(k-1); i++)
+ {
+ *p++ = *q++;
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr,
+ " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
+#endif
+ }
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr, " ]\n");
+#endif
+ next = &buffer[k-1];
+ tp = &buffer[k-1]; // tp points to what will be filled in next
+ last = tp-1;
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr,
+ "after: tp=%d, last=%d, next=%d\n",
+ tp-buffer, last-buffer, next-buffer);
+#endif
+/*
+ }
+ else {
+ extendBuffer();
+ }
+*/
+}
+
+/* This function extends 'buffer' by chunk_size and returns with all
+ * pointers at the same relative positions in the buffer (the buffer base
+ * address could have changed in realloc()) except that 'next' comes
+ * back set to where the next token should be stored. All other pointers
+ * are untouched.
+ */
+void
+ANTLRTokenBuffer::
+extendBuffer()
+{
+ int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
+#ifdef DBG_TBUF
+ /* MR23 */ printMessage(stderr, "extending physical buffer\n");
+#endif
+ buffer_size += chunk_size;
+ buffer = (_ANTLRTokenPtr *)
+ realloc((char *)(buffer-1),
+ (buffer_size+1)*sizeof(_ANTLRTokenPtr ));
+ if ( buffer == NULL ) {
+ panic("cannot alloc token buffer");
+ }
+ buffer++; // leave the first elem empty so tp-1 is valid ptr
+
+ tp = buffer + save_tp; // put the pointers back to same relative position
+ last = buffer + save_last;
+ next = buffer + save_next;
+ end_of_buffer = &buffer[buffer_size-1];
+ threshold = &buffer[(int)(buffer_size*(1.0/2.0))];
+
+/*
+ // zero out new token ptrs so we'll know if something to delete in buffer
+ ANTLRAbstractToken **p = end_of_buffer-chunk_size+1;
+ for (; p<=end_of_buffer; p++) *p = NULL;
+*/
+}
+
+ANTLRParser * ANTLRTokenBuffer:: // MR1
+setParser(ANTLRParser *p) { // MR1
+ ANTLRParser *old=parser; // MR1
+ parser=p; // MR1
+ input->setParser(p); // MR1
+ return old; // MR1
+} // MR1
+ // MR1
+ANTLRParser * ANTLRTokenBuffer:: // MR1
+getParser() { // MR1
+ return parser; // MR1
+} // MR1
+
+void ANTLRTokenBuffer::panic(const char *msg) // MR23
+{
+ if (parser) //MR23
+ parser->panic(msg); //MR23
+ else //MR23
+ exit(PCCTS_EXIT_FAILURE);
+}
+
+//MR23
+int ANTLRTokenBuffer::printMessage(FILE* pFile, const char* pFormat, ...)
+{
+ va_list marker;
+ va_start( marker, pFormat );
+
+ int iRet = 0;
+ if (parser)
+ parser->printMessageV(pFile, pFormat, marker);
+ else
+ iRet = vfprintf(pFile, pFormat, marker);
+
+ va_end( marker );
+ return iRet;
+}
+
+/* to avoid having to link in another file just for the smart token ptr
+ * stuff, we include it here. Ugh.
+ *
+ * MR23 This causes nothing but problems for IDEs.
+ * Change from .cpp to .h
+ *
+ */
+
+#include ATOKPTR_IMPL_H
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.h
new file mode 100644
index 00000000..a6bec639
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.h
@@ -0,0 +1,109 @@
+/* ANTLRTokenBuffer.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ATOKENBUFFER_H_GATE
+#define ATOKENBUFFER_H_GATE
+
+#include "pcctscfg.h"
+
+#include "pccts_stdlib.h"
+
+PCCTS_NAMESPACE_STD
+
+#include ATOKEN_H
+#include ATOKENSTREAM_H
+
+/*
+ * The parser is "attached" to an ANTLRTokenBuffer via interface
+ * functions: getToken() and bufferedToken(). The object that actually
+ * consumes characters and constructs tokens is connected to the
+ * ANTLRTokenBuffer via interface function ANTLRTokenStream::getToken();
+ * where ANTLRTokenStream is really just a behavior (class with no data).
+ * C++ does not have this abstraction and hence we simply have come up
+ * with a fancy name for "void *". See the note in ANTLRTokenStream.h on
+ * the "behavior" of ANTLRTokenStream.
+ */
+
+class ANTLRParser; // MR1
+
+class DllExportPCCTS ANTLRTokenBuffer {
+protected:
+ ANTLRTokenStream *input; // where do I get tokens
+ int buffer_size;
+ int chunk_size;
+ int num_markers;
+ int k; // Need at least this many tokens in buffer
+ _ANTLRTokenPtr *buffer; // buffer used for arbitrary lookahead
+ _ANTLRTokenPtr *tp; // pts into buffer; current token ptr
+ _ANTLRTokenPtr *last; // pts to last valid token in buffer
+ _ANTLRTokenPtr *next; // place to put token from getANTLRToken()
+ _ANTLRTokenPtr *end_of_buffer;
+ /* when you try to write a token past this and there are no markers
+ set, then move k-1 tokens back to the beginning of the buffer.
+ We want to stay away from the end of the buffer because we have
+ to extend it if a marker is set and we reach the end (we cannot
+ move tokens to the beginning of the buffer in this case).
+ */
+ _ANTLRTokenPtr *threshold;
+ unsigned char _deleteTokens;
+
+ // This function is filled in by the subclass; it initiates fetch of input
+ virtual _ANTLRTokenPtr getANTLRToken() { return input->getToken(); }
+ void makeRoom();
+ void extendBuffer();
+
+public:
+ ANTLRTokenBuffer(ANTLRTokenStream *in, int k=1, int chksz=50);
+ virtual ~ANTLRTokenBuffer();
+ virtual _ANTLRTokenPtr getToken();
+ virtual void rewind(int pos);
+ virtual int mark();
+ virtual _ANTLRTokenPtr bufferedToken(int i);
+
+ void noGarbageCollectTokens() { _deleteTokens=0; }
+ void garbageCollectTokens() { _deleteTokens=1; }
+
+ virtual int bufferSize() { return buffer_size; }
+ virtual int minTokens() { return k; }
+ virtual void setMinTokens(int k_new) { k = k_new; }
+
+ virtual void panic(const char *msg); /* MR20 const */
+
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23
+
+protected: // MR1
+ ANTLRParser *parser; // MR1
+public: // MR1
+ ANTLRParser *setParser(ANTLRParser *p); // MR1
+ ANTLRParser *getParser(); // MR1
+ ANTLRTokenStream *getLexer() const { // MR12
+ return input;} // MR12
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenStream.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenStream.h
new file mode 100644
index 00000000..3df6385d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenStream.h
@@ -0,0 +1,51 @@
+/* ANTLRTokenStream.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ATOKENSTREAM_H_GATE
+#define ATOKENSTREAM_H_GATE
+
+#include "pcctscfg.h"
+
+/* This is really a behavior or protocol; it merely indicates the behavior
+ * required of the input and output of an ANTLRTokenBuffer. You could
+ * subclass it, but you can also just pass any old pointer to ANTLRTokenBuffer
+ * with a type cast (in which case, your getANTLRToken() would have to
+ * explicitly cast the input pointer to your REAL type (typically your lexer)).
+ */
+
+class ANTLRParser; // MR1
+
+class DllExportPCCTS ANTLRTokenStream {
+public:
+ virtual _ANTLRTokenPtr getToken() = 0;
+ virtual ANTLRParser * setParser(ANTLRParser * /*p MR23*/) {return 0; }; // MR12
+ virtual ANTLRParser * getParser() { return 0; }; // MR12
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.cpp
new file mode 100644
index 00000000..738d47cc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.cpp
@@ -0,0 +1,100 @@
+// FILE: BufFileInput.cpp
+// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru
+// CREATION: 26-JAN-1998
+// DESCRIPTION: File Input Stream with lookahead for Scanner.
+// See file BufFileInput.h for details
+
+// Change History:
+//
+// 22-Jun-1998 assert.h -> PCCTS_ASSERT_H
+// string.h -> PCCTS_STRING_H
+//
+// 28-May-1998 Add virtual destructor to release buffer.
+//
+// Add dummy definition for ANTLRTokenType
+// to allow compilation without knowing
+// token type codes.
+//
+// Manfred Kogler (km@cast.uni-linz.ac.at)
+// (1.33MR14)
+//
+// 20-Jul-1998 MR14a - Reorder initialization list for ctor.
+//
+
+enum ANTLRTokenType {TER_HATES_CPP=0, SO_DO_OTHERS=9999 };
+
+#include "pcctscfg.h"
+#include "pccts_assert.h"
+#include "pccts_string.h"
+
+PCCTS_NAMESPACE_STD
+
+#include "BufFileInput.h"
+
+BufFileInput::BufFileInput( FILE *f, int buf_size )
+: input( f ),
+ buf( new int[buf_size] ),
+ size( buf_size ),
+ start( 0 ),
+ len( 0 )
+{
+}
+
+BufFileInput::~BufFileInput()
+{
+ delete [] buf;
+}
+
+int BufFileInput::nextChar( void )
+{
+ if( len > 0 )
+ {
+ // get char from buffer
+ int c = buf[start];
+
+ if( c != EOF )
+ {
+ start++; start %= size;
+ len--;
+ }
+ return c;
+ } else {
+ // get char from file
+ int c = getc( input );
+
+ if( c == EOF )
+ {
+ // if EOF - put it in the buffer as indicator
+ buf[start] = EOF;
+ len++;
+ }
+ return c;
+ }
+}
+
+int BufFileInput::lookahead( char* s )
+{
+ int l = strlen( s );
+
+ assert( 0 < l && l <= size );
+
+ while( len < l )
+ {
+ int c = getc( input );
+
+ buf[ (start+len) % size ] = c;
+
+ len++;
+
+ if( c == EOF ) return 0;
+ }
+
+ for( int i = 0; i < l; i++ )
+ {
+ if( s[i] != buf[ (start+i) % size ] ) return 0;
+ }
+ return 1;
+}
+
+// End of file BufFileInput.cpp
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.h
new file mode 100644
index 00000000..d53340e3
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/BufFileInput.h
@@ -0,0 +1,53 @@
+// FILE: BufFileInput.h
+// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru
+// CREATION: 26-JAN-1998
+// DESCRIPTION: File Input Stream with lookahead for Scanner
+// Tested under Win32 with ANTLR 1.33 MR10 and MSVC 5.0
+
+// Change History:
+//
+// 28-May-1998 Add virtual destructor to release buffer
+// Manfred Kogler (km@cast.uni-linz.ac.at)
+// (1.33MR14)
+
+#ifndef BufFileInput_h
+#define BufFileInput_h
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+
+PCCTS_NAMESPACE_STD
+
+#include "DLexerBase.h"
+
+class DllExportPCCTS BufFileInput : public DLGInputStream
+{
+public:
+ // constructor
+ // f - input stream
+ // buf_size - size of buffer (maximal length for string in is_in)
+
+ BufFileInput(FILE *f, int buf_size = 8 );
+
+ virtual ~BufFileInput();
+
+ // gets next char from stream
+
+ virtual int nextChar( void );
+
+ // looks in stream and compares next l characters with s
+ // returns the result of comparision
+
+ int lookahead( char* s );
+
+private:
+ FILE *input; // input stream;
+ int* buf; // buffer
+ int size; // size of buffer
+ int start; // position of the first symbol in buffer
+ int len; // count of characters in buffers
+};
+
+#endif
+// end of file BufFileInput.h
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLG_stream_input.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLG_stream_input.h
new file mode 100644
index 00000000..e7972f1e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLG_stream_input.h
@@ -0,0 +1,98 @@
+
+/************************************************************/
+/* */
+/* Predefined char stream: Input from (c++) stream. */
+/* */
+/* By Hubert Holin (Hubert.Holin@Bigfoot.com), 1998. */
+/* */
+/* This is completely free stuff, do whatever you want with */
+/* it (but then, I will take no responsibility for whatever */
+/* may happen if you do either... caveat emptor!). */
+/* */
+/************************************************************/
+
+#ifndef _DLG_STREAM_INPUT_H
+#define _DLG_STREAM_INPUT_H
+
+#include "pccts_istream.h"
+
+PCCTS_NAMESPACE_STD
+
+#ifndef DLGX_H
+#include "DLexerBase.h"
+#endif
+
+
+// NOTES: The semantics of the copy constructor
+// and the affectation operator may be unwarranted...
+// and the stream may not be reset.
+//
+// It would have been so much nicer for nextChar()
+// to throw (of for the DLGInputStream to change status)
+// upon hitting EOF than to return an "int"...
+
+template <
+ class E,
+ class T = ::std::char_traits<E>
+ >
+class DLG_stream_input : public DLGInputStream
+{
+public:
+
+ DLG_stream_input(::std::basic_istream<E,T> * p_input_stream)
+ : input(p_input_stream)
+ {
+ // nothing to do!
+ };
+
+ DLG_stream_input(const DLG_stream_input & a_recopier)
+ : input(a_recopier.input)
+ {
+ // nothing to do!
+ };
+
+ virtual ~DLG_stream_input()
+ {
+ this->purge(); // bloody templarized lookup...
+ };
+
+ DLG_stream_input operator = (const DLG_stream_input & a_affecter)
+ {
+ if (this != &a_affecter)
+ {
+ input = a_affecter.input;
+ }
+
+ return(*this);
+ };
+
+ virtual int nextChar()
+ {
+ E extracted_stuff;
+
+ input->get(extracted_stuff);
+
+ if (*input)
+ {
+ return(int(extracted_stuff));
+ }
+ else
+ {
+ return(EOF);
+ }
+ };
+
+protected:
+
+ ::std::basic_istream<E,T> * input;
+
+private:
+
+ void purge()
+ {
+ // nothing to do!
+ };
+};
+
+#endif /* _DLG_STREAM_INPUT_H */
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexer.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexer.h
new file mode 100644
index 00000000..afc172ae
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexer.h
@@ -0,0 +1,194 @@
+/* DLexer.h (formerly DLexer.cpp)
+ *
+ * This was renamed because the use of the .cpp extension caused problems
+ * with IDEs.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include <assert.h>
+
+#define ZZINC {if ( track_columns ) (++_endcol);}
+
+#define ZZGETC {ch = input->nextChar(); cl = ZZSHIFT(ch);}
+
+#define ZZNEWSTATE (newstate = dfa[state][cl])
+
+#ifndef ZZCOPY
+#define ZZCOPY \
+ /* Truncate matching buffer to size (not an error) */ \
+ if (nextpos < lastpos){ \
+ *(nextpos++) = ch; \
+ }else{ \
+ bufovf = 1; \
+ }
+#endif
+
+void DLGLexer::
+mode( int m )
+{
+ /* points to base of dfa table */
+ if (m<MAX_MODE){
+ automaton = m;
+ /* have to redo class since using different compression */
+ cl = ZZSHIFT(ch);
+ }else{
+ sprintf((char *)ebuf,"Invalid automaton mode = %d ",m);
+ errstd(ebuf);
+ }
+}
+
+ANTLRTokenType DLGLexer::
+nextTokenType(void)
+{
+ register int state, newstate;
+ /* last space reserved for the null char */
+ register DLGChar *lastpos;
+ ANTLRTokenType tk;
+
+skip:
+ bufovf = 0;
+ lastpos = &_lextext[_bufsize-1];
+ nextpos = _lextext;
+ _begcol = _endcol+1;
+more:
+ _begexpr = nextpos;
+ if ( interactive ) {
+ /* interactive version of automaton */
+ /* if there is something in ch, process it */
+ state = newstate = dfa_base[automaton];
+ if (charfull){
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ while (alternatives[newstate]){
+ state = newstate;
+ ZZGETC;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ /* figure out if last character really part of token */
+ if ((state != dfa_base[automaton]) && (newstate == DfaStates)){
+ charfull = 1;
+ --nextpos;
+ }else{
+ charfull = 0;
+ state = newstate;
+ }
+ *(nextpos) = '\0';
+ /* Able to transition out of start state to some non err state?*/
+ if ( state == dfa_base[automaton] ){
+ /* make sure doesn't get stuck */
+ advance();
+ }
+ }
+ else { /* non-interactive version of automaton */
+ if (!charfull)
+ advance();
+ else
+ ZZINC;
+ state = dfa_base[automaton];
+ while (ZZNEWSTATE != DfaStates) {
+ state = newstate;
+ assert(state <= sizeof(dfa)/sizeof(dfa[0]));
+ ZZCOPY;
+ ZZGETC;
+ ZZINC;
+ }
+ charfull = 1;
+ if ( state == dfa_base[automaton] ){
+ if (nextpos < lastpos){
+ *(nextpos++) = ch;
+ }else{
+ bufovf = 1;
+ }
+ *nextpos = '\0';
+ /* make sure doesn't get stuck */
+ advance();
+ }else{
+ *nextpos = '\0';
+ }
+ }
+ if ( track_columns ) _endcol -= charfull;
+ _endexpr = nextpos -1;
+ add_erase = 0;
+#ifdef OLD
+ tk = (ANTLRTokenType)
+ (*actions[accepts[state]])(this); // must pass this manually
+ // actions is not a [] of pointers
+ // to member functions.
+#endif
+ tk = (this->*actions[accepts[state]])();
+
+// MR1
+// MR1 11-Apr-97 Help for tracking DLG results
+// MR1
+
+#ifdef DEBUG_LEXER
+
+/* MR1 */ if (debugLexerFlag) {
+/* MR1 */ if (parser != NULL) {
+/* MR1 */ /* MR23 */ printMessage(stdout, "\ntoken name=%s",parser->parserTokenName(tk));
+/* MR1 */ } else {
+/* MR1 */ /* MR23 */ printMessage(stdout, "\ntoken nnumber=%d",tk);
+/* MR1 */ };
+/* MR1 */ /* MR23 */ printMessage(stdout, " lextext=(%s) mode=%d",
+/* MR1 */ (_lextext[0]=='\n' && _lextext[1]==0) ?
+/* MR1 */ "newline" : _lextext,
+/* MR1 */ automaton);
+/* MR1 */ if (interactive && !charfull) {
+/* MR1 */ /* MR23 */ printMessage(stdout, " char=empty");
+/* MR1 */ } else {
+/* MR1 */ if (ch=='\n') {
+/* MR1 */ /* MR23 */ printMessage(stdout, " char=newline");
+/* MR1 */ } else {
+/* MR1 */ /* MR23 */ printMessage(stdout, " char=(%c)",ch);
+/* MR1 */ };
+/* MR1 */ };
+/* MR1 */ /* MR23 */ printMessage(stdout, " %s\n",
+/* MR1 */ (add_erase==1 ? "skip()" :
+/* MR1 */ add_erase==2 ? "more()" :
+/* MR1 */ ""));
+/* MR1 */ };
+
+#endif
+
+ switch (add_erase) {
+ case 1: goto skip;
+ case 2: goto more;
+ }
+ return tk;
+}
+
+void DLGLexer::
+advance()
+{
+ if ( input==NULL ) err_in();
+ ZZGETC; charfull = 1; ZZINC;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.cpp
new file mode 100644
index 00000000..87b29208
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.cpp
@@ -0,0 +1,302 @@
+/* DLGLexerBase.c
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+#include "pccts_stdlib.h"
+
+PCCTS_NAMESPACE_STD
+
+/* I have to put this here due to C++ limitation
+ * that you can't have a 'forward' decl for enums.
+ * I hate C++!!!!!!!!!!!!!!!
+ */
+
+// MR1
+// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the
+// MR1 ANTLRTokenType enum
+// MR1
+
+enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE, // MR1
+ WITH_SOME_GOOD_IDEAS=9999}; // MR1
+
+#define ANTLR_SUPPORT_CODE
+
+#include "pcctscfg.h"
+#include DLEXERBASE_H
+#include APARSER_H // MR23
+
+DLGLexerBase::
+DLGLexerBase(DLGInputStream *in,
+ unsigned bufsize,
+ int _interactive,
+ int _track_columns)
+{
+ this->_bufsize = bufsize;
+ this->_lextext = new DLGChar[_bufsize];
+ if ( this->_lextext==NULL ) {
+ panic("text buffer is NULL");
+ }
+ this->_begexpr = this->_endexpr = NULL;
+ this->ch = this->bufovf = 0;
+ this->nextpos = NULL;
+ this->cl = 0;
+ this->add_erase = 0;
+ this->input = in;
+ this->_begcol = 0;
+ this->_endcol = 0;
+ this->_line = 1;
+ this->charfull = 0;
+ this->automaton = 0;
+ this->token_to_fill = NULL;
+ this->interactive = _interactive;
+ this->track_columns = _track_columns;
+ this->debugLexerFlag = 0; // MR1
+ this->parser = NULL; // MR1
+ this->lexErrCount=0; // MR11
+}
+
+// MR19 THM
+
+void DLGLexerBase::reset()
+{
+ this->charfull = 0;
+ this->_begcol = 0;
+ this->_endcol = 0;
+ this->automaton = 0;
+ this->_line=1;
+ this->lexErrCount=0;
+}
+
+void DLGLexerBase::
+setInputStream( DLGInputStream *in )
+{
+ this->input = in;
+ _line = 1;
+ charfull = 0;
+}
+
+/* saves dlg state, but not what feeds dlg (such as file position) */
+void DLGLexerBase::
+saveState(DLGState *state)
+{
+ state->input = input;
+ state->interactive = interactive;
+ state->track_columns = track_columns;
+ state->auto_num = automaton;
+ state->add_erase = add_erase;
+ state->lookc = ch;
+ state->char_full = charfull;
+ state->begcol = _begcol;
+ state->endcol = _endcol;
+ state->line = _line;
+ state->lextext = _lextext;
+ state->begexpr = _begexpr;
+ state->endexpr = _endexpr;
+ state->bufsize = _bufsize;
+ state->bufovf = bufovf;
+ state->nextpos = nextpos;
+ state->class_num = cl;
+ state->debugLexerFlag = debugLexerFlag; // MR1
+ state->parser = parser; // MR1
+}
+
+void DLGLexerBase::
+restoreState(DLGState *state)
+{
+ input = state->input;
+ interactive = state->interactive;
+ track_columns = state->track_columns;
+ automaton = state->auto_num;
+ add_erase = state->add_erase;
+ ch = state->lookc;
+ charfull = state->char_full;
+ _begcol = state->begcol;
+ _endcol = state->endcol;
+ _line = state->line;
+ _lextext = state->lextext;
+ _begexpr = state->begexpr;
+ _endexpr = state->endexpr;
+ _bufsize = state->bufsize;
+ bufovf = state->bufovf;
+ nextpos = state->nextpos;
+ cl = state->class_num;
+ debugLexerFlag = state->debugLexerFlag; // MR1
+ parser = state->parser; // MR1
+}
+
+/* erase what is currently in the buffer, and get a new reg. expr */
+void DLGLexerBase::
+skip()
+{
+ add_erase = 1;
+}
+
+/* don't erase what is in the lextext buffer, add on to it */
+void DLGLexerBase::
+more()
+{
+ add_erase = 2;
+}
+
+/* substitute c for the reg. expr last matched and is in the buffer */
+void DLGLexerBase::
+replchar(DLGChar c)
+{
+ /* can't allow overwriting null at end of string */
+ if (_begexpr < &_lextext[_bufsize-1]){
+ *_begexpr = c;
+ *(_begexpr+1) = '\0';
+ }
+ _endexpr = _begexpr;
+ if (c != '\0') {
+ nextpos = _begexpr + 1;
+ }
+ else {
+ nextpos = _begexpr; /* MR30 Zero terminates string. */
+ }
+}
+
+/* replace the string s for the reg. expr last matched and in the buffer */
+
+#ifdef _MSC_VER // MR23
+//Turn off "assignment within conditional expression" warning
+#pragma warning(disable : 4706)
+#endif
+void DLGLexerBase::
+replstr(const DLGChar *s) /* MR20 const */
+{
+ register DLGChar *l= &_lextext[_bufsize -1];
+
+ nextpos = _begexpr;
+ if (s){
+ while ((nextpos <= l) && (*(nextpos++) = *(s++))){
+ /* empty */
+ }
+ /* correct for NULL at end of string */
+ nextpos--;
+ }
+ if ((nextpos <= l) && (*(--s) == 0)){
+ bufovf = 0;
+ }else{
+ bufovf = 1;
+ }
+ *(nextpos) = '\0';
+ _endexpr = nextpos - 1;
+}
+#ifdef _MSC_VER // MR23
+#pragma warning(default: 4706)
+#endif
+
+void DLGLexerBase::
+errstd(const char *s) /* MR20 const */
+{
+ lexErrCount++; /* MR11 */
+ /* MR23 */ printMessage(stderr,
+ "%s near line %d (text was '%s')\n",
+ ((s == NULL) ? "Lexical error" : s),
+ _line,_lextext);
+}
+
+int DLGLexerBase::
+err_in()
+{
+ /* MR23 */ printMessage(stderr,"No input stream, function, or string\n");
+ /* return eof to get out gracefully */
+ return EOF;
+}
+
+ANTLRTokenType DLGLexerBase::
+erraction()
+{
+ errstd("invalid token");
+ advance();
+ skip();
+ return (ANTLRTokenType) 0; // bogus, but satisfies compiler
+}
+
+_ANTLRTokenPtr DLGLexerBase::
+getToken()
+{
+ if ( token_to_fill==NULL ) panic("NULL token_to_fill");
+ ANTLRTokenType tt = nextTokenType();
+ _ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line);
+ return tk;
+}
+
+void DLGLexerBase::
+panic(const char *msg) /* MR20 const */
+{
+ if (parser) //MR23
+ parser->panic(msg); //MR23
+ else //MR23
+ {
+ /* MR23 */ printMessage(stderr, "DLG panic: %s\n", msg);
+ //
+ // 7-Apr-97 133MR1
+ //
+ exit(PCCTS_EXIT_FAILURE); // MR1
+ }
+}
+
+ANTLRParser * DLGLexerBase:: // MR1
+setParser(ANTLRParser *p) { // MR1
+ ANTLRParser *oldValue=parser; // MR1
+ parser=p; // MR1
+ return oldValue; // MR1
+} // MR1
+ // MR1
+ANTLRParser * DLGLexerBase:: // MR1
+getParser() { // MR1
+ return parser; // MR1
+} // MR1
+ // MR1
+int DLGLexerBase:: // MR1
+debugLexer(int newValue) { // MR1
+ int oldValue=debugLexerFlag; // MR1
+ debugLexerFlag=newValue; // MR1
+ return oldValue; // MR1
+} // MR1
+
+//MR23
+int DLGLexerBase::printMessage(FILE* pFile, const char* pFormat, ...)
+{
+ va_list marker;
+ va_start( marker, pFormat );
+
+ int iRet = 0;
+ if (parser)
+ parser->printMessageV(pFile, pFormat, marker);
+ else
+ iRet = vfprintf(pFile, pFormat, marker);
+
+ va_end( marker );
+ return iRet;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.h
new file mode 100644
index 00000000..c30f2277
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/DLexerBase.h
@@ -0,0 +1,202 @@
+/* DLGLexerBase.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef DLGX_H
+#define DLGX_H
+
+#include "pcctscfg.h"
+#include "pccts_stdio.h"
+
+PCCTS_NAMESPACE_STD
+
+#include ATOKEN_H
+#include ATOKENSTREAM_H
+
+class ANTLRParser; // MR1
+
+/* must define what a char looks like; can make this a class too */
+typedef char DLGChar;
+
+/* Can have it as a class too: (ack this looks weird; is it right?)
+class DllExportPCCTS DLGChar {
+private:
+ int c;
+public:
+ DLGChar(int ch) { c = ch; }
+ int atom() { return c; }
+};
+*/
+
+/* user must subclass this */
+class DllExportPCCTS DLGInputStream {
+public:
+ virtual int nextChar() = 0;
+ virtual ~DLGInputStream() {};
+};
+
+/* Predefined char stream: Input from FILE */
+class DllExportPCCTS DLGFileInput : public DLGInputStream {
+private:
+ int found_eof;
+ FILE *input;
+public:
+ DLGFileInput(FILE *f) { input = f; found_eof = 0; }
+ int nextChar() {
+ int c;
+ if ( found_eof ) return EOF;
+ else {
+ c=getc(input);
+ if ( c==EOF ) found_eof = 1;
+ return c;
+ }
+ }
+ void DLGFileReset(FILE *f) {input=f; found_eof = 0; }; // MR11
+};
+
+// MR9 Suggested by Bruce Guenter (bruceg@qcc.sk.ca)
+// MR9 Make DLGStringInput const correct
+
+/* Predefined char stream: Input from string */
+class DllExportPCCTS DLGStringInput : public DLGInputStream {
+private:
+ const DLGChar *input; // MR9
+ const DLGChar *p; // MR9
+public:
+ DLGStringInput(const DLGChar *s) { input = s; p = &input[0];} // MR9
+ int nextChar()
+ {
+ if (*p) return (int) (unsigned char) *p++; // MR14
+ else return EOF;
+ }
+
+ void DLGStringReset(const DLGChar *s) {input=s; p= &input[0]; }; // MR11 // MR16
+};
+
+class DllExportPCCTS DLGState {
+public:
+ DLGInputStream *input;
+ int interactive;
+ int track_columns;
+ int auto_num;
+ int add_erase;
+ int lookc;
+ int char_full;
+ int begcol, endcol;
+ int line;
+ DLGChar *lextext, *begexpr, *endexpr;
+ int bufsize;
+ int bufovf;
+ DLGChar *nextpos;
+ int class_num;
+ int debugLexerFlag; // MR1
+ ANTLRParser *parser; // MR1
+};
+
+/* user must subclass this */
+class DllExportPCCTS DLGLexerBase : public ANTLRTokenStream {
+private:
+ DLGLexerBase(const DLGLexerBase&); // Prevent copy-construction
+ DLGLexerBase& operator=(const DLGLexerBase&); // Prevent assignment
+public:
+ virtual ANTLRTokenType erraction();
+
+protected:
+ DLGInputStream *input;
+ int interactive;
+ int track_columns;
+ DLGChar *_lextext; /* text of most recently matched token */
+ DLGChar *_begexpr; /* beginning of last reg expr recogn. */
+ DLGChar *_endexpr; /* beginning of last reg expr recogn. */
+ int _bufsize; /* number of characters in lextext */
+ int _begcol; /* column that first character of token is in*/
+ int _endcol; /* column that last character of token is in */
+ int _line; /* line current token is on */
+ int ch; /* character to determine next state */
+ int bufovf; /* indicates that buffer too small for text */
+ int charfull;
+ DLGChar *nextpos; /* points to next available position in lextext*/
+ int cl;
+ int automaton;
+ int add_erase;
+ DLGChar ebuf[70];
+ _ANTLRTokenPtr token_to_fill;
+
+ int debugLexerFlag; // MR1
+ ANTLRParser *parser; // MR1
+public:
+ virtual _ANTLRTokenPtr getToken(); // MR12 public
+ virtual void advance(void) = 0;
+ void skip(void); /* erase lextext, look for antoher token */
+ void more(void); /* keep lextext, look for another token */
+ void mode(int k); /* switch to automaton 'k' */
+ void saveState(DLGState *);
+ void restoreState(DLGState *);
+ virtual ANTLRTokenType nextTokenType(void)=0;/* get next token */
+ void replchar(DLGChar c); /* replace last recognized reg. expr. with
+ a character */
+ void replstr(const DLGChar *s); /* replace last recognized reg. expr. with
+ a string */ /* MR20 const */
+ virtual int err_in(); // MR1
+ virtual void errstd(const char *); // MR1 MR20 const
+ int line() { return _line; }
+ void set_line(int newValue) { _line=newValue; }; // MR1
+ virtual void newline() { _line++; }
+ DLGChar *lextext() { return _lextext; }
+
+ int begcol() { return _begcol; }
+ int endcol() { return _endcol; }
+ void set_begcol(int a) { _begcol=a; }
+ void set_endcol(int a) { _endcol=a; }
+ DLGChar *begexpr() { return _begexpr; }
+ DLGChar *endexpr() { return _endexpr; }
+ int bufsize() { return _bufsize; }
+
+ void setToken(ANTLRAbstractToken *t) { token_to_fill = t; }
+
+ void setInputStream(DLGInputStream *);
+ DLGLexerBase(DLGInputStream *in,
+ unsigned bufsize=2000,
+ int interactive=0,
+ int track_columns=0);
+ void reset(); // MR19
+ virtual ~DLGLexerBase() { delete [] _lextext; }
+ virtual void panic(const char *msg); // MR1 MR20 const
+ void trackColumns() {
+ track_columns = 1;
+ this->_begcol = 0;
+ this->_endcol = 0;
+ };
+ virtual ANTLRParser *setParser(ANTLRParser *p); // MR1
+ virtual ANTLRParser *getParser(); // MR1
+ virtual int debugLexer(int value); // MR1
+ int lexErrCount; // MR12
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PBlackBox.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PBlackBox.h
new file mode 100644
index 00000000..6d201601
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PBlackBox.h
@@ -0,0 +1,134 @@
+#ifndef PBLACKBOX_H
+#define PBLACKBOX_H
+
+/*
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+/* Completely rewritten by Chris Uzdavinis (chris@atdesk.com) for MR23 */
+
+#include "pcctscfg.h"
+
+#include "pccts_iostream.h"
+
+PCCTS_NAMESPACE_STD
+
+// MR20 Added #include for "DLexerBase.h"
+
+#include "DLexerBase.h"
+
+//
+// The default buffer size of the lexer is given by the
+// second argument of the lexer's ctor. It is optional
+// and defaults to 2000
+//
+
+template<class Lexer, class Parser, class Token>
+class DllExportPCCTS ParserBlackBox {
+private:
+ // no copy construction allowed
+ ParserBlackBox(ParserBlackBox const &);
+
+ // no copy assignment allowed
+ ParserBlackBox & operator=(ParserBlackBox const &);
+
+protected:
+ DLGFileInput *in;
+ Lexer *scan;
+ _ANTLRTokenPtr tok;
+ ANTLRTokenBuffer *pipe;
+ Parser *_parser;
+ FILE *file;
+ int openByBlackBox; /* MR21 Don't close what we haven't opened */
+public:
+
+ ParserBlackBox(FILE *f)
+ : in(0)
+ , scan(0)
+ , tok(0)
+ , pipe(0)
+ , _parser(0)
+ , file(0)
+ , openByBlackBox(0)
+ {
+ if (f == NULL)
+ {
+ cerr << "invalid file pointer\n";
+ }
+ else
+ {
+ openByBlackBox = 0; /* MR21a */
+ file = f;
+ in = new DLGFileInput(f);
+ scan = new Lexer(in);
+ pipe = new ANTLRTokenBuffer(scan);
+ tok = new Token;
+ scan->setToken(tok);
+ _parser = new Parser(pipe);
+ _parser->init();
+ }
+ }
+ ParserBlackBox(char *fname)
+ : in(0)
+ , scan(0)
+ , tok(0)
+ , pipe(0)
+ , _parser(0)
+ , file(0)
+ , openByBlackBox(0)
+ {
+ FILE *f = fopen(fname, "r");
+ if ( f==NULL ) {
+ openByBlackBox = 0;
+ cerr << "cannot open " << fname << "\n"; return;
+ }
+ else {
+ openByBlackBox = 1;
+ file = f;
+ in = new DLGFileInput(f);
+ scan = new Lexer(in);
+ pipe = new ANTLRTokenBuffer(scan);
+ tok = new Token;
+ scan->setToken(tok);
+ _parser = new Parser(pipe);
+ _parser->init();
+ }
+ }
+
+ ~ParserBlackBox()
+ {
+ delete in; delete scan; delete pipe; delete _parser; delete tok;
+ if (1 == openByBlackBox) {
+ fclose(file);
+ }
+ }
+
+ Parser *parser() { return _parser; }
+ Lexer *getLexer() { return scan; }
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.cpp
new file mode 100644
index 00000000..c29b69fa
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.cpp
@@ -0,0 +1,684 @@
+/*
+ * PCCTSAST.C
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
+ * domain. An individual or company may do whatever they wish with
+ * source code distributed with SORCERER or the code generated by
+ * SORCERER, including the incorporation of SORCERER, or its output, into
+ * commerical software.
+ *
+ * We encourage users to develop software with SORCERER. However, we do
+ * ask that credit is given to us for developing SORCERER. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like SORCERER and have developed a nice tool with the
+ * output, please mention that you developed it using SORCERER. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * SORCERER 1.00B14 and ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * AHPCRC, University of Minnesota
+ * 1992-2000
+ */
+
+#define ANTLR_SUPPORT_CODE
+
+#include "pcctscfg.h"
+
+#include "PCCTSAST.h"
+#include "pccts_stdarg.h"
+
+PCCTS_NAMESPACE_STD
+
+#include <ctype.h>
+
+//#include "SList.h"
+
+ /* String Scanning/Parsing Stuff */
+
+const char *PCCTS_AST::scan_token_tbl[] = { /* MR20 const */
+ "invalid", /* 0 */
+ "LPAREN", /* 1 */
+ "RPAREN", /* 2 */
+ "PERCENT", /* 3 */
+ "INT", /* 4 */
+ "COLON", /* 5 */
+ "POUND", /* 6 */
+ "PERIOD", /* 7 */
+};
+
+void PCCTS_AST::
+addChild(PCCTS_AST *t)
+{
+ if ( t==NULL ) return;
+ PCCTS_AST *s = down();
+ if ( s!=NULL )
+ {
+ while ( s->right()!=NULL ) s = s->right();
+ s->setRight(t);
+ }
+ else
+ this->setDown(t);
+}
+
+void PCCTS_AST::
+lisp(FILE *f)
+{
+ if ( down() != NULL ) /* MR23 */ printMessage(f," (");
+ lisp_action(f);
+ if ( down()!=NULL ) down()->lisp(f);
+ if ( down() != NULL ) /* MR23 */ printMessage(f," )");
+ if ( right()!=NULL ) right()->lisp(f);
+}
+
+/* build a tree (root child1 child2 ... NULL)
+ * If root is NULL, simply make the children siblings and return ptr
+ * to 1st sibling (child1). If root is not single node, return NULL.
+ *
+ * Siblings that are actually sibling lists themselves are handled
+ * correctly. For example #( NULL, #( NULL, A, B, C), D) results
+ * in the tree ( NULL A B C D ).
+ *
+ * Requires at least two parameters with the last one being NULL. If
+ * both are NULL, return NULL.
+ *
+ * The down() and right() down/right pointers are used to make the tree.
+ */
+PCCTS_AST *PCCTS_AST::
+make(PCCTS_AST *rt, ...)
+{
+ va_list ap;
+ register PCCTS_AST *child, *sibling=NULL, *tail=NULL /*MR23*/, *w;
+ PCCTS_AST *root;
+
+ va_start(ap, rt);
+ root = rt;
+
+ if ( root != NULL )
+ if ( root->down() != NULL ) return NULL;
+ child = va_arg(ap, PCCTS_AST *);
+ while ( child != NULL )
+ {
+ /* find end of child */
+ for (w=child; w->right()!=NULL; w=w->right()) {;}
+ if ( sibling == NULL ) {sibling = child; tail = w;}
+ else {tail->setRight(child); tail = w;}
+ child = va_arg(ap, PCCTS_AST *);
+ }
+ if ( root==NULL ) root = sibling;
+ else root->setDown(sibling);
+ va_end(ap);
+ return root;
+}
+
+/* The following push and pop routines are only used by ast_find_all() */
+
+void PCCTS_AST::
+_push(PCCTS_AST **st, int *sp, PCCTS_AST *e)
+{
+ (*sp)--;
+ require((*sp)>=0, "stack overflow");
+ st[(*sp)] = e;
+}
+
+PCCTS_AST *PCCTS_AST::
+_pop(PCCTS_AST **st, int *sp)
+{
+ PCCTS_AST *e = st[*sp];
+ (*sp)++;
+ require((*sp)<=MaxTreeStackDepth, "stack underflow");
+ return e;
+}
+
+/* Find all occurrences of u in t.
+ * 'cursor' must be initialized to 't'. It eventually
+ * returns NULL when no more occurrences of 'u' are found.
+ */
+PCCTS_AST *PCCTS_AST::
+ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor)
+{
+ PCCTS_AST *sib;
+ /*** static ***/ PCCTS_AST *template_stack[MaxTreeStackDepth]; /* MR23 Remove "static" */
+ /*** static ***/ int tsp = MaxTreeStackDepth; /* MR23 Remove "static" */
+
+////static int nesting = 0; /* MR23 Not referenced */
+
+ if ( *cursor == NULL ) return NULL;
+ if ( *cursor!=this ) sib = *cursor;
+ else {
+ /* else, first time--start at top of template 't' */
+ tsp = MaxTreeStackDepth;
+ sib = this;
+ /* bottom of stack is always a NULL--"cookie" indicates "done" */
+ _push(template_stack, &tsp, NULL);
+ }
+
+keep_looking:
+ if ( sib==NULL ) /* hit end of sibling list */
+ {
+ sib = _pop(template_stack, &tsp);
+ if ( sib == NULL ) { *cursor = NULL; return NULL; }
+ }
+
+ if ( sib->type() != u->type() )
+ {
+ /* look for another match */
+ if ( sib->down()!=NULL )
+ {
+ if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
+ sib=sib->down();
+ goto keep_looking;
+ }
+ /* nothing below to try, try next sibling */
+ sib=sib->right();
+ goto keep_looking;
+ }
+
+ /* found a matching root node, try to match what's below */
+ if ( match_partial(sib, u) )
+ {
+ /* record sibling cursor so we can pick up next from there */
+ if ( sib->down()!=NULL )
+ {
+ if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
+ *cursor = sib->down();
+ }
+ else if ( sib->right()!=NULL ) *cursor = sib->right();
+ else *cursor = _pop(template_stack, &tsp);
+ return sib;
+ }
+
+ /* no match, keep searching */
+ if ( sib->down()!=NULL )
+ {
+ if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
+ sib=sib->down();
+ }
+ else sib = sib->right(); /* else, try to right if zip below */
+ goto keep_looking;
+}
+
+/* are two trees exactly alike? */
+int PCCTS_AST::
+match(PCCTS_AST *u)
+{
+ PCCTS_AST *t = this;
+ PCCTS_AST *sib;
+
+ if ( u==NULL ) return 0;
+
+ for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
+ {
+ if ( sib->type() != u->type() ) return 0;
+ if ( sib->down()!=NULL )
+ if ( !sib->down()->match(u->down()) ) return 0;
+ }
+ return 1;
+}
+
+/* Is 'u' a subtree of 't' beginning at the root? */
+int PCCTS_AST::
+match_partial(PCCTS_AST *t, PCCTS_AST *u)
+{
+ PCCTS_AST *sib;
+
+ if ( u==NULL ) return 1;
+ if ( t==NULL ) return 0; /* MR23 removed unreachable code */
+
+ for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
+ {
+ if ( sib->type() != u->type() ) return 0;
+ if ( sib->down()!=NULL )
+ if ( !match_partial(sib->down(), u->down()) ) return 0;
+ }
+ return 1;
+}
+
+#ifdef _MSC_VER // MR23
+//Turn off "unreachable code" warning
+#pragma warning(disable : 4702)
+#endif
+/* Walk the template tree 't' (matching against 'this'), filling in the
+ * 'labels' array, and setting 'n' according to how many labels were matched.
+ */
+int PCCTS_AST::
+scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n)
+{
+ ScanAST *sib;
+ PCCTS_AST *u = this;
+
+ if ( u==NULL ) return 0;
+
+ for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
+ {
+ /* make sure tokens match; token of '0' means wildcard match */
+ if ( sib->type() != u->type() && sib->type()!=0 ) return 0;
+ /* we have a matched token here; set label pointers if exists */
+ if ( sib->label_num>0 )
+ {
+ require(labels!=NULL, "label found in template, but no array of labels");
+ (*n)++;
+ *(labels[sib->label_num-1]) = u;
+ }
+ /* match what's below if something there and current node is not wildcard */
+ if ( sib->down()!=NULL && sib->type()!=0 )
+ {
+ if ( sib->down()==NULL )
+ {
+ if ( u->down()!=NULL )
+ return 0;
+ else
+ return 1;
+ }
+ if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0;
+ }
+ }
+ return 1;
+}
+#ifdef _MSC_VER // MR23
+#pragma warning(default : 4702)
+#endif
+
+void PCCTS_AST::
+insert_after(PCCTS_AST *b)
+{
+ PCCTS_AST *end;
+ if ( b==NULL ) return;
+ /* find end of b's child list */
+ for (end=b; end->right()!=NULL; end=end->right()) {;}
+ end->setRight(this->right());
+ this->setRight(b);
+}
+
+void PCCTS_AST::
+append(PCCTS_AST *b)
+{
+ PCCTS_AST *end;
+ require(b!=NULL, "append: NULL input tree");
+ /* find end of child list */
+ for (end=this; end->right()!=NULL; end=end->right()) {;}
+ end->setRight(b);
+}
+
+PCCTS_AST *PCCTS_AST::
+tail()
+{
+ PCCTS_AST *end;
+ /* find end of child list */
+ for (end=this; end->right()!=NULL; end=end->right()) {;}
+ return end;
+}
+
+PCCTS_AST *PCCTS_AST::
+bottom()
+{
+ PCCTS_AST *end;
+ /* find end of child list */
+ for (end=this; end->down()!=NULL; end=end->down()) {;}
+ return end;
+}
+
+PCCTS_AST *PCCTS_AST::
+cut_between(PCCTS_AST *a, PCCTS_AST *b)
+{
+ PCCTS_AST *end, *ret;
+ if (a==NULL||b==NULL) return NULL;
+ /* find node pointing to b */
+ for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right())
+ {;}
+ if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected
+ end->setRight(NULL); /* don't want it point to 'b' anymore */
+ ret = a->right();
+ a->setRight(b);
+ return ret;
+}
+
+#ifdef NOT_YET
+SList *PCCTS_AST::
+to_slist()
+{
+ SList *list = new SList;
+ PCCTS_AST *p;
+
+ for (p=this; p!=NULL; p=p->right())
+ {
+ list->add(p);
+ }
+ return list;
+}
+#endif
+
+void PCCTS_AST::
+tfree()
+{
+ PCCTS_AST *t = this;
+ if ( t->down()!=NULL ) t->down()->tfree();
+ if ( t->right()!=NULL ) t->right()->tfree();
+ delete t;
+}
+
+int PCCTS_AST::
+nsiblings()
+{
+ PCCTS_AST *t = this;
+ int n=0;
+
+ while ( t!=NULL )
+ {
+ n++;
+ t = t->right();
+ }
+ return n;
+}
+
+PCCTS_AST *PCCTS_AST::
+sibling_index(int i)
+{
+ PCCTS_AST *t = this;
+ int j=1;
+ require(i>0, "sibling_index: i<=0");
+
+ while ( t!=NULL )
+ {
+ if ( j==i ) return t;
+ j++;
+ t = t->right();
+ }
+ return NULL;
+}
+
+/* Assume this is a root node of a tree--
+ * duplicate that node and what's below; ignore siblings of root node.
+ */
+
+// MR9 23-Sep-97 RJV
+// MR9
+// MR9 RJV: Original version only duplicated the node and down elements.
+// MR9 Made copies of the pointers to sibling.
+// MR9 Changed call "down()->deepCopy()" to "down()->deepCopyBushy()"
+// MR9
+
+PCCTS_AST *PCCTS_AST::
+deepCopy()
+{
+ PCCTS_AST *u = this->shallowCopy();
+ if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());
+ u->setRight(NULL);
+ return u;
+}
+
+/* Copy all nodes including siblings of root. */
+PCCTS_AST *PCCTS_AST::
+deepCopyBushy()
+{
+ PCCTS_AST *u = this->shallowCopy();
+ /* copy the rest of the tree */
+ if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());
+ if ( right()!=NULL ) u->setRight(right()->deepCopyBushy());
+ return u;
+}
+
+void PCCTS_AST::
+scanast_free(ScanAST *t)
+{
+ if ( t == NULL ) return;
+ scanast_free( t->down() );
+ scanast_free( t->right() );
+ free( (char *) t ); // MR1
+}
+
+/*
+ * scan
+ *
+ * This function is like scanf(): it attempts to match a template
+ * against an input tree. A variable number of tree pointers
+ * may be set according to the '%i' labels in the template string.
+ * For example:
+ *
+ * t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",
+ * &w, &x, &y, &z);
+ *
+ * Naturally, you'd want this converted from
+ *
+ * t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )",
+ * &w, &x, &y, &z);
+ *
+ * by SORCERER.
+ *
+ * This function call must be done withing a SORCERER file because SORCERER
+ * must convert the token references to the associated token number.
+ *
+ * This functions parses the template and creates trees which are then
+ * matched against the input tree. The labels are set as they are
+ * encountered; hence, partial matches may leave some pointers set
+ * and some NULL. This routines initializes all argument pointers to NULL
+ * at the beginning.
+ *
+ * This function returns the number of labels matched.
+ */
+int PCCTS_AST::
+ast_scan(char *templ, ...)
+{
+ va_list ap;
+ ScanAST *tmpl;
+ int n, i, found=0;
+ PCCTS_AST ***label_ptrs=NULL;
+
+ va_start(ap, templ);
+
+ /* make a ScanAST tree out of the template */
+ tmpl = stringparser_parse_scanast(templ, &n);
+
+ /* make an array out of the labels */
+ if ( n>0 )
+ {
+ label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **));
+ require(label_ptrs!=NULL, "scan: out of memory");
+ for (i=1; i<=n; i++)
+ {
+ label_ptrs[i-1] = va_arg(ap, PCCTS_AST **);
+ *(label_ptrs[i-1]) = NULL;
+ }
+ }
+
+ /* match the input tree against the template */
+ scanmatch(tmpl, label_ptrs, &found);
+
+ scanast_free(tmpl);
+ free( (char *) label_ptrs); // MR1
+
+ return found;
+}
+
+ScanAST *PCCTS_AST::
+new_scanast(int tok)
+{
+ ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST));
+//
+// 7-Apr-97 133MR1
+//
+ if ( p == NULL )
+ panic("out of memory\n"); // MR23
+ p->_token = tok;
+ return p;
+}
+
+ScanAST *PCCTS_AST::
+stringparser_parse_scanast(char *templ, int *num_labels)
+{
+ StringLexer lex;
+ StringParser parser;
+ ScanAST *t;
+
+ stringlexer_init(&lex, templ);
+ stringparser_init(&parser, &lex);
+ t = stringparser_parse_tree(&parser);
+ *num_labels = parser.num_labels;
+ return t;
+}
+
+void PCCTS_AST::
+stringparser_match(StringParser *parser, int token)
+{
+ if ( parser->token != token ) panic("bad tree in scan()");
+}
+
+/*
+ * Match a tree of the form:
+ * (root child1 child2 ... childn)
+ * or,
+ * node
+ *
+ * where the elements are integers or labeled integers.
+ */
+ScanAST *PCCTS_AST::
+stringparser_parse_tree(StringParser *parser)
+{
+ ScanAST *t=NULL, *root, *child, *last=NULL /*MR23*/;
+
+ if ( parser->token != __POUND )
+ {
+ return stringparser_parse_element(parser);
+ }
+ stringparser_match(parser,__POUND);
+ parser->token = stringscan_gettok(parser->lexer);
+ stringparser_match(parser,__LPAREN);
+ parser->token = stringscan_gettok(parser->lexer);
+ root = stringparser_parse_element(parser);
+ while ( parser->token != __RPAREN )
+ {
+ child = stringparser_parse_element(parser);
+ if ( t==NULL ) { t = child; last = t; }
+ else { last->_right = child; last = child; }
+ }
+ stringparser_match(parser,__RPAREN);
+ parser->token = stringscan_gettok(parser->lexer);
+ root->_down = t;
+ return root;
+}
+
+ScanAST *PCCTS_AST::
+stringparser_parse_element(StringParser *parser)
+{
+ char ebuf[100];
+ int label = 0;
+
+ if ( parser->token == __POUND )
+ {
+ return stringparser_parse_tree(parser);
+ }
+ if ( parser->token == __PERCENT )
+ {
+ parser->token = stringscan_gettok(parser->lexer);
+ stringparser_match(parser,__INT);
+ label = atoi(parser->lexer->text);
+ parser->num_labels++;
+ if ( label==0 ) panic("%%0 is an invalid label");
+ parser->token = stringscan_gettok(parser->lexer);
+ stringparser_match(parser,__COLON);
+ parser->token = stringscan_gettok(parser->lexer);
+ /* can label tokens and wildcards */
+ if ( parser->token != __INT && parser->token != __PERIOD )
+ panic("can only label tokens");
+ }
+ if ( parser->token == __INT )
+ {
+ ScanAST *p = new_scanast(atoi(parser->lexer->text));
+ parser->token = stringscan_gettok(parser->lexer);
+ p->label_num = label;
+ return p;
+ }
+ if ( parser->token == __PERIOD )
+ {
+ ScanAST *p = new_scanast(0); /* token of 0 is wildcard */
+ parser->token = stringscan_gettok(parser->lexer);
+ p->label_num = label;
+ return p;
+ }
+ sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token));
+ panic(ebuf);
+ return NULL;
+}
+
+void PCCTS_AST::
+stringparser_init(StringParser *parser, StringLexer *input)
+{
+ parser->lexer = input;
+ parser->token = stringscan_gettok(parser->lexer);
+ parser->num_labels = 0;
+}
+
+void PCCTS_AST::
+stringlexer_init(StringLexer *scanner, char *input)
+{
+ scanner->text[0]='\0';
+ scanner->input = input;
+ scanner->p = input;
+ stringscan_advance(scanner);
+}
+
+void PCCTS_AST::
+stringscan_advance(StringLexer *scanner)
+{
+ if ( *(scanner->p) == '\0' ) scanner->c = __StringScanEOF;
+ scanner->c = *(scanner->p)++;
+}
+
+int PCCTS_AST::
+stringscan_gettok(StringLexer *scanner)
+{
+ char *index = &scanner->text[0];
+ char ebuf[100]; /* MR23 Remove static */
+
+ while ( isspace(scanner->c) ) { stringscan_advance(scanner); }
+ if ( isdigit(scanner->c) )
+ {
+ int tok = __INT;
+ while ( isdigit(scanner->c) ) {
+ *index++ = (char) /* static_cast<char> */ (scanner->c); // MR23
+ stringscan_advance(scanner);
+ }
+ *index = '\0';
+ return tok;
+ }
+ switch ( scanner->c )
+ {
+ case '#' : stringscan_advance(scanner); return __POUND;
+ case '(' : stringscan_advance(scanner); return __LPAREN;
+ case ')' : stringscan_advance(scanner); return __RPAREN;
+ case '%' : stringscan_advance(scanner); return __PERCENT;
+ case ':' : stringscan_advance(scanner); return __COLON;
+ case '.' : stringscan_advance(scanner); return __PERIOD;
+ case '\0' : return __StringScanEOF;
+ case __StringScanEOF : return __StringScanEOF;
+ default :
+ sprintf(ebuf, "invalid char in scan: '%c'", scanner->c);
+ panic(ebuf);
+ }
+ return __StringScanEOF; // never reached
+}
+
+const char *PCCTS_AST:: /* MR20 const */
+scan_token_str(int t)
+{
+ if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t];
+ else if ( t==__StringScanEOF ) return "<end-of-string>";
+ else return "<invalid-token>";
+}
+
+//MR23
+int PCCTS_AST::printMessage(FILE* pFile, const char* pFormat, ...)
+{
+ va_list marker;
+ va_start( marker, pFormat );
+ int iRet = vfprintf(pFile, pFormat, marker);
+ va_end( marker );
+ return iRet;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.h
new file mode 100644
index 00000000..9fb3fd7a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/PCCTSAST.h
@@ -0,0 +1,143 @@
+/* Abstract syntax tree
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef PCCTSAST_H
+#define PCCTSAST_H
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+#include "pccts_stdlib.h"
+
+PCCTS_NAMESPACE_STD
+
+//class SList;
+
+#define StringScanMaxText 50
+#define MaxTreeStackDepth 400
+
+//
+// 7-Apr-97 133MR1 signed int not accepted by AT&T cfront
+//
+typedef struct stringlexer {
+ int c; // MR1
+ char *input;
+ char *p;
+ char text[StringScanMaxText];
+ } StringLexer;
+
+/* Define the structures needed for ast_scan() */
+typedef struct stringparser {
+ int token;
+ StringLexer *lexer;
+ int num_labels;
+ } StringParser;
+
+typedef struct _scanast {
+ struct _scanast *_right, *_down;
+ int _token;
+ int label_num;
+ int type() { return _token; }
+ struct _scanast *right() { return _right; }
+ struct _scanast *down() { return _down; }
+ } ScanAST;
+
+#define VALID_SCAN_TOKEN(t) (t>=__LPAREN && t<=__PERIOD)
+
+class DllExportPCCTS PCCTS_AST {
+protected:
+ static const char *scan_token_tbl[]; /* MR20 const */
+ enum {
+ __LPAREN=1,
+ __RPAREN=2,
+ __PERCENT=3,
+ __INT=4,
+ __COLON=5,
+ __POUND=6,
+ __PERIOD=7,
+ __StringScanEOF=-1};
+
+protected:
+ const char *scan_token_str(int t); /* MR20 const */
+ void stringlexer_init(StringLexer *scanner, char *input);
+ void stringparser_init(StringParser *, StringLexer *);
+ ScanAST *stringparser_parse_scanast(char *templ, int *n);
+ ScanAST *stringparser_parse_tree(StringParser *parser);
+ ScanAST *stringparser_parse_element(StringParser *parser);
+ void stringscan_advance(StringLexer *scanner);
+ int stringscan_gettok(StringLexer *scanner);
+ void _push(PCCTS_AST **st, int *sp, PCCTS_AST *e);
+ PCCTS_AST *_pop(PCCTS_AST **st, int *sp);
+ int match_partial(PCCTS_AST *t, PCCTS_AST *u);
+ int scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n);
+ void scanast_free(ScanAST *t);
+ ScanAST *new_scanast(int tok);
+ void stringparser_match(StringParser *parser, int type);
+ virtual PCCTS_AST *deepCopyBushy();
+
+public:
+ PCCTS_AST() {;}
+ virtual ~PCCTS_AST() {;}
+
+ /* This group must be defined for SORCERER to work correctly */
+ virtual PCCTS_AST *right() = 0;
+ virtual PCCTS_AST *down() = 0;
+ virtual void setRight(PCCTS_AST *t) = 0;
+ virtual void setDown(PCCTS_AST *t) = 0;
+// we define these so ANTLR doesn't have to
+ virtual int type() { return 0; }
+ virtual void setType(int /*t MR23 */) {;}
+ virtual PCCTS_AST *shallowCopy() {panic("no shallowCopy() defined"); return NULL;}
+
+ /* These are not needed by ANTLR, but are support functions */
+ virtual PCCTS_AST *deepCopy(); // used by SORCERER in transform mode
+ virtual void addChild(PCCTS_AST *t);
+ virtual void lisp_action(FILE * /*f MR23 */) {;}
+ virtual void lisp(FILE *f);
+ static PCCTS_AST *make(PCCTS_AST *rt, ...);
+ virtual PCCTS_AST *ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor);
+ virtual int match(PCCTS_AST *u);
+ virtual void insert_after(PCCTS_AST *b);
+ virtual void append(PCCTS_AST *b);
+ virtual PCCTS_AST *tail();
+ virtual PCCTS_AST *bottom();
+ static PCCTS_AST *cut_between(PCCTS_AST *a, PCCTS_AST *b);
+// virtual SList *to_slist();
+ virtual void tfree();
+ int ast_scan(char *templ, ...);
+ virtual int nsiblings();
+ virtual PCCTS_AST *sibling_index(int i);
+
+ void require(int e,const char *err){ if ( !e ) panic(err); } /* MR20 const */
+ virtual void panic(const char *err) // MR20 const
+ { /* MR23 */ printMessage(stderr, "PCCTS_AST: %s\n", err); exit(PCCTS_EXIT_FAILURE); }
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23
+};
+
+#endif /* PCCTSAST_H */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/SList.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/SList.h
new file mode 100644
index 00000000..34354ccd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/SList.h
@@ -0,0 +1,72 @@
+#ifndef SList_h
+#define SList_h
+
+/*
+ * SList.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
+ * domain. An individual or company may do whatever they wish with
+ * source code distributed with SORCERER or the code generated by
+ * SORCERER, including the incorporation of SORCERER, or its output, into
+ * commerical software.
+ *
+ * We encourage users to develop software with SORCERER. However, we do
+ * ask that credit is given to us for developing SORCERER. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like SORCERER and have developed a nice tool with the
+ * output, please mention that you developed it using SORCERER. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * PCCTS 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1992-2000
+ */
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+#include "pccts_stdlib.h"
+
+PCCTS_NAMESPACE_STD
+
+#include "PCCTSAST.h"
+
+class PCCTS_AST;
+
+class SListNode {
+protected:
+ void *_elem; /* pointer to any kind of element */
+ SListNode *_next;
+public:
+ SListNode() {_elem=_next=NULL;}
+ virtual ~SListNode() {_elem=_next=NULL;}
+ void *elem() { return _elem; }
+ void setElem(void *e) { _elem = e; }
+ void setNext(SListNode *t) { _next = t; }
+ SListNode *next() { return _next; }
+};
+
+class SList {
+ SListNode *head, *tail;
+public:
+ SList() {head=tail=NULL;}
+ virtual ~SList() {head=tail=NULL;}
+ virtual void *iterate(SListNode **);
+ virtual void add(void *e);
+ virtual void lfree();
+ virtual PCCTS_AST *to_ast(SList list);
+ virtual void require(int e,char *err){ if ( !e ) panic(err); }
+ virtual void panic(char *err){ /* MR23 */ printMessage(stderr, "SList panic: %s\n", err); exit(PCCTS_EXIT_FAILURE); }
+ virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/antlr.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/antlr.h
new file mode 100644
index 00000000..9d50bd83
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/antlr.h
@@ -0,0 +1,807 @@
+/* antlr.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ANTLR_H
+#define ANTLR_H
+
+#include "pcctscfg.h"
+
+#include "pccts_stdio.h"
+
+/* turn off warnings for unreferenced labels */
+
+#ifdef _MSC_VER
+#pragma warning(disable:4102)
+#endif
+
+/*
+ * Define all of the stack setup and manipulation of $i, #i variables.
+ *
+ * Notes:
+ * The type 'Attrib' must be defined before entry into this .h file.
+ */
+
+
+#ifdef __USE_PROTOS
+#include "pccts_stdlib.h"
+#else
+#ifdef VAXC
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#endif
+#include "pccts_string.h"
+
+#if 0
+#include "set.h"
+#endif
+
+
+typedef int ANTLRTokenType;
+typedef unsigned char SetWordType;
+
+typedef char ANTLRChar;
+
+ /* G u e s s S t u f f */
+
+#ifdef ZZCAN_GUESS
+#ifndef ZZINF_LOOK
+#define ZZINF_LOOK
+#endif
+#endif
+
+#ifdef ZZCAN_GUESS
+typedef struct _zzjmp_buf {
+ jmp_buf state;
+ } zzjmp_buf;
+#endif
+
+
+/* can make this a power of 2 for more efficient lookup */
+
+#ifndef ZZLEXBUFSIZE
+#define ZZLEXBUFSIZE 8000 /* MR22 raise from 2k to 8k */
+#endif
+
+#define zzOvfChk \
+ if ( zzasp <= 0 ) \
+ { \
+ fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \
+ exit(PCCTS_EXIT_FAILURE); \
+ }
+
+#ifndef ZZA_STACKSIZE
+#define ZZA_STACKSIZE 400
+#endif
+#ifndef ZZAST_STACKSIZE
+#define ZZAST_STACKSIZE 400
+#endif
+
+#ifndef zzfailed_pred
+#ifdef ZZCAN_GUESS
+#define zzfailed_pred(_p,_hasuseraction,_useraction) \
+ if (zzguessing) { \
+ zzGUESS_FAIL; \
+ } else { \
+ zzfailed_pred_action(_p,_hasuseraction,_useraction); \
+ }
+#else
+#define zzfailed_pred(_p,_hasuseraction,_useraction) \
+ zzfailed_pred_action(_p,_hasuseraction,_useraction);
+#endif
+#endif
+
+/* MR23 Provide more control over failed predicate action
+ without any need for user to worry about guessing internals.
+ _hasuseraction == 0 => no user specified error action
+ _hasuseraction == 1 => user specified error action
+*/
+
+#ifndef zzfailed_pred_action
+#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \
+ if (_hasuseraction) { _useraction } \
+ else { fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p); }
+#endif
+
+/* MR19 zzchar_t additions */
+
+#ifdef LL_K
+#define LOOKAHEAD \
+ int zztokenLA[LL_K]; \
+ zzchar_t zztextLA[LL_K][ZZLEXBUFSIZE]; \
+ int zzlap = 0, zzlabase=0; /* labase only used for DEMAND_LOOK */
+#else
+#define LOOKAHEAD \
+ int zztoken;
+#endif
+
+#ifndef zzcr_ast
+#define zzcr_ast(ast,attr,tok,text)
+#endif
+
+#ifdef DEMAND_LOOK
+#define DemandLookData int zzdirty=1;
+#else
+#define DemandLookData
+#endif
+
+#ifndef zzUSER_GUESS_HOOK
+#define zzUSER_GUESS_HOOK(seqFrozen,zzrv)
+#endif
+
+#ifndef zzUSER_GUESS_DONE_HOOK
+#define zzUSER_GUESS_DONE_HOOK(seqFrozen)
+#endif
+
+ /* S t a t e S t u f f */
+
+#ifdef ZZCAN_GUESS
+#define zzGUESS_BLOCK zzantlr_state zzst; int zzrv; int zzGuessSeqFrozen;
+
+/* MR10 change zzGUESS: do zzGUESS_DONE when zzrv==1 after longjmp as in C++ mode */
+
+#define zzGUESS zzsave_antlr_state(&zzst); \
+ zzguessing = 1; \
+ zzGuessSeqFrozen=++zzGuessSeq; \
+ zzrv = setjmp(zzguess_start.state); \
+ zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \
+ if (zzrv) zzGUESS_DONE;
+#ifdef zzTRACE_RULES
+#define zzGUESS_FAIL { zzTraceGuessFail(); longjmp(zzguess_start.state, 1); }
+#else
+#define zzGUESS_FAIL longjmp(zzguess_start.state, 1)
+#endif
+
+/* MR10 change zzGUESS_DONE: zzrv=1 to simulate longjmp() return value as in C++ mode */
+
+#define zzGUESS_DONE { zzrestore_antlr_state(&zzst); zzrv=1; zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) }
+#define zzNON_GUESS_MODE if ( !zzguessing )
+#define zzGuessData \
+ zzjmp_buf zzguess_start; \
+ int zzguessing;
+#else
+#define zzGUESS_BLOCK
+#define zzGUESS
+#define zzGUESS_FAIL
+#define zzGUESS_DONE
+#define zzNON_GUESS_MODE
+#define zzGuessData
+#endif
+
+typedef struct _zzantlr_state {
+#ifdef ZZCAN_GUESS
+ zzjmp_buf guess_start;
+ int guessing;
+#endif
+ int asp;
+ int ast_sp;
+#ifdef ZZINF_LOOK
+ int inf_lap; /* not sure we need to save this one */
+ int inf_labase;
+ int inf_last;
+
+/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */
+/* MR6 Additional state needs to be saved/restored */
+/* MR6 Matching changes in err.h */
+
+ int *inf_tokens; /* MR6 */
+ char **inf_text; /* MR6 */
+ char *inf_text_buffer; /* MR6 */
+ int *inf_line; /* MR6 */
+#endif
+#ifdef DEMAND_LOOK
+ int dirty;
+#endif
+
+#ifdef LL_K
+ int tokenLA[LL_K];
+ char textLA[LL_K][ZZLEXBUFSIZE];
+ int lap;
+ int labase;
+#else
+ int token;
+ char text[ZZLEXBUFSIZE];
+#endif
+#ifdef zzTRACE_RULES
+ int traceOptionValue; /* MR10 */
+ int traceGuessOptionValue; /* MR10 */
+ char *traceCurrentRuleName; /* MR10 */
+ int traceDepth; /* MR10 */
+#endif
+
+ } zzantlr_state;
+
+#ifdef zzTRACE_RULES
+extern int zzTraceOptionValueDefault;
+extern int zzTraceOptionValue;
+extern int zzTraceGuessOptionValue;
+extern char *zzTraceCurrentRuleName;
+extern int zzTraceDepth;
+#endif
+
+extern int zzGuessSeq; /* MR10 */
+extern int zzSyntaxErrCount; /* MR11 */
+extern int zzLexErrCount; /* MR11 */
+
+ /* I n f i n i t e L o o k a h e a d */
+
+
+#ifdef ZZINF_LOOK
+#define InfLookData \
+ int *zzinf_tokens; \
+ char **zzinf_text; \
+ char *zzinf_text_buffer; \
+ int *zzinf_line; \
+ int zzinf_labase; \
+ int zzinf_last;
+#else
+#define InfLookData
+#endif
+
+#ifdef ZZINF_LOOK
+
+#ifndef ZZINF_DEF_TEXT_BUFFER_SIZE
+#define ZZINF_DEF_TEXT_BUFFER_SIZE 20000
+#endif
+#ifndef ZZINF_DEF_TOKEN_BUFFER_SIZE
+#define ZZINF_DEF_TOKEN_BUFFER_SIZE 2000
+#endif
+/* WARNING!!!!!!
+ * ZZINF_BUFFER_TEXT_CHUNK_SIZE must be > sizeof(text) largest possible token.
+ */
+#ifndef ZZINF_BUFFER_TEXT_CHUNK_SIZE
+#define ZZINF_BUFFER_TEXT_CHUNK_SIZE 5000
+#endif
+#ifndef ZZINF_BUFFER_TOKEN_CHUNK_SIZE
+#define ZZINF_BUFFER_TOKEN_CHUNK_SIZE 1000
+#endif
+
+#if ZZLEXBUFSIZE > ZZINF_BUFFER_TEXT_CHUNK_SIZE
+#define ZZINF_BUFFER_TEXT_CHUNK_SIZE ZZLEXBUFSIZE+5
+#endif
+
+/* make inf_look user-access macros */
+#ifdef LL_K
+#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)-LL_K+1) <= zzinf_last)
+#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)-LL_K+1]
+#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)-LL_K+1]
+/* MR6 In 1.33 vanilla the #define ZZINF_LINE(i) is was commented out */
+#define ZZINF_LINE(i) zzinf_line[(zzinf_labase+i-1)-LL_K+1]
+#else
+#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)) <= zzinf_last)
+#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)]
+#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)]
+#endif
+
+#define inf_zzgettok _inf_zzgettok()
+extern void _inf_zzgettok();
+
+#endif /* ZZINF_LOOK */
+
+
+#ifdef LL_K
+
+#ifdef __USE_PROTOS
+#define ANTLR_INFO \
+ Attrib zzempty_attr(void) {static Attrib a; return a;} \
+ Attrib zzconstr_attr(int _tok, char *_text) \
+ {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
+ int zzasp=ZZA_STACKSIZE; \
+ char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
+ Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
+ InfLookData \
+ zzGuessData
+#else
+#define ANTLR_INFO \
+ Attrib zzempty_attr() {static Attrib a; return a;} \
+ Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \
+ {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
+ int zzasp=ZZA_STACKSIZE; \
+ char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
+ Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
+ InfLookData \
+ zzGuessData
+#endif
+
+#else
+
+#ifdef __USE_PROTOS
+#define ANTLR_INFO \
+ Attrib zzempty_attr(void) {static Attrib a; return a;} \
+ Attrib zzconstr_attr(int _tok, char *_text) \
+ {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
+ int zzasp=ZZA_STACKSIZE; \
+ char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
+ Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
+ InfLookData \
+ zzGuessData
+#else
+#define ANTLR_INFO \
+ Attrib zzempty_attr() {static Attrib a; return a;} \
+ Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \
+ {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
+ int zzasp=ZZA_STACKSIZE; \
+ char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
+ Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
+ InfLookData \
+ zzGuessData
+#endif
+
+#endif /* LL_k */
+
+
+#ifdef ZZINF_LOOK
+
+#ifdef LL_K
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;}
+#else
+#define zzPrimeLookAhead {zzlap = zzlabase = 0; zzfill_inf_look();\
+ {int _i; for(_i=1;_i<=LL_K; _i++) \
+ {zzCONSUME;} zzlap = zzlabase = 0;}}
+#endif
+
+#else /* LL_K */
+
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead zzfill_inf_look(); zzdirty=1
+#else
+#define zzPrimeLookAhead zzfill_inf_look(); inf_zzgettok
+
+#endif
+#endif /* LL_K */
+
+#else /* ZZINF_LOOK */
+
+#ifdef LL_K
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;}
+#else
+#define zzPrimeLookAhead {int _i; zzlap = 0; for(_i=1;_i<=LL_K; _i++) \
+ {zzCONSUME;} zzlap = 0;}
+#endif
+
+#else
+
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead zzdirty=1
+#else
+#define zzPrimeLookAhead zzgettok()
+#endif
+#endif /* LL_K */
+
+#endif /* ZZINF_LOOK */
+
+
+#ifdef LL_K
+#define zzenterANTLRs(s) \
+ zzlextext = &(zztextLA[0][0]); zzrdstr( s ); zzPrimeLookAhead;
+#define zzenterANTLRf(f) \
+ zzlextext = &(zztextLA[0][0]); zzrdfunc( f ); zzPrimeLookAhead;
+#define zzenterANTLR(f) \
+ zzlextext = &(zztextLA[0][0]); zzrdstream( f ); zzPrimeLookAhead;
+#ifdef ZZINF_LOOK
+#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#else
+#define zzleaveANTLR(f)
+#define zzleaveANTLRf(f)
+#define zzleaveANTLRs(f)
+#endif
+
+#else
+
+#define zzenterANTLRs(s) \
+ {static char zztoktext[ZZLEXBUFSIZE]; \
+ zzlextext = zztoktext; zzrdstr( s ); zzPrimeLookAhead;}
+#define zzenterANTLRf(f) \
+ {static char zztoktext[ZZLEXBUFSIZE]; \
+ zzlextext = zztoktext; zzrdfunc( f ); zzPrimeLookAhead;}
+#define zzenterANTLR(f) \
+ {static char zztoktext[ZZLEXBUFSIZE]; \
+ zzlextext = zztoktext; zzrdstream( f ); zzPrimeLookAhead;}
+#ifdef ZZINF_LOOK
+#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#else
+#define zzleaveANTLR(f)
+#define zzleaveANTLRf(f)
+#define zzleaveANTLRs(f)
+#endif
+
+#endif
+
+/* MR19 Paul D. Smith (psmith@baynetworks.com)
+ Need to adjust AST stack pointer at exit.
+ Referenced in ANTLRx macros.
+*/
+
+#ifdef GENAST
+#define ZZAST_ADJUST ++zzast_sp;
+#else
+#define ZZAST_ADJUST
+#endif
+
+#define ANTLR(st, f) zzbufsize = ZZLEXBUFSIZE; \
+ zzenterANTLR(f); \
+ { \
+ zzBLOCK(zztasp1); \
+ st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
+ /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
+ /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
+ zzEXIT_ANTLR(zztasp1 + 1); \
+ } \
+ zzleaveANTLR(f);
+
+#define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE; \
+ zzmode(_m); \
+ zzenterANTLR(f); \
+ { \
+ zzBLOCK(zztasp1); \
+ st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
+ /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
+ /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
+ zzEXIT_ANTLR(zztasp1 + 1); \
+ } \
+ zzleaveANTLR(f);
+
+#define ANTLRf(st, f) zzbufsize = ZZLEXBUFSIZE; \
+ zzenterANTLRf(f); \
+ { \
+ zzBLOCK(zztasp1); \
+ st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
+ /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
+ /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
+ zzEXIT_ANTLR(zztasp1 + 1); \
+ } \
+ zzleaveANTLRf(f);
+
+#define ANTLRs(st, s) zzbufsize = ZZLEXBUFSIZE; \
+ zzenterANTLRs(s); \
+ { \
+ zzBLOCK(zztasp1); \
+ st; /* ++zzasp; Removed MR20 G. Hobbelt */ \
+ /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \
+ /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \
+ zzEXIT_ANTLR(zztasp1 + 1); \
+ } \
+ zzleaveANTLRs(s);
+
+#ifdef LL_K
+#define zztext (&(zztextLA[zzlap][0]))
+#else
+#define zztext zzlextext
+#endif
+
+
+ /* A r g u m e n t A c c e s s */
+
+#define zzaCur (zzaStack[zzasp])
+#define zzaRet (*zzaRetPtr)
+#define zzaArg(v,n) zzaStack[v-n]
+#define zzMakeAttr { zzNON_GUESS_MODE {zzOvfChk; --zzasp; zzcr_attr(&(zzaStack[zzasp]),LA(1),LATEXT(1));}}
+#ifdef zzdef0
+#define zzMake0 { zzOvfChk; --zzasp; zzdef0(&(zzaStack[zzasp]));}
+#else
+#define zzMake0 { zzOvfChk; --zzasp;}
+#endif
+#define zzaPush(_v) { zzOvfChk; zzaStack[--zzasp] = _v;}
+#ifndef zzd_attr
+#define zzREL(t) zzasp=(t); /* Restore state of stack */
+#else
+#define zzREL(t) for (; zzasp<(t); zzasp++) \
+ { zzd_attr(&(zzaStack[zzasp])); }
+#endif
+
+
+#define zzsetmatch(_es,_tokclassErrset) \
+ if ( !_zzsetmatch(_es, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail; /* MR23 */
+
+#ifdef ZZCAN_GUESS
+#define zzsetmatch_wsig(_es, handler) \
+ if ( !_zzsetmatch_wsig(_es) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;}
+#else
+#define zzsetmatch_wsig(_es, handler) \
+ if ( !_zzsetmatch_wsig(_es) ) {_signal=MismatchedToken; goto handler;}
+#endif
+
+#ifdef __USE_PROTOS
+extern int _zzsetmatch(SetWordType *, char **, char **, int *, int *, SetWordType **, SetWordType * /* MR23 */);
+extern int _zzsetmatch_wsig(SetWordType *);
+#else
+extern int _zzsetmatch();
+extern int _zzsetmatch_wsig();
+#endif
+
+#define zzmatch(_t) \
+ if ( !_zzmatch(_t, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail;
+
+#ifdef ZZCAN_GUESS
+#define zzmatch_wsig(_t,handler) \
+ if ( !_zzmatch_wsig(_t) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;}
+#else
+#define zzmatch_wsig(_t,handler) \
+ if ( !_zzmatch_wsig(_t) ) {_signal=MismatchedToken; goto handler;}
+#endif
+
+#ifdef __USE_PROTOS
+extern int _zzmatch(int, char **, char **, int *, int *, SetWordType **);
+extern int _zzmatch_wsig(int);
+#else
+extern int _zzmatch();
+extern int _zzmatch_wsig();
+#endif
+
+#define zzmatch_wdfltsig(_t,_f) \
+ if ( !_zzmatch_wdfltsig(_t,_f) ) _signal=MismatchedToken;
+#define zzsetmatch_wdfltsig(tw,tt,wf) \
+ if ( !_zzsetmatch_wdfltsig(tw,tt,wf) ) _signal=MismatchedToken;
+
+#ifdef __USE_PROTOS
+extern int _zzmatch_wdfltsig(int, SetWordType *);
+extern int _zzsetmatch_wdfltsig(SetWordType *tokensWanted,
+ int tokenTypeOfSet,
+ SetWordType *whatFollows);
+#else
+extern int _zzmatch_wdfltsig();
+extern int _zzsetmatch_wdfltsig();
+#endif
+
+#ifdef GENAST
+#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \
+ SetWordType *zzMissSet=NULL; int zzMissTok=0; \
+ int zzBadTok=0; char *zzBadText=""; \
+ int zzErrk=1,zzpf=0; \
+ zzTRACEdata \
+ char *zzMissText=""; zzASTVars
+#else
+#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \
+ int zzBadTok=0; char *zzBadText=""; \
+ int zzErrk=1,zzpf=0; \
+ zzTRACEdata \
+ SetWordType *zzMissSet=NULL; int zzMissTok=0; char *zzMissText=""
+#endif
+
+#ifdef GENAST
+#define zzBLOCK(i) int i = zzasp - 1; int zztsp = zzast_sp
+#define zzEXIT(i) zzREL(i); zzastREL; zzNON_GUESS_MODE { zzastPush(*_root); }
+#define zzEXIT_ANTLR(i) zzREL(i); zzastREL /* [i_a] added as we want this for the ANTLRx() macros */
+#define zzLOOP(i) zzREL(i); zzastREL
+#else
+#define zzBLOCK(i) int i = zzasp - 1
+#define zzEXIT(i) zzREL(i)
+#define zzEXIT_ANTLR(i) zzREL(i) /* [i_a] added as we want this for the ANTLRx() macros */
+#define zzLOOP(i) zzREL(i)
+#endif
+
+#ifdef LL_K
+
+#ifdef DEMAND_LOOK
+#define LOOK(_k) {int i,stop=_k-(LL_K-zzdirty); for (i=1; i<=stop; i++) \
+ zzCONSUME;}
+#define zzCONSUME {zzgettok(); zzdirty--; \
+ zzlap = (zzlap+1)&(LL_K-1); \
+ zzlextext = &(zztextLA[zzlap][0]);}
+#else
+#ifdef ZZINF_LOOK
+#define zzCONSUME {inf_zzgettok; \
+ zzlap = (zzlap+1)&(LL_K-1); \
+ zzlextext = &(zztextLA[zzlap][0]); \
+ }
+#else
+#define zzCONSUME {zzgettok(); \
+ zzlap = (zzlap+1)&(LL_K-1); \
+ zzlextext = &(zztextLA[zzlap][0]);}
+#endif /* ZZINF_LOOK */
+#endif /* DEMAND_LOOK */
+
+#else /* LL_K */
+
+#ifdef DEMAND_LOOK
+#define LOOK(_k) if ( zzdirty) zzCONSUME;
+#ifdef ZZINF_LOOK
+#define zzCONSUME inf_zzgettok; zzdirty=0;
+#else
+#define zzCONSUME zzgettok(); zzdirty=0;
+#endif /* ZZINF_LOOK */
+
+#else /* DEMAND_LOOK */
+
+#ifdef ZZINF_LOOK
+#define zzCONSUME inf_zzgettok
+#else
+#define zzCONSUME zzgettok();
+#endif
+
+#endif /* DEMAND_LOOK */
+
+#endif /* LL_K */
+
+#ifdef LL_K
+#define NLA zztokenLA[zzlap&(LL_K-1)] /* --> next LA */
+#define NLATEXT zztextLA[zzlap&(LL_K-1)] /* --> next text of LA */
+#ifdef DEMAND_LOOK
+#define LA(i) zztokenLA[(zzlabase+(i)-1)&(LL_K-1)]
+#define LATEXT(i) (&(zztextLA[(zzlabase+(i)-1)&(LL_K-1)][0]))
+#else
+#define LA(i) zztokenLA[(zzlap+(i)-1)&(LL_K-1)]
+#define LATEXT(i) (&(zztextLA[(zzlap+(i)-1)&(LL_K-1)][0]))
+#endif
+#else
+#define NLA zztoken
+#define NLATEXT zztext
+#define LA(i) zztoken
+#define LATEXT(i) zztext
+#endif
+
+
+ /* S t a n d a r d S i g n a l s */
+
+#define NoSignal 0
+#define MismatchedToken 1
+#define NoViableAlt 2
+#define NoSemViableAlt 3
+
+/* MR7 Allow more control over signalling */
+/* by adding "Unwind" and "zzsetSignal" */
+
+#define Unwind 4
+#define zzsetSignal(newValue) *_retsignal=_signal=(newValue)
+#define zzsuppressSignal *_retsignal=_signal=0
+#define zzexportSignal *_retsignal=_signal
+
+ /* F u n c t i o n T r a c i n g */
+
+#ifndef zzTRACE_RULES
+#define zzTRACEdata
+#else
+#ifndef zzTRACEdata
+#define zzTRACEdata ANTLRChar *zzTracePrevRuleName = NULL;
+#endif
+#endif
+
+#ifndef zzTRACEIN
+#define zzTRACEIN(r) zzTracePrevRuleName=zzTraceCurrentRuleName;zzTraceIn(r);
+#endif
+#ifndef zzTRACEOUT
+#define zzTRACEOUT(r) zzTraceOut(r);zzTraceCurrentRuleName=zzTracePrevRuleName;
+#endif
+
+/* MR19 zzchar_t additions */
+
+#ifndef zzchar_t
+#ifdef ZZWCHAR_T
+#define zzchar_t wchar_t
+#else
+#define zzchar_t char
+#endif
+#endif
+
+
+/* MR26 */
+
+#ifdef PCCTS_USE_STDARG
+extern void zzFAIL(int k, ...);
+#else
+extern void zzFAIL();
+#endif
+ /* E x t e r n D e f s */
+
+#ifdef __USE_PROTOS
+extern Attrib zzempty_attr(void);
+extern Attrib zzconstr_attr(int, char *);
+extern void zzsyn(char *, int, char *, SetWordType *, int, int, char *);
+extern int zzset_el(unsigned, SetWordType *);
+extern int zzset_deg(SetWordType *);
+extern void zzedecode(SetWordType *);
+
+extern void zzresynch(SetWordType *, SetWordType);
+extern void zzsave_antlr_state(zzantlr_state *);
+extern void zzrestore_antlr_state(zzantlr_state *);
+extern void zzfill_inf_look(void);
+extern void zzconsumeUntil(SetWordType *st); /* MR7 */
+extern void zzconsumeUntilToken(int t); /* MR7 */
+extern void zzTraceIn(char * ruleName); /* MR10 */
+extern void zzTraceOut(char * ruleName); /* MR10 */
+extern int zzTraceOption(int delta); /* MR10 */
+extern int zzTraceGuessOption(int delta); /* MR10 */
+extern void zzTraceReset(void); /* MR10 */
+extern void zzTraceGuessFail(void); /* MR10 */
+#ifdef EXCEPTION_HANDLING
+extern void zzdflthandlers(int, int *);
+#endif
+#else
+extern Attrib zzempty_attr();
+extern Attrib zzconstr_attr();
+extern void zzsyn();
+extern int zzset_el();
+extern int zzset_deg();
+extern void zzedecode();
+extern void zzresynch();
+extern void zzsave_antlr_state();
+extern void zzrestore_antlr_state();
+extern void zzfill_inf_look();
+extern void zzconsumeUntil(); /* MR7 */
+extern void zzconsumeUntilToken(); /* MR7 */
+extern void zzTraceIn(); /* MR10 */
+extern void zzTraceOut(); /* MR10 */
+extern int zzTraceOption(); /* MR10 */
+extern int zzTraceGuessOption(); /* MR10 */
+extern void zzTraceReset(); /* MR10 */
+extern void zzTraceGuessFail(); /* MR10 */
+#ifdef EXCEPTION_HANDLING
+extern void zzdflthandlers();
+#endif
+#endif
+
+ /* G l o b a l V a r i a b l e s */
+
+/* Define a parser; user should do a "#parser myname" in their grammar file */
+/*extern struct pccts_parser zzparser;*/
+
+extern char *zztokens[];
+#ifdef LL_K
+extern int zztokenLA[];
+extern zzchar_t zztextLA[][ZZLEXBUFSIZE];
+extern int zzlap;
+extern int zzlabase;
+#else
+extern int zztoken;
+#endif
+
+extern char zzStackOvfMsg[];
+extern int zzasp;
+extern Attrib zzaStack[];
+#ifdef ZZINF_LOOK
+extern int *zzinf_tokens;
+extern char **zzinf_text;
+extern char *zzinf_text_buffer;
+extern int *zzinf_line;
+extern int zzinf_labase;
+extern int zzinf_last;
+#endif
+#ifdef DEMAND_LOOK
+extern int zzdirty;
+#endif
+#ifdef ZZCAN_GUESS
+extern int zzguessing;
+extern zzjmp_buf zzguess_start;
+#endif
+
+/* Define global variables that refer to values exported by the scanner.
+ * These declarations duplicate those in dlgdef.h, but are needed
+ * if ANTLR is not to generate a .dlg file (-gx); PS, this is a hack.
+ */
+extern zzchar_t *zzlextext; /* text of most recently matched token */
+extern int zzbufsize; /* how long zzlextext is */
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.c
new file mode 100644
index 00000000..45007e35
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.c
@@ -0,0 +1,345 @@
+/* Abstract syntax tree manipulation functions
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include "pcctscfg.h"
+
+#ifdef PCCTS_USE_STDARG
+#include "pccts_stdarg.h"
+#else
+#include <varargs.h>
+#endif
+
+/* ensure that tree manipulation variables are current after a rule
+ * reference
+ */
+
+void
+#ifdef __USE_PROTOS
+zzlink(AST **_root, AST **_sibling, AST **_tail)
+#else
+zzlink(_root, _sibling, _tail)
+AST **_root, **_sibling, **_tail;
+#endif
+{
+ if ( *_sibling == NULL ) return;
+ if ( *_root == NULL ) *_root = *_sibling;
+ else if ( *_root != *_sibling ) (*_root)->down = *_sibling;
+ if ( *_tail==NULL ) *_tail = *_sibling;
+ while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right;
+}
+
+AST *
+#ifdef __USE_PROTOS
+zzastnew(void)
+#else
+zzastnew()
+#endif
+{
+ AST *p = (AST *) calloc(1, sizeof(AST));
+ if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__);
+ return p;
+}
+
+/* add a child node to the current sibling list */
+void
+#ifdef __USE_PROTOS
+zzsubchild(AST **_root, AST **_sibling, AST **_tail)
+#else
+zzsubchild(_root, _sibling, _tail)
+AST **_root, **_sibling, **_tail;
+#endif
+{
+ AST *n;
+ zzNON_GUESS_MODE {
+ n = zzastnew();
+#ifdef DEMAND_LOOK
+ zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
+#else
+ zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
+#endif
+ zzastPush( n );
+ if ( *_tail != NULL ) (*_tail)->right = n;
+ else {
+ *_sibling = n;
+ if ( *_root != NULL ) (*_root)->down = *_sibling;
+ }
+ *_tail = n;
+ if ( *_root == NULL ) *_root = *_sibling;
+ }
+}
+
+/* make a new AST node. Make the newly-created
+ * node the root for the current sibling list. If a root node already
+ * exists, make the newly-created node the root of the current root.
+ */
+void
+#ifdef __USE_PROTOS
+zzsubroot(AST **_root, AST **_sibling, AST **_tail)
+#else
+zzsubroot(_root, _sibling, _tail)
+AST **_root, **_sibling, **_tail;
+#endif
+{
+ AST *n;
+ zzNON_GUESS_MODE {
+ n = zzastnew();
+#ifdef DEMAND_LOOK
+ zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
+#else
+ zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
+#endif
+ zzastPush( n );
+ if ( *_root != NULL )
+ if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root;
+ *_root = n;
+ (*_root)->down = *_sibling;
+ }
+}
+
+/* Apply function to root then each sibling
+ * example: print tree in child-sibling LISP-format (AST has token field)
+ *
+ * void show(tree)
+ * AST *tree;
+ * {
+ * if ( tree == NULL ) return;
+ * printf(" %s", zztokens[tree->token]);
+ * }
+ *
+ * void before() { printf(" ("); }
+ * void after() { printf(" )"); }
+ *
+ * LISPdump() { zzpre_ast(tree, show, before, after); }
+ *
+ */
+void
+#ifdef __USE_PROTOS
+zzpre_ast(
+ AST *tree,
+ void (*func)(AST *), /* apply this to each tree node */
+ void (*before)(AST *), /* apply this to root of subtree before preordering it */
+ void (*after)(AST *)) /* apply this to root of subtree after preordering it */
+#else
+zzpre_ast(tree, func, before, after)
+AST *tree;
+void (*func)(), /* apply this to each tree node */
+ (*before)(), /* apply this to root of subtree before preordering it */
+ (*after)(); /* apply this to root of subtree after preordering it */
+#endif
+{
+ while ( tree!= NULL )
+ {
+ if ( tree->down != NULL ) (*before)(tree);
+ (*func)(tree);
+ zzpre_ast(tree->down, func, before, after);
+ if ( tree->down != NULL ) (*after)(tree);
+ tree = tree->right;
+ }
+}
+
+/* free all AST nodes in tree; apply func to each before freeing */
+
+#if 0
+////void
+////#ifdef __USE_PROTOS
+////zzfree_ast(AST *tree)
+////#else
+////zzfree_ast(tree)
+////AST *tree;
+////#endif
+////{
+//// if ( tree == NULL ) return;
+//// zzfree_ast( tree->down );
+//// zzfree_ast( tree->right );
+//// zztfree( tree );
+////}
+#endif
+
+/*
+ MR19 Optimize freeing of the following structure to limit recursion
+ SAKAI Kiyotaka (ksakai@isr.co.jp)
+*/
+
+/*
+ NULL o
+ / \
+ NULL o
+ / \
+ NULL NULL
+*/
+
+/*
+ MR21 Another refinement to replace recursion with iteration
+ NAKAJIMA Mutsuki (muc@isr.co.jp).
+*/
+
+void
+#ifdef __USE_PROTOS
+zzfree_ast(AST *tree)
+#else
+zzfree_ast(tree)
+AST *tree;
+#endif
+{
+
+ AST *otree;
+
+ if (tree == NULL) return;
+
+ while (tree->down == NULL || tree->right == NULL) {
+
+ if (tree->down == NULL && tree->right == NULL) {
+ zztfree(tree);
+ return;
+ }
+
+ otree = tree;
+ if (tree->down == NULL) {
+ tree = tree->right;
+ } else {
+ tree = tree->down;
+ }
+ zztfree( otree );
+ }
+
+ while (tree != NULL) {
+ zzfree_ast(tree->down);
+ otree = tree;
+ tree = otree->right;
+ zztfree(otree);
+ }
+}
+
+/* build a tree (root child1 child2 ... NULL)
+ * If root is NULL, simply make the children siblings and return ptr
+ * to 1st sibling (child1). If root is not single node, return NULL.
+ *
+ * Siblings that are actually siblins lists themselves are handled
+ * correctly. For example #( NULL, #( NULL, A, B, C), D) results
+ * in the tree ( NULL A B C D ).
+ *
+ * Requires at least two parameters with the last one being NULL. If
+ * both are NULL, return NULL.
+ */
+#ifdef PCCTS_USE_STDARG
+AST *zztmake(AST *rt, ...)
+#else
+AST *zztmake(va_alist)
+va_dcl
+#endif
+{
+ va_list ap;
+ register AST *child, *sibling=NULL, *tail=NULL /* MR20 */, *w;
+ AST *root;
+
+#ifdef PCCTS_USE_STDARG
+ va_start(ap, rt);
+ root = rt;
+#else
+ va_start(ap);
+ root = va_arg(ap, AST *);
+#endif
+
+ if ( root != NULL )
+ if ( root->down != NULL ) return NULL;
+ child = va_arg(ap, AST *);
+ while ( child != NULL )
+ {
+ for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
+ if ( sibling == NULL ) {sibling = child; tail = w;}
+ else {tail->right = child; tail = w;}
+ child = va_arg(ap, AST *);
+ }
+ if ( root==NULL ) root = sibling;
+ else root->down = sibling;
+ va_end(ap);
+ return root;
+}
+
+/* tree duplicate */
+AST *
+#ifdef __USE_PROTOS
+zzdup_ast(AST *t)
+#else
+zzdup_ast(t)
+AST *t;
+#endif
+{
+ AST *u;
+
+ if ( t == NULL ) return NULL;
+ u = zzastnew();
+ *u = *t;
+#ifdef zzAST_DOUBLE
+ u->up = NULL; /* set by calling invocation */
+ u->left = NULL;
+#endif
+ u->right = zzdup_ast(t->right);
+ u->down = zzdup_ast(t->down);
+#ifdef zzAST_DOUBLE
+ if ( u->right!=NULL ) u->right->left = u;
+ if ( u->down!=NULL ) u->down->up = u;
+#endif
+ return u;
+}
+
+void
+#ifdef __USE_PROTOS
+zztfree(AST *t)
+#else
+zztfree(t)
+AST *t;
+#endif
+{
+#ifdef zzd_ast
+ zzd_ast( t );
+#endif
+ free( t );
+}
+
+#ifdef zzAST_DOUBLE
+/*
+ * Set the 'up', and 'left' pointers of all nodes in 't'.
+ * Initial call is double_link(your_tree, NULL, NULL).
+ */
+void
+#ifdef __USE_PROTOS
+zzdouble_link(AST *t, AST *left, AST *up)
+#else
+zzdouble_link(t, left, up)
+AST *t, *left, *up;
+#endif
+{
+ if ( t==NULL ) return;
+ t->left = left;
+ t->up = up;
+ zzdouble_link(t->down, NULL, t);
+ zzdouble_link(t->right, t, up);
+}
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.h
new file mode 100644
index 00000000..911f913d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/ast.h
@@ -0,0 +1,121 @@
+/* Abstract syntax tree
+ *
+ * Macros, definitions
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ZZAST_H
+#define ZZAST_H
+
+#define zzastOvfChk \
+ if ( zzast_sp <= 0 ) \
+ { \
+ fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \
+ exit(PCCTS_EXIT_FAILURE); \
+ }
+
+#ifndef USER_DEFINED_AST
+#ifndef AST_FIELDS
+#define AST_FIELDS
+#endif
+
+typedef struct _ast {
+ struct _ast *right, *down;
+#ifdef zzAST_DOUBLE
+ struct _ast *left, *up;
+#endif
+ AST_FIELDS
+} AST;
+
+#else
+
+#ifdef zzAST_DOUBLE
+#define AST_REQUIRED_FIELDS struct _ast *right, *down, *left, *up;
+#else
+#define AST_REQUIRED_FIELDS struct _ast *right, *down;
+#endif
+
+#endif
+
+
+/* N o d e a c c e s s m a c r o s */
+#define zzchild(t) (((t)==NULL)? (AST *) NULL:(t->down)) /* MR19 */
+#define zzsibling(t) (((t)==NULL)? (AST *) NULL:(t->right)) /* MR19 */
+
+
+/* define global variables needed by #i stack */
+#define zzASTgvars \
+ AST *zzastStack[ZZAST_STACKSIZE]; \
+ int zzast_sp = ZZAST_STACKSIZE;
+
+#define zzASTVars AST *_ast = NULL, *_sibling = NULL, *_tail = NULL
+#define zzSTR ( (_tail==NULL)?(&_sibling):(&(_tail->right)) )
+#define zzastCur (zzastStack[zzast_sp])
+#define zzastArg(i) (zzastStack[zztsp-i])
+#define zzastPush(p) zzastOvfChk; zzastStack[--zzast_sp] = p;
+#define zzastDPush --zzast_sp
+#define zzastMARK zztsp=zzast_sp; /* Save state of stack */
+#define zzastREL zzast_sp=zztsp; /* Return state of stack */
+#define zzrm_ast {zzfree_ast(*_root); _tail = _sibling = (*_root)=NULL;}
+
+extern int zzast_sp;
+extern AST *zzastStack[];
+
+/* MR26 */
+
+#ifdef PCCTS_USE_STDARG
+AST *zztmake(AST *, ...);
+#else
+AST *zztmake();
+#endif
+
+#ifdef __USE_PROTOS
+void zzlink(AST **, AST **, AST **);
+void zzsubchild(AST **, AST **, AST **);
+void zzsubroot(AST **, AST **, AST **);
+void zzpre_ast(AST *, void (*)(AST *), void (*)(AST *), void (*)(AST *));
+void zzfree_ast(AST *);
+AST *zzdup_ast(AST *);
+void zztfree(AST *);
+void zzdouble_link(AST *, AST *, AST *);
+AST *zzastnew(void);
+
+#else
+
+void zzlink();
+AST *zzastnew();
+void zzsubchild();
+void zzsubroot();
+void zzpre_ast();
+void zzfree_ast();
+AST *zzdup_ast();
+void zztfree();
+void zzdouble_link();
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charbuf.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charbuf.h
new file mode 100644
index 00000000..e10ba67d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charbuf.h
@@ -0,0 +1,46 @@
+/* ANTLR attribute definition -- constant width text
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ZZCHARBUF_H
+#define ZZCHARBUF_H
+
+#include "pcctscfg.h"
+
+#include "pccts_string.h"
+
+#ifndef D_TextSize
+#define D_TextSize 30
+#endif
+
+typedef struct { char text[D_TextSize]; } Attrib;
+
+#define zzcr_attr(a,tok,t) strncpy((a)->text, t, D_TextSize-1); \
+ (a)->text[D_TextSize-1] = '\0';
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.c
new file mode 100644
index 00000000..15a51766
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.c
@@ -0,0 +1,58 @@
+/*
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#include "pcctscfg.h"
+
+#ifdef __STDC__
+#include "pccts_stdlib.h"
+#else
+#include <malloc.h>
+#endif
+#include "pccts_string.h"
+
+/* 133MR1 include stdio.h for fprintf in charptr.c */
+
+#include "pccts_stdio.h"
+
+/* 133MR1 include charptr.h for Attrib in charptr.c */
+
+#include "charptr.h"
+
+#ifdef __USE_PROTOS
+zzcr_attr(Attrib *a,int token,char *text)
+#else
+zzcr_attr(a,token,text)
+Attrib *a;
+int token;
+char *text;
+#endif
+{
+ *a = (char *) malloc(strlen(text)+1); /* MR6 */
+ if ( *a == NULL ) {fprintf(stderr, "zzcr_attr: out of memory!\n"); exit(-1);}
+ strcpy(*a, text);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.h
new file mode 100644
index 00000000..2cc36d8d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/charptr.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+/*
+ * WARNING!!!!: charptr.h does NOT make copies and the
+ * memory is freed after the attribute scope exits.
+ */
+
+#ifndef ZZCHARPTR_H
+#define ZZCHARPTR_H
+
+typedef char *Attrib;
+#define zzdef0(a) {*(a)=NULL;}
+/* MR8 Jens Tingleff (jensting@imaginet.fr) */
+/* Set memory pointer to null after free() */
+#define zzd_attr(a) {if ( *(a)!=NULL ) {free(*(a)); *(a)=NULL; }; }
+
+#ifdef __STDC__
+extern zzcr_attr(Attrib *,int,char *);
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/config.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/config.h
new file mode 100644
index 00000000..1cc4fbcd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/config.h
@@ -0,0 +1 @@
+#include "pcctscfg.h"
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgauto.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgauto.h
new file mode 100644
index 00000000..2bf640bf
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgauto.h
@@ -0,0 +1,504 @@
+/* dlgauto.h automaton
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Will Cohen and Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ZZDEFAUTO_H
+#define ZZDEFAUTO_H
+
+/* 10-Apr-97 133MR1 Uses __USE_PROTOS show should #include pcctscfg.h */
+
+#include "pcctscfg.h"
+
+zzchar_t *zzlextext; /* text of most recently matched token */
+zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */
+zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */
+int zzbufsize = 0; /* number of characters in zzlextext */ /* MR7 */
+int zzbegcol = 0; /* column that first character of token is in*/
+int zzendcol = 0; /* column that last character of token is in */
+int zzline = 1; /* line current token is on */
+int zzreal_line=1; /* line of 1st portion of token that is not skipped */
+int zzchar; /* character to determine next state */
+int zzbufovf; /* indicates that buffer too small for text */
+int zzcharfull = 0;
+static zzchar_t *zznextpos;/* points to next available position in zzlextext*/
+static int zzclass;
+
+#ifdef __USE_PROTOS
+void zzerrstd(const char *);
+void (*zzerr)(const char *)=zzerrstd;/* pointer to error reporting function */
+extern int zzerr_in(void);
+static int (*zzfunc_in)(void) = zzerr_in; /* MR20 */
+#else
+void zzerrstd();
+void (*zzerr)()=zzerrstd; /* pointer to error reporting function */
+extern int zzerr_in();
+static int (*zzfunc_in)() = zzerr_in; /* MR20 */
+#endif
+
+static FILE *zzstream_in=0;
+static zzchar_t *zzstr_in=0;
+
+#ifdef USER_ZZMODE_STACK
+int zzauto = 0;
+#else
+static int zzauto = 0;
+#endif
+static int zzadd_erase;
+static char zzebuf[70];
+
+#ifdef ZZCOL
+#define ZZINC (++zzendcol)
+#else
+#define ZZINC
+#endif
+
+
+#define ZZGETC_STREAM {zzchar = getc(zzstream_in); zzclass = ZZSHIFT(zzchar);}
+#define ZZGETC_FUNC {zzchar = (*zzfunc_in)(); zzclass = ZZSHIFT(zzchar);}
+#define ZZGETC_STR { \
+ if (*zzstr_in){ \
+ zzchar = *zzstr_in; \
+ ++zzstr_in; \
+ }else{ \
+ zzchar = EOF; \
+ } \
+ zzclass = ZZSHIFT(zzchar); \
+}
+
+#define ZZNEWSTATE (newstate = dfa[state][zzclass])
+
+#ifndef ZZCOPY
+#define ZZCOPY \
+ /* Truncate matching buffer to size (not an error) */ \
+ if (zznextpos < lastpos){ \
+ *(zznextpos++) = zzchar; \
+ }else{ \
+ zzbufovf = 1; \
+ }
+#endif
+
+void
+#ifdef __USE_PROTOS
+zzrdstream( FILE *f )
+#else
+zzrdstream( f )
+FILE *f;
+#endif
+{
+ /* make sure that it is really set to something, otherwise just
+ leave it be.
+ */
+ if (f){
+ /* make sure that there is always someplace to get input
+ before closing zzstream_in
+ */
+#if 0
+ if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );
+#endif
+ zzline = 1;
+ zzstream_in = f;
+ zzfunc_in = NULL;
+ zzstr_in = 0;
+ zzcharfull = 0;
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+zzrdfunc( int (*f)(void) )
+#else
+zzrdfunc( f )
+int (*f)();
+#endif
+{
+ /* make sure that it is really set to something, otherwise just
+ leave it be.
+ */
+ if (f){
+ /* make sure that there is always someplace to get input
+ before closing zzstream_in
+ */
+#if 0
+ if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );
+#endif
+ zzline = 1;
+ zzstream_in = NULL;
+ zzfunc_in = f;
+ zzstr_in = 0;
+ zzcharfull = 0;
+ }
+}
+
+
+void
+#ifdef __USE_PROTOS
+zzrdstr( zzchar_t *s )
+#else
+zzrdstr( s )
+zzchar_t *s;
+#endif
+{
+ /* make sure that it is really set to something, otherwise just
+ leave it be.
+ */
+ if (s){
+ /* make sure that there is always someplace to get input
+ before closing zzstream_in
+ */
+#if 0
+ if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in );
+#endif
+ zzline = 1;
+ zzstream_in = NULL;
+ zzfunc_in = 0;
+ zzstr_in = s;
+ zzcharfull = 0;
+ }
+}
+
+
+#ifdef __USE_PROTOS
+void zzclose_stream(void)
+#else
+void zzclose_stream()
+#endif
+{
+#if 0
+ fclose( zzstream_in );
+ zzstream_in = NULL;
+ zzfunc_in = NULL;
+#endif
+}
+
+/* saves dlg state, but not what feeds dlg (such as file position) */
+void
+#ifdef __USE_PROTOS
+zzsave_dlg_state(struct zzdlg_state *state)
+#else
+zzsave_dlg_state(state)
+struct zzdlg_state *state;
+#endif
+{
+ state->stream = zzstream_in;
+ state->func_ptr = zzfunc_in;
+ state->str = zzstr_in;
+ state->auto_num = zzauto;
+ state->add_erase = zzadd_erase;
+ state->lookc = zzchar;
+ state->char_full = zzcharfull;
+ state->begcol = zzbegcol;
+ state->endcol = zzendcol;
+ state->line = zzline;
+ state->lextext = zzlextext;
+ state->begexpr = zzbegexpr;
+ state->endexpr = zzendexpr;
+ state->bufsize = zzbufsize;
+ state->bufovf = zzbufovf;
+ state->nextpos = zznextpos;
+ state->class_num = zzclass;
+}
+
+void
+#ifdef __USE_PROTOS
+zzrestore_dlg_state(struct zzdlg_state *state)
+#else
+zzrestore_dlg_state(state)
+struct zzdlg_state *state;
+#endif
+{
+ zzstream_in = state->stream;
+ zzfunc_in = state->func_ptr;
+ zzstr_in = state->str;
+ zzauto = state->auto_num;
+ zzadd_erase = state->add_erase;
+ zzchar = state->lookc;
+ zzcharfull = state->char_full;
+ zzbegcol = state->begcol;
+ zzendcol = state->endcol;
+ zzline = state->line;
+ zzlextext = state->lextext;
+ zzbegexpr = state->begexpr;
+ zzendexpr = state->endexpr;
+ zzbufsize = state->bufsize;
+ zzbufovf = state->bufovf;
+ zznextpos = state->nextpos;
+ zzclass = state->class_num;
+}
+
+void
+#ifdef __USE_PROTOS
+zzmode( int m )
+#else
+zzmode( m )
+int m;
+#endif
+{
+ /* points to base of dfa table */
+ if (m<MAX_MODE){
+ zzauto = m;
+ /* have to redo class since using different compression */
+ zzclass = ZZSHIFT(zzchar);
+ }else{
+ sprintf(zzebuf,"Invalid automaton mode = %d ",m);
+ zzerr(zzebuf);
+ }
+}
+
+/* erase what is currently in the buffer, and get a new reg. expr */
+
+#ifdef __USE_PROTOS
+void zzskip(void)
+#else
+void zzskip()
+#endif
+{
+ zzadd_erase = 1;
+}
+
+/* don't erase what is in the zzlextext buffer, add on to it */
+#ifdef __USE_PROTOS
+void zzmore()
+#else
+void zzmore()
+#endif
+{
+ zzadd_erase = 2;
+}
+
+/* substitute c for the reg. expr last matched and is in the buffer */
+#ifdef __USE_PROTOS
+void
+zzreplchar(zzchar_t c)
+#else
+void
+zzreplchar(c)
+zzchar_t c;
+#endif
+{
+ /* can't allow overwriting null at end of string */
+ if (zzbegexpr < &zzlextext[zzbufsize-1]){
+ *zzbegexpr = c;
+ *(zzbegexpr+1) = '\0';
+ }
+ zzendexpr = zzbegexpr;
+ if (c != '\0') {
+ zznextpos = zzbegexpr + 1;
+ }
+ else {
+ zznextpos = zzbegexpr; /* MR30 Zero terminates string. */
+ }
+}
+
+/* replace the string s for the reg. expr last matched and in the buffer */
+void
+#ifdef __USE_PROTOS
+zzreplstr(register zzchar_t *s)
+#else
+zzreplstr(s)
+register zzchar_t *s;
+#endif
+{
+ register zzchar_t *l= &zzlextext[zzbufsize -1];
+
+ zznextpos = zzbegexpr;
+ if (s){
+ while ((zznextpos <= l) && (*(zznextpos++) = *(s++))!=0){
+ /* empty */
+ }
+ /* correct for NULL at end of string */
+ zznextpos--;
+ }
+ if ((zznextpos <= l) && (*(--s) == 0)){
+ zzbufovf = 0;
+ }else{
+ zzbufovf = 1;
+ }
+ *(zznextpos) = '\0';
+ zzendexpr = zznextpos - 1;
+}
+
+#ifdef __USE_PROTOS
+void zzgettok(void)
+#else
+void zzgettok()
+#endif
+{
+ register int state, newstate;
+ /* last space reserved for the null char */
+ zzchar_t *lastpos; /* MR27 Remove register since address operator used. */
+
+skip:
+ zzreal_line = zzline;
+ zzbufovf = 0;
+ lastpos = &zzlextext[zzbufsize-1];
+ zznextpos = zzlextext;
+ zzbegcol = zzendcol+1;
+more:
+ zzbegexpr = zznextpos;
+#ifdef ZZINTERACTIVE
+ /* interactive version of automaton */
+ /* if there is something in zzchar, process it */
+ state = newstate = dfa_base[zzauto];
+ if (zzcharfull){
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ if (zzstr_in)
+ while (zzalternatives[newstate]){
+ state = newstate;
+ ZZGETC_STR;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ else if (zzstream_in)
+ while (zzalternatives[newstate]){
+ state = newstate;
+ ZZGETC_STREAM;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ else if (zzfunc_in)
+ while (zzalternatives[newstate]){
+ state = newstate;
+ ZZGETC_FUNC;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ /* figure out if last character really part of token */
+ if ((state != dfa_base[zzauto]) && (newstate == DfaStates)){
+ zzcharfull = 1;
+ --zznextpos;
+ }else{
+ zzcharfull = 0;
+ state = newstate;
+ }
+ *(zznextpos) = '\0';
+ /* Able to transition out of start state to some non err state?*/
+ if ( state == dfa_base[zzauto] ){
+ /* make sure doesn't get stuck */
+ zzadvance();
+ }
+#else
+ /* non-interactive version of automaton */
+ if (!zzcharfull)
+ zzadvance();
+ else
+ ZZINC;
+ state = dfa_base[zzauto];
+ if (zzstr_in)
+ while (ZZNEWSTATE != DfaStates){
+ state = newstate;
+ ZZCOPY;
+ ZZGETC_STR;
+ ZZINC;
+ }
+ else if (zzstream_in)
+ while (ZZNEWSTATE != DfaStates){
+ state = newstate;
+ ZZCOPY;
+ ZZGETC_STREAM;
+ ZZINC;
+ }
+ else if (zzfunc_in)
+ while (ZZNEWSTATE != DfaStates){
+ state = newstate;
+ ZZCOPY;
+ ZZGETC_FUNC;
+ ZZINC;
+ }
+ zzcharfull = 1;
+ if ( state == dfa_base[zzauto] ){
+ if (zznextpos < lastpos){
+ *(zznextpos++) = zzchar;
+ }else{
+ zzbufovf = 1;
+ }
+ *zznextpos = '\0';
+ /* make sure doesn't get stuck */
+ zzadvance();
+ }else{
+ *zznextpos = '\0';
+ }
+#endif
+#ifdef ZZCOL
+ zzendcol -= zzcharfull;
+#endif
+ zzendexpr = zznextpos -1;
+ zzadd_erase = 0;
+ (*actions[accepts[state]])();
+ switch (zzadd_erase) {
+ case 1: goto skip;
+ case 2: goto more;
+ }
+}
+
+#ifdef __USE_PROTOS
+void zzadvance(void)
+#else
+void zzadvance()
+#endif
+{
+ if (zzstream_in) { ZZGETC_STREAM; zzcharfull = 1; ZZINC;}
+ if (zzfunc_in) { ZZGETC_FUNC; zzcharfull = 1; ZZINC;}
+ if (zzstr_in) { ZZGETC_STR; zzcharfull = 1; ZZINC;}
+ if (!(zzstream_in || zzfunc_in || zzstr_in)){
+ zzerr_in();
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+zzerrstd(const char *s)
+#else
+zzerrstd(s)
+char *s;
+#endif
+{
+ zzLexErrCount++; /* MR11 */
+ fprintf(stderr,
+ "%s near line %d (text was '%s')\n",
+ ((s == NULL) ? "Lexical error" : s),
+ zzline,zzlextext);
+}
+
+#ifdef __USE_PROTOS
+int zzerr_in(void)
+#else
+int zzerr_in()
+#endif
+{
+ fprintf(stderr,"No input stream, function, or string\n");
+ /* return eof to get out gracefully */
+ return EOF;
+}
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgdef.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgdef.h
new file mode 100644
index 00000000..759bc0c7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/dlgdef.h
@@ -0,0 +1,128 @@
+/* dlgdef.h
+ * Things in scanner produced by dlg that should be visible to the outside
+ * world
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ZZDLGDEF_H
+#define ZZDLGDEF_H
+
+#include "pcctscfg.h"
+
+#ifndef zzchar_t
+#ifdef ZZWCHAR_T
+#define zzchar_t wchar_t
+#else
+#define zzchar_t char
+#endif
+#endif
+
+struct zzdlg_state {
+ FILE *stream;
+#ifdef __USE_PROTOS
+ int (*func_ptr)(void);
+#else
+ int (*func_ptr)();
+#endif
+ zzchar_t *str;
+ int auto_num;
+ int add_erase;
+ int lookc;
+ int char_full;
+ int begcol, endcol;
+ int line;
+ zzchar_t *lextext, *begexpr, *endexpr;
+ int bufsize;
+ int bufovf;
+ zzchar_t *nextpos;
+ int class_num;
+};
+
+extern zzchar_t *zzlextext; /* text of most recently matched token */
+extern zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */
+extern zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */
+extern int zzbufsize; /* how long zzlextext is */
+extern int zzbegcol; /* column that first character of token is in*/
+extern int zzendcol; /* column that last character of token is in */
+extern int zzline; /* line current token is on */
+extern int zzreal_line; /* line of 1st portion of token that is not skipped */
+extern int zzchar; /* character to determine next state */
+extern int zzbufovf; /* indicates that buffer too small for text */
+#ifdef __USE_PROTOS
+extern void (*zzerr)(const char *);/* pointer to error reporting function */
+#else
+extern void (*zzerr)();
+#endif
+
+#ifdef USER_ZZMODE_STACK
+extern int zzauto;
+#endif
+
+#ifdef __USE_PROTOS
+extern void zzadvance(void);
+extern void zzskip(void); /* erase zzlextext, look for antoher token */
+extern void zzmore(void); /* keep zzlextext, look for another token */
+extern void zzmode(int k); /* switch to automaton 'k' */
+extern void zzrdstream(FILE *);/* what stream to read from */
+extern void zzclose_stream(void);/* close the current input stream */
+extern void zzrdfunc(int (*)(void));/* what function to get char from */
+extern void zzrdstr( zzchar_t * );
+extern void zzgettok(void); /* get next token */
+extern void zzreplchar(zzchar_t c);/* replace last recognized reg. expr. with
+ a character */
+extern void zzreplstr(zzchar_t *s);/* replace last recognized reg. expr. with
+ a string */
+extern void zzsave_dlg_state(struct zzdlg_state *);
+extern void zzrestore_dlg_state(struct zzdlg_state *);
+extern int zzerr_in(void);
+extern void zzerrstd(const char *);
+extern void zzerraction(void);
+
+#else
+
+extern void zzadvance();
+extern void zzskip(); /* erase zzlextext, look for antoher token */
+extern void zzmore(); /* keep zzlextext, look for another token */
+extern void zzmode(/*k*/); /* switch to automaton 'k' */
+extern void zzrdstream(); /* what stream to read from */
+extern void zzclose_stream();/* close the current input stream */
+extern void zzrdfunc(); /* what function to get char from */
+extern void zzrdstr();
+extern void zzgettok(); /* get next token */
+extern void zzreplchar(); /* replace last recognized reg. expr. with
+ a character */
+extern void zzreplstr(); /* replace last recognized reg. expr. with
+ a string */
+extern void zzsave_dlg_state();
+extern void zzrestore_dlg_state();
+extern int zzerr_in();
+extern void zzerrstd();
+extern void zzerraction();
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/err.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/err.h
new file mode 100644
index 00000000..b4250643
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/err.h
@@ -0,0 +1,1173 @@
+/*
+ * err.h
+ *
+ * Standard error handling mechanism
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * Has grown to hold all kinds of stuff (err.h is increasingly misnamed)
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ERR_H
+#define ERR_H
+
+#include "pcctscfg.h"
+#include <stdlib.h>
+#include <assert.h>
+
+/* */
+/* 7-Apr-97 133MR1 */
+/* Proper choice of STDC and cplusplus pre-processor symbols (?) */
+/* */
+#include "pccts_string.h"
+
+#ifdef PCCTS_USE_STDARG
+#include "pccts_stdarg.h"
+#else
+#include <varargs.h>
+#endif
+
+#ifdef DUM
+/* Define usable bits per unsigned int word (used for set stuff) */
+#ifdef PC
+#define BSETWORDSIZE 16
+#define BSETLOGWORDSIZE 4
+#else
+#define BSETWORDSIZE 32
+#define BSETLOGWORDSIZE 5
+#endif
+#endif
+
+#define BSETWORDSIZE 8
+#define BSETLOGWORDSIZE 3 /* SetWordType is 8bits */
+
+#define BSETMODWORD(x) ((x) & (BSETWORDSIZE-1)) /* x % BSETWORDSIZE */
+#define BSETDIVWORD(x) ((x) >> BSETLOGWORDSIZE) /* x / BSETWORDSIZE */
+
+/* This is not put into the global pccts_parser structure because it is
+ * hidden and does not need to be saved during a "save state" operation
+ */
+/* maximum of 32 bits/unsigned int and must be 8 bits/byte */
+static SetWordType bitmask[] = {
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080
+};
+
+#ifdef zzTRACE_RULES
+int zzTraceOptionValueDefault=1;
+int zzTraceOptionValue=1;
+int zzTraceGuessOptionValue=1;
+char *zzTraceCurrentRuleName=NULL;
+int zzTraceDepth=0;
+#endif
+
+int zzGuessSeq=0; /* MR10 */
+int zzSyntaxErrCount=0; /* MR11 */
+int zzLexErrCount=0; /* MR11 */
+
+void
+#ifdef __USE_PROTOS
+zzresynch(SetWordType *wd,SetWordType mask)
+#else
+zzresynch(wd,mask)
+SetWordType *wd, mask;
+#endif
+{
+ static int consumed = 1;
+
+ /* if you enter here without having consumed a token from last resynch
+ * force a token consumption.
+ */
+ if ( !consumed ) {zzCONSUME; consumed=1; return;} /* MR10 */
+
+ /* if current token is in resynch set, we've got what we wanted */
+ if ( wd[LA(1)]&mask || LA(1) == zzEOF_TOKEN ) {consumed=0; return;}
+
+ /* scan until we find something in the resynch set */
+ while ( !(wd[LA(1)]&mask) && LA(1) != zzEOF_TOKEN ) {zzCONSUME;}
+ consumed=1;
+}
+
+/* */
+/* 7-Apr-97 133MR1 for C++ and MR7 for C */
+/* Change suggested by Eli Sternheim (eli@interhdl.com) */
+/* */
+
+void
+#ifdef __USE_PROTOS
+zzconsumeUntil(SetWordType *st)
+#else
+zzconsumeUntil(st)
+SetWordType *st;
+#endif
+{
+ int tmp; /* MR7 */
+ while ( !zzset_el( (tmp=LA(1)), st) && tmp!=1 /* Eof */) { /* MR7 */
+ zzCONSUME; } /* MR7 */
+}
+
+/* */
+/* 7-Apr-97 133MR1 for C++ and MR7 for C */
+/* Change suggested by Eli Sternheim (eli@interhdl.com) */
+/* */
+
+void
+#ifdef __USE_PROTOS
+zzconsumeUntilToken(int t)
+#else
+zzconsumeUntilToken(t)
+int t;
+#endif
+{
+ int tmp; /* MR7 */
+ while ( (tmp=LA(1)) !=t && tmp!=1 /* Eof */) { zzCONSUME; } /* MR7 */
+}
+
+/* input looks like:
+ * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText)
+ * where the zzMiss stuff is set here to the token that did not match
+ * (and which set wasn't it a member of).
+ */
+
+#ifdef PCCTS_USE_STDARG
+void zzFAIL(int k, ...)
+#else
+void zzFAIL(va_alist)
+va_dcl
+#endif
+{
+#ifdef LL_K
+ static char text[LL_K*ZZLEXBUFSIZE+1];
+ SetWordType *f[LL_K];
+#else
+ static char text[ZZLEXBUFSIZE+1];
+ SetWordType *f[1];
+#endif
+ SetWordType **miss_set;
+ char **miss_text;
+ int *bad_tok;
+ char **bad_text;
+ int *err_k;
+ int i;
+ va_list ap;
+#ifndef PCCTS_USE_STDARG /* MR20 */
+ int k;
+#endif
+#ifdef PCCTS_USE_STDARG /* MR20 */
+ va_start(ap, k);
+#else
+ va_start(ap);
+ k = va_arg(ap, int); /* how many lookahead sets? */
+#endif
+ assert(k <= sizeof(f)/sizeof(f[0])); /* MR20 G. Hobbelt */
+ text[0] = '\0';
+#ifdef VBOX
+ memset(f, 0, sizeof(f));
+#endif
+ for (i=1; i<=k; i++) /* collect all lookahead sets */
+ {
+ f[i-1] = va_arg(ap, SetWordType *);
+ }
+ for (i=1; i<=k; i++) /* look for offending token */
+ {
+ if ( i>1 ) strcat(text, " ");
+ strcat(text, LATEXT(i));
+ if ( !zzset_el((unsigned)LA(i), f[i-1]) ) break;
+ }
+ miss_set = va_arg(ap, SetWordType **);
+ miss_text = va_arg(ap, char **);
+ bad_tok = va_arg(ap, int *);
+ bad_text = va_arg(ap, char **);
+ err_k = va_arg(ap, int *);
+ if ( i>k )
+ {
+ /* bad; lookahead is permutation that cannot be matched,
+ * but, the ith token of lookahead is valid at the ith position
+ * (The old LL sub 1 (k) versus LL(k) parsing technique)
+ */
+ *miss_set = NULL;
+ *miss_text = zzlextext;
+ *bad_tok = LA(1);
+ *bad_text = LATEXT(1);
+ *err_k = k;
+ return;
+ }
+/* fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/
+ *miss_set = f[i-1];
+ *miss_text = text;
+ *bad_tok = LA(i);
+ *bad_text = LATEXT(i);
+ if ( i==1 ) *err_k = 1;
+ else *err_k = k;
+}
+
+#ifdef __USE_PROTOS
+void zzTraceGuessDone(zzantlr_state *state)
+#else
+void zzTraceGuessDone(state)
+ zzantlr_state *state;
+#endif
+{
+#ifdef zzTRACE_RULES
+#ifdef ZZCAN_GUESS
+
+ int doIt=0;
+
+ if (zzTraceCurrentRuleName == NULL) return;
+
+ if (zzTraceOptionValue <= 0) {
+ doIt=0;
+ } else if (zzTraceGuessOptionValue <= 0) {
+ doIt=0;
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ fprintf(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d",
+ state->traceCurrentRuleName,
+ LATEXT(1),
+ state->traceDepth);
+ if (state->guessing != 0) {
+ fprintf(stderr," (guess mode continues - an enclosing guess is still active)");
+ } else {
+ fprintf(stderr," (guess mode ends)");
+ };
+ fprintf(stderr,"\n");
+ };
+#endif
+#endif
+}
+
+void
+#ifdef __USE_PROTOS
+zzsave_antlr_state(zzantlr_state *buf)
+#else
+zzsave_antlr_state(buf)
+zzantlr_state *buf;
+#endif
+{
+#ifdef LL_K
+ int i;
+#endif
+
+#ifdef ZZCAN_GUESS
+ buf->guess_start = zzguess_start;
+ buf->guessing = zzguessing;
+#endif
+ buf->asp = zzasp;
+#ifdef GENAST
+ buf->ast_sp = zzast_sp;
+#endif
+#ifdef ZZINF_LOOK
+ buf->inf_labase = zzinf_labase;
+ buf->inf_last = zzinf_last;
+
+/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */
+/* MR6 Additional state needs to be saved/restored */
+
+ buf->inf_tokens = zzinf_tokens; /* MR6 */
+ buf->inf_text = zzinf_text; /* MR6 */
+ buf->inf_text_buffer = zzinf_text_buffer; /* MR6 */
+ buf->inf_line = zzinf_line; /* MR6 */
+
+#endif
+#ifdef DEMAND_LOOK
+ buf->dirty = zzdirty;
+#endif
+#ifdef LL_K
+ for (i=0; i<LL_K; i++) buf->tokenLA[i] = zztokenLA[i];
+ for (i=0; i<LL_K; i++) strcpy(buf->textLA[i], zztextLA[i]);
+ buf->lap = zzlap;
+ buf->labase = zzlabase;
+#else
+ buf->token = zztoken;
+ strcpy(buf->text, zzlextext);
+#endif
+#ifdef zzTRACE_RULES
+
+ /* MR10 */
+
+ buf->traceOptionValue=zzTraceOptionValue;
+ buf->traceGuessOptionValue=zzTraceGuessOptionValue;
+ buf->traceCurrentRuleName=zzTraceCurrentRuleName;
+ buf->traceDepth=zzTraceDepth;
+#endif
+}
+
+void
+#ifdef __USE_PROTOS
+zzrestore_antlr_state(zzantlr_state *buf)
+#else
+zzrestore_antlr_state(buf)
+zzantlr_state *buf;
+#endif
+{
+
+#ifdef zzTRACE_RULES
+ int prevTraceOptionValue;
+#endif
+
+#ifdef LL_K
+ int i;
+#endif
+
+#ifdef ZZCAN_GUESS
+ zzguess_start = buf->guess_start;
+ zzguessing = buf->guessing;
+#endif
+ zzasp = buf->asp;
+#ifdef GENAST
+ zzast_sp = buf->ast_sp;
+#endif
+#ifdef ZZINF_LOOK
+ zzinf_labase = buf->inf_labase;
+ zzinf_last = buf->inf_last;
+
+/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */
+/* MR6 Additional state needs to be saved/restored */
+
+ zzinf_tokens = buf->inf_tokens; /* MR6 */
+ zzinf_text = buf->inf_text; /* MR6 */
+ zzinf_text_buffer = buf->inf_text_buffer; /* MR6 */
+ zzinf_line = buf->inf_line; /* MR6 */
+#endif
+#ifdef DEMAND_LOOK
+ zzdirty = buf->dirty;
+#endif
+#ifdef LL_K
+ for (i=0; i<LL_K; i++) zztokenLA[i] = buf->tokenLA[i];
+ for (i=0; i<LL_K; i++) strcpy(zztextLA[i], buf->textLA[i]);
+ zzlap = buf->lap;
+ zzlabase = buf->labase;
+#else
+ zztoken = buf->token;
+ strcpy(zzlextext, buf->text);
+#endif
+#ifdef zzTRACE_RULES
+
+ prevTraceOptionValue=zzTraceOptionValue;
+ zzTraceOptionValue=buf->traceOptionValue;
+ if ( (prevTraceOptionValue > 0) !=
+ (zzTraceOptionValue > 0)) {
+ if (zzTraceOptionValue > 0) {
+ fprintf(stderr,"trace enable restored in rule %s depth %d\n",
+ zzTraceCurrentRuleName,zzTraceDepth);
+ };
+ if (zzTraceOptionValue <= 0) {
+ fprintf(stderr,"trace disable restored in rule %s depth %d\n",
+ zzTraceCurrentRuleName,zzTraceDepth);
+ };
+ };
+
+ zzTraceOptionValue=buf->traceOptionValue; /* MR10 */
+ zzTraceGuessOptionValue=buf->traceGuessOptionValue; /* MR10 */
+ zzTraceCurrentRuleName=buf->traceCurrentRuleName; /* MR10 */
+ zzTraceDepth=buf->traceDepth; /* MR10 */
+ zzTraceGuessDone(buf); /* MR10 */
+#endif
+}
+
+void
+#ifdef __USE_PROTOS
+zzedecode(SetWordType *a)
+#else
+zzedecode(a)
+SetWordType *a;
+#endif
+{
+ register SetWordType *p = a;
+ register SetWordType *endp = &(p[zzSET_SIZE]);
+ register unsigned e = 0;
+
+ if ( zzset_deg(a)>1 ) fprintf(stderr, " {");
+ do {
+ register SetWordType t = *p;
+ register SetWordType *b = &(bitmask[0]);
+ do {
+ if ( t & *b ) fprintf(stderr, " %s", zztokens[e]);
+ e++;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ } while (++p < endp);
+ if ( zzset_deg(a)>1 ) fprintf(stderr, " }");
+}
+
+#ifndef USER_ZZSYN
+/* standard error reporting function */
+void
+#ifdef __USE_PROTOS
+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)
+#else
+zzsyn(text, tok, egroup, eset, etok, k, bad_text)
+char *text, *egroup, *bad_text;
+int tok;
+int etok;
+int k;
+SetWordType *eset;
+#endif
+{
+
+ zzSyntaxErrCount++; /* MR11 */
+ fprintf(stderr, "line %d: syntax error at \"%s\"", zzline, (tok==zzEOF_TOKEN)?"EOF":bad_text);
+ if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
+ if ( k==1 ) fprintf(stderr, " missing");
+ else
+ {
+ fprintf(stderr, "; \"%s\" not", bad_text);
+ if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
+ }
+ if ( zzset_deg(eset)>0 ) zzedecode(eset);
+ else fprintf(stderr, " %s", zztokens[etok]);
+ if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup);
+ fprintf(stderr, "\n");
+}
+#endif
+
+/* is b an element of set p? */
+int
+#ifdef __USE_PROTOS
+zzset_el(unsigned b, SetWordType *p)
+#else
+zzset_el(b,p)
+unsigned b;
+SetWordType *p;
+#endif
+{
+ return( p[BSETDIVWORD(b)] & bitmask[BSETMODWORD(b)] );
+}
+
+int
+#ifdef __USE_PROTOS
+zzset_deg(SetWordType *a)
+#else
+zzset_deg(a)
+SetWordType *a;
+#endif
+{
+ /* Fast compute degree of a set... the number
+ of elements present in the set. Assumes
+ that all word bits are used in the set
+ */
+ register SetWordType *p = a;
+ register SetWordType *endp = &(a[zzSET_SIZE]);
+ register int degree = 0;
+
+ if ( a == NULL ) return 0;
+ while ( p < endp )
+ {
+ register SetWordType t = *p;
+ register SetWordType *b = &(bitmask[0]);
+ do {
+ if (t & *b) ++degree;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ p++;
+ }
+
+ return(degree);
+}
+
+#ifdef DEMAND_LOOK
+
+#ifdef LL_K
+int
+#ifdef __USE_PROTOS
+_zzmatch(int _t, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok,
+ SetWordType **zzMissSet)
+#else
+_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet)
+int _t;
+char **zzBadText;
+char **zzMissText;
+int *zzMissTok, *zzBadTok;
+SetWordType **zzMissSet;
+#endif
+{
+ if ( zzdirty==LL_K ) {
+ zzCONSUME;
+ }
+ if ( LA(1)!=_t ) {
+ *zzBadText = *zzMissText=LATEXT(1);
+ *zzMissTok= _t; *zzBadTok=LA(1);
+ *zzMissSet=NULL;
+ return 0;
+ }
+ zzMakeAttr
+ zzdirty++;
+ zzlabase++;
+ return 1;
+}
+
+int
+#ifdef __USE_PROTOS
+_zzmatch_wsig(int _t)
+#else
+_zzmatch_wsig(_t)
+int _t;
+#endif
+{
+ if ( zzdirty==LL_K ) {
+ zzCONSUME;
+ }
+ if ( LA(1)!=_t ) {
+ return 0;
+ }
+ zzMakeAttr
+ zzdirty++;
+ zzlabase++;
+ return 1;
+}
+
+#else
+
+int
+#ifdef __USE_PROTOS
+_zzmatch(int _t, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok, SetWordType **zzMissSet)
+#else
+_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet)
+int _t;
+char **zzBadText;
+char **zzMissText;
+int *zzMissTok, *zzBadTok;
+SetWordType **zzMissSet;
+#endif
+{
+ if ( zzdirty ) {zzCONSUME;}
+ if ( LA(1)!=_t ) {
+ *zzBadText = *zzMissText=LATEXT(1);
+ *zzMissTok= _t; *zzBadTok=LA(1);
+ *zzMissSet=NULL;
+ return 0;
+ }
+ zzdirty = 1;
+ zzMakeAttr
+ return 1;
+}
+
+int
+#ifdef __USE_PROTOS
+_zzmatch_wsig(int _t)
+#else
+_zzmatch_wsig(_t)
+int _t;
+#endif
+{
+ if ( zzdirty ) {zzCONSUME;}
+ if ( LA(1)!=_t ) {
+ return 0;
+ }
+ zzdirty = 1;
+ zzMakeAttr
+ return 1;
+}
+
+#endif /*LL_K*/
+
+#else
+
+int
+#ifdef __USE_PROTOS
+_zzmatch(int _t, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok,
+ SetWordType **zzMissSet)
+#else
+_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet)
+int _t;
+char **zzBadText;
+char **zzMissText;
+int *zzMissTok, *zzBadTok;
+SetWordType **zzMissSet;
+#endif
+{
+ if ( LA(1)!=_t ) {
+ *zzBadText = *zzMissText=LATEXT(1);
+ *zzMissTok= _t; *zzBadTok=LA(1);
+ *zzMissSet=NULL;
+ return 0;
+ }
+ zzMakeAttr
+ return 1;
+}
+
+int
+#ifdef __USE_PROTOS
+_zzmatch_wsig(int _t)
+#else
+_zzmatch_wsig(_t)
+int _t;
+#endif
+{
+ if ( LA(1)!=_t ) return 0;
+ zzMakeAttr
+ return 1;
+}
+
+#endif /*DEMAND_LOOK*/
+
+#ifdef ZZINF_LOOK
+void
+#ifdef __USE_PROTOS
+_inf_zzgettok(void)
+#else
+_inf_zzgettok()
+#endif
+{
+ if ( zzinf_labase >= zzinf_last )
+ {NLA = zzEOF_TOKEN; strcpy(NLATEXT, "");}
+ else {
+ NLA = zzinf_tokens[zzinf_labase];
+ zzline = zzinf_line[zzinf_labase]; /* wrong in 1.21 */
+ strcpy(NLATEXT, zzinf_text[zzinf_labase]);
+ zzinf_labase++;
+ }
+}
+#endif
+
+#ifdef ZZINF_LOOK
+/* allocate default size text,token and line arrays;
+ * then, read all of the input reallocing the arrays as needed.
+ * Once the number of total tokens is known, the LATEXT(i) array (zzinf_text)
+ * is allocated and its pointers are set to the tokens in zzinf_text_buffer.
+ */
+void
+#ifdef __USE_PROTOS
+zzfill_inf_look(void)
+#else
+zzfill_inf_look()
+#endif
+{
+ int tok, line;
+ int zzinf_token_buffer_size = ZZINF_DEF_TOKEN_BUFFER_SIZE;
+ int zzinf_text_buffer_size = ZZINF_DEF_TEXT_BUFFER_SIZE;
+ int zzinf_text_buffer_index = 0;
+ int zzinf_lap = 0;
+
+ /* allocate text/token buffers */
+ zzinf_text_buffer = (char *) malloc(zzinf_text_buffer_size);
+ if ( zzinf_text_buffer == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n",
+ zzinf_text_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_tokens = (int *) calloc(zzinf_token_buffer_size,sizeof(int));
+ if ( zzinf_tokens == NULL )
+ {
+ fprintf(stderr, "cannot allocate token buffer (%d tokens)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_line = (int *) calloc(zzinf_token_buffer_size,sizeof(int));
+ if ( zzinf_line == NULL )
+ {
+ fprintf(stderr, "cannot allocate line buffer (%d ints)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+
+ /* get tokens, copying text to text buffer */
+ zzinf_text_buffer_index = 0;
+ do {
+ zzgettok();
+ line = zzreal_line;
+ while ( zzinf_lap>=zzinf_token_buffer_size )
+ {
+ zzinf_token_buffer_size += ZZINF_BUFFER_TOKEN_CHUNK_SIZE;
+ zzinf_tokens = (int *) realloc(zzinf_tokens,
+ zzinf_token_buffer_size*sizeof(int));
+ if ( zzinf_tokens == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead token buffer (%d tokens)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_line = (int *) realloc(zzinf_line,
+ zzinf_token_buffer_size*sizeof(int));
+ if ( zzinf_line == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead line buffer (%d ints)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+
+ }
+ while ( (zzinf_text_buffer_index+strlen(NLATEXT)+1) >= zzinf_text_buffer_size )
+ {
+ zzinf_text_buffer_size += ZZINF_BUFFER_TEXT_CHUNK_SIZE;
+ zzinf_text_buffer = (char *) realloc(zzinf_text_buffer,
+ zzinf_text_buffer_size);
+ if ( zzinf_text_buffer == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n",
+ zzinf_text_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ }
+ /* record token and text and line of input symbol */
+ tok = zzinf_tokens[zzinf_lap] = NLA;
+ strcpy(&zzinf_text_buffer[zzinf_text_buffer_index], NLATEXT);
+ zzinf_text_buffer_index += strlen(NLATEXT)+1;
+ zzinf_line[zzinf_lap] = line;
+ zzinf_lap++;
+ } while (tok!=zzEOF_TOKEN);
+ zzinf_labase = 0;
+ zzinf_last = zzinf_lap-1;
+
+ /* allocate ptrs to text of ith token */
+ zzinf_text = (char **) calloc(zzinf_last+1,sizeof(char *));
+ if ( zzinf_text == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead text buffer (%d)\n",
+ zzinf_text_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_text_buffer_index = 0;
+ zzinf_lap = 0;
+ /* set ptrs so that zzinf_text[i] is the text of the ith token found on input */
+ while (zzinf_lap<=zzinf_last)
+ {
+ zzinf_text[zzinf_lap++] = &zzinf_text_buffer[zzinf_text_buffer_index];
+ zzinf_text_buffer_index += strlen(&zzinf_text_buffer[zzinf_text_buffer_index])+1;
+ }
+}
+#endif
+
+int
+#ifdef __USE_PROTOS
+_zzsetmatch(SetWordType *e, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok,
+ SetWordType **zzMissSet,
+ SetWordType *zzTokclassErrset /* MR23 */)
+#else
+_zzsetmatch(e, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet, zzTokclassErrset /* MR23 */)
+SetWordType *e;
+char **zzBadText;
+char **zzMissText;
+int *zzMissTok, *zzBadTok;
+SetWordType **zzMissSet;
+SetWordType *zzTokclassErrset;
+#endif
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {zzCONSUME;}
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+ if ( !zzset_el((unsigned)LA(1), e) ) {
+ *zzBadText = LATEXT(1); *zzMissText=NULL;
+ *zzMissTok= 0; *zzBadTok=LA(1);
+ *zzMissSet=zzTokclassErrset; /* MR23 */
+ return 0;
+ }
+ zzMakeAttr /* MR14 Ger Hobbelt (hobbelt@axa.nl) */
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+ zzlabase++; /* MR14 Ger Hobbelt (hobbelt@axa.nl) */
+#else
+ zzdirty = 1;
+#endif
+#endif
+ return 1;
+}
+
+int
+#ifdef __USE_PROTOS
+_zzmatch_wdfltsig(int tokenWanted, SetWordType *whatFollows)
+#else
+_zzmatch_wdfltsig(tokenWanted, whatFollows)
+int tokenWanted;
+SetWordType *whatFollows;
+#endif
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {
+ zzCONSUME;
+ }
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+
+ if ( LA(1)!=tokenWanted )
+ {
+ zzSyntaxErrCount++; /* MR11 */
+ fprintf(stderr,
+ "line %d: syntax error at \"%s\" missing %s\n",
+ zzline,
+ (LA(1)==zzEOF_TOKEN)?"<eof>":(char *)LATEXT(1),
+ zztokens[tokenWanted]);
+ zzconsumeUntil( whatFollows );
+ return 0;
+ }
+ else {
+ zzMakeAttr
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+ zzlabase++;
+#else
+ zzdirty = 1;
+#endif
+#else
+/* zzCONSUME; consume if not demand lookahead */
+#endif
+ return 1;
+ }
+}
+
+int
+#ifdef __USE_PROTOS
+_zzsetmatch_wdfltsig(SetWordType *tokensWanted,
+ int tokenTypeOfSet,
+ SetWordType *whatFollows)
+#else
+_zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows)
+SetWordType *tokensWanted;
+int tokenTypeOfSet;
+SetWordType *whatFollows;
+#endif
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {zzCONSUME;}
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+ if ( !zzset_el((unsigned)LA(1), tokensWanted) )
+ {
+ zzSyntaxErrCount++; /* MR11 */
+ fprintf(stderr,
+ "line %d: syntax error at \"%s\" missing %s\n",
+ zzline,
+ (LA(1)==zzEOF_TOKEN)?"<eof>":(char *)LATEXT(1),
+ zztokens[tokenTypeOfSet]);
+ zzconsumeUntil( whatFollows );
+ return 0;
+ }
+ else {
+ zzMakeAttr
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+ zzlabase++;
+#else
+ zzdirty = 1;
+#endif
+#else
+/* zzCONSUME; consume if not demand lookahead */
+#endif
+ return 1;
+ }
+}
+
+int
+#ifdef __USE_PROTOS
+_zzsetmatch_wsig(SetWordType *e)
+#else
+_zzsetmatch_wsig(e)
+SetWordType *e;
+#endif
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {zzCONSUME;}
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+ if ( !zzset_el((unsigned)LA(1), e) ) return 0;
+ zzMakeAttr /* MR14 Ger Hobbelt (hobbelt@axa.nl) */
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+ zzlabase++; /* MR14 Ger Hobbelt (hobbelt@axa.nl) */
+#else
+ zzdirty = 1;
+#endif
+#endif
+ return 1;
+}
+
+#ifdef USER_ZZMODE_STACK
+static int zzmstk[ZZMAXSTK] = { -1 };
+static int zzmdep = 0;
+static char zzmbuf[70];
+
+void
+#ifdef __USE_PROTOS
+zzmpush( int m )
+#else
+zzmpush( m )
+int m;
+#endif
+{
+ if(zzmdep == ZZMAXSTK - 1) {
+ sprintf(zzmbuf, "Mode stack overflow ");
+ zzerr(zzmbuf);
+ } else {
+ zzmstk[zzmdep++] = zzauto;
+ zzmode(m);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+zzmpop( void )
+#else
+zzmpop( )
+#endif
+{
+ if(zzmdep == 0)
+ { sprintf(zzmbuf, "Mode stack underflow ");
+ zzerr(zzmbuf);
+ }
+ else
+ { zzmdep--;
+ zzmode(zzmstk[zzmdep]);
+ }
+}
+
+void
+#ifdef __USE_PROTOS
+zzsave_mode_stack( int modeStack[], int *modeLevel )
+#else
+zzsave_mode_stack( modeStack, modeLevel )
+int modeStack[];
+int *modeLevel;
+#endif
+{
+ int i;
+ memcpy(modeStack, zzmstk, sizeof(zzmstk));
+ *modeLevel = zzmdep;
+ zzmdep = 0;
+
+ return;
+}
+
+void
+#ifdef __USE_PROTOS
+zzrestore_mode_stack( int modeStack[], int *modeLevel )
+#else
+zzrestore_mode_stack( modeStack, modeLevel )
+int modeStack[];
+int *modeLevel;
+#endif
+{
+ int i;
+
+ memcpy(zzmstk, modeStack, sizeof(zzmstk));
+ zzmdep = *modeLevel;
+
+ return;
+}
+#endif /* USER_ZZMODE_STACK */
+
+#ifdef __USE_PROTOS
+void zzTraceReset(void)
+#else
+void zzTraceReset()
+#endif
+{
+#ifdef zzTRACE_RULES
+ zzTraceOptionValue=zzTraceOptionValueDefault;
+ zzTraceGuessOptionValue=1;
+ zzTraceCurrentRuleName=NULL;
+ zzTraceDepth=0;
+#endif
+}
+
+#ifdef __USE_PROTOS
+void zzTraceGuessFail(void)
+#else
+void zzTraceGuessFail()
+#endif
+{
+
+#ifdef zzTRACE_RULES
+#ifdef ZZCAN_GUESS
+
+ int doIt=0;
+
+ if (zzTraceOptionValue <= 0) {
+ doIt=0;
+ } else if (zzguessing && zzTraceGuessOptionValue <= 0) {
+ doIt=0;
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ fprintf(stderr,"guess failed\n");
+ };
+#endif
+#endif
+}
+
+/* zzTraceOption:
+ zero value turns off trace
+*/
+
+#ifdef __USE_PROTOS
+void zzTraceIn(char * rule)
+#else
+void zzTraceIn(rule)
+ char *rule;
+#endif
+{
+#ifdef zzTRACE_RULES
+
+ int doIt=0;
+
+ zzTraceDepth++;
+ zzTraceCurrentRuleName=rule;
+
+ if (zzTraceOptionValue <= 0) {
+ doIt=0;
+#ifdef ZZCAN_GUESS
+ } else if (zzguessing && zzTraceGuessOptionValue <= 0) {
+ doIt=0;
+#endif
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ fprintf(stderr,"enter rule %s {\"%s\"} depth %d",
+ rule,
+ LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */
+ zzTraceDepth);
+#ifdef ZZCAN_GUESS
+ if (zzguessing) fprintf(stderr," guessing");
+#endif
+ fprintf(stderr,"\n");
+ };
+#endif
+ return;
+}
+
+#ifdef __USE_PROTOS
+void zzTraceOut(char * rule)
+#else
+void zzTraceOut(rule)
+ char *rule;
+#endif
+{
+#ifdef zzTRACE_RULES
+ int doIt=0;
+
+ zzTraceDepth--;
+
+ if (zzTraceOptionValue <= 0) {
+ doIt=0;
+#ifdef ZZCAN_GUESS
+ } else if (zzguessing && zzTraceGuessOptionValue <= 0) {
+ doIt=0;
+#endif
+ } else {
+ doIt=1;
+ };
+
+ if (doIt) {
+ fprintf(stderr,"exit rule %s {\"%s\"} depth %d",
+ rule,
+ LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */
+ zzTraceDepth+1);
+#ifdef ZZCAN_GUESS
+ if (zzguessing) fprintf(stderr," guessing");
+#endif
+ fprintf(stderr,"\n");
+ };
+#endif
+}
+
+#ifdef __USE_PROTOS
+int zzTraceOption(int delta)
+#else
+int zzTraceOption(delta)
+ int delta;
+#endif
+{
+#ifdef zzTRACE_RULES
+ int prevValue=zzTraceOptionValue;
+
+ zzTraceOptionValue=zzTraceOptionValue+delta;
+
+ if (zzTraceCurrentRuleName != NULL) {
+ if (prevValue <= 0 && zzTraceOptionValue > 0) {
+ fprintf(stderr,"trace enabled in rule %s depth %d\n",
+ zzTraceCurrentRuleName,zzTraceDepth);
+ };
+ if (prevValue > 0 && zzTraceOptionValue <= 0) {
+ fprintf(stderr,"trace disabled in rule %s depth %d\n",
+ zzTraceCurrentRuleName,zzTraceDepth);
+ };
+ };
+ return prevValue;
+#else
+ return 0;
+#endif
+}
+
+#ifdef __USE_PROTOS
+int zzTraceGuessOption(int delta)
+#else
+int zzTraceGuessOption(delta)
+ int delta;
+#endif
+{
+#ifdef zzTRACE_RULES
+#ifdef ZZCAN_GUESS
+ int prevValue=zzTraceGuessOptionValue;
+
+ zzTraceGuessOptionValue=zzTraceGuessOptionValue+delta;
+
+ if (zzTraceCurrentRuleName != NULL) {
+ if (prevValue <= 0 && zzTraceGuessOptionValue > 0) {
+ fprintf(stderr,"guess trace enabled in rule %s depth %d\n",
+ zzTraceCurrentRuleName,zzTraceDepth);
+ };
+ if (prevValue > 0 && zzTraceGuessOptionValue <= 0) {
+ fprintf(stderr,"guess trace disabled in rule %s depth %d\n",
+ zzTraceCurrentRuleName,zzTraceDepth);
+ };
+ };
+ return prevValue;
+#else
+ return 0;
+#endif
+#else
+ return 0;
+#endif
+}
+
+#endif /* ERR_H */
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/int.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/int.h
new file mode 100644
index 00000000..cebe16c5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/int.h
@@ -0,0 +1,37 @@
+/* ANTLR attribute definition -- long integers
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+#ifndef ZZINT_H
+#define ZZINT_H
+
+typedef long Attrib;
+
+#define zzcr_attr(a,tok,t) *(a) = atol(t);
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_assert.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_assert.h
new file mode 100644
index 00000000..13d133ab
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_assert.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_ASSERT_H__
+#define __PCCTS_ASSERT_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <cassert>
+#else
+#include <assert.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_iostream.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_iostream.h
new file mode 100644
index 00000000..24aee39f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_iostream.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_IOSTREAM_H__
+#define __PCCTS_IOSTREAM_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_istream.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_istream.h
new file mode 100644
index 00000000..54e1461d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_istream.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_ISTREAM_H__
+#define __PCCTS_ISTREAM_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <istream>
+#else
+#include <istream.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_setjmp.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_setjmp.h
new file mode 100644
index 00000000..a6e925d1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_setjmp.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_SETJMP_H__
+#define __PCCTS_SETJMP_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <csetjmp>
+#else
+#include <setjmp.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdarg.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdarg.h
new file mode 100644
index 00000000..25b3f1c9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdarg.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STDARG_H__
+#define __PCCTS_STDARG_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <cstdarg>
+#else
+#include <stdarg.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdio.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdio.h
new file mode 100644
index 00000000..0e9fc5b4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdio.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STDIO_H__
+#define __PCCTS_STDIO_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdlib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdlib.h
new file mode 100644
index 00000000..d929e29c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_stdlib.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STDLIB_H__
+#define __PCCTS_STDLIB_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <cstdlib>
+#else
+#include <stdlib.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_string.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_string.h
new file mode 100644
index 00000000..5ebd368a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pccts_string.h
@@ -0,0 +1,10 @@
+#ifndef __PCCTS_STRING_H__
+#define __PCCTS_STRING_H__
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#include <cstring>
+#else
+#include <string.h>
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcctscfg.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcctscfg.h
new file mode 100644
index 00000000..64637536
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcctscfg.h
@@ -0,0 +1,359 @@
+#ifndef PCCTS_CONFIG_H
+#define PCCTS_CONFIG_H
+/*
+ * pcctscfg.h (formerly config.h) (for ANTLR, DLG, and SORCERER)
+ *
+ * This is a simple configuration file that doesn't have config stuff
+ * in it, but it's a start.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * Used by PCCTS 1.33 (SORCERER 1.00B11 and up)
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-2000
+ */
+
+/* This file knows about the following ``environments''
+ UNIX (default)
+ DOS (use #define PC)
+ MAC (use #define MPW; has a few things for THINK C, Metrowerks)
+ MS/C++ (MR14 Microsoft Visual C++ environment uses symbol _MSC_VER)
+
+ */
+
+/* should test __STDC__ for 1, but some compilers don't set value, just def */
+
+#ifndef __USE_PROTOS
+#ifdef __STDC__
+#define __USE_PROTOS
+#endif
+#ifdef __cplusplus
+#define __USE_PROTOS
+#endif
+#endif
+
+#ifdef PCCTS_USE_NAMESPACE_STD
+#define PCCTS_NAMESPACE_STD namespace std {}; using namespace std;
+#else
+#define PCCTS_NAMESPACE_STD
+#endif
+
+#include "pccts_stdio.h"
+#include "pccts_stdlib.h"
+
+/* largest file name size */
+
+#ifdef _MAX_PATH
+#define MaxFileName _MAX_PATH /* MR9 RJV: MAX_PATH defined in stdlib.h (MSVC++ 5.0) */
+#else
+#define MaxFileName 300
+#endif
+
+/*
+* Define PC32 if in a 32-bit PC environment (e.g. extended DOS or Win32).
+* The macros tested here are defined by Watcom, Microsoft, Borland,
+* and djgpp, respectively, when they are used as 32-bit compilers.
+* Users of these compilers *must* be sure to define PC in their
+* makefiles for this to work correctly.
+*/
+#ifdef PC
+# if (defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) || \
+ defined(__GNUC__) || defined(__GNUG__))
+# ifndef PC32
+# define PC32
+# endif
+# endif
+#endif
+
+/* MR1 10-Apr-97 Default for PC is short file names */
+/* MR1 Default for non-PC is long file names */
+/* MR1 Can override via command line option LONGFILENAMES */
+
+#ifndef LONGFILENAMES
+#ifndef PC
+#define LONGFILENAMES
+#endif
+#endif
+
+#ifndef LONGFILENAMES
+#define ATOKEN_H "AToken.h"
+#define ATOKPTR_H "ATokPtr.h"
+#define ATOKPTR_IMPL_H "ATokPtrIm.h"
+#define ATOKENBUFFER_H "ATokBuf.h"
+#define ATOKENBUFFER_C "ATokBuf.cpp"
+#define ATOKENSTREAM_H "ATokStr.h"
+#define APARSER_H "AParser.h"
+#define APARSER_C "AParser.cpp"
+#define ASTBASE_H "ASTBase.h"
+#define ASTBASE_C "ASTBase.cpp"
+#define PCCTSAST_C "PCCTSAST.cpp"
+#define LIST_C "List.cpp"
+#define DLEXERBASE_H "DLexBase.h"
+#define DLEXERBASE_C "DLexBase.cpp"
+#define DLEXER_H "DLexer.h"
+#define STREESUPPORT_C "STreeSup.C"
+#else
+#define ATOKEN_H "AToken.h"
+#define ATOKPTR_H "ATokPtr.h"
+#define ATOKPTR_IMPL_H "ATokPtrImpl.h"
+#define ATOKENBUFFER_H "ATokenBuffer.h"
+#define ATOKENBUFFER_C "ATokenBuffer.cpp"
+#define ATOKENSTREAM_H "ATokenStream.h"
+#define APARSER_H "AParser.h"
+#define APARSER_C "AParser.cpp"
+#define ASTBASE_H "ASTBase.h"
+#define ASTBASE_C "ASTBase.cpp"
+#define PCCTSAST_C "PCCTSAST.cpp"
+#define LIST_C "List.cpp"
+#define DLEXERBASE_H "DLexerBase.h"
+#define DLEXERBASE_C "DLexerBase.cpp"
+#define DLEXER_H "DLexer.h"
+#define STREESUPPORT_C "STreeSupport.cpp"
+#endif
+
+/* SORCERER Stuff */
+
+/* MR8 6-Aug-97 Change from ifdef PC to ifndef LONGFILENAMES */
+
+#ifndef LONGFILENAMES
+#define STPARSER_H "STreePar.h"
+#define STPARSER_C "STreePar.C"
+#else
+#define STPARSER_H "STreeParser.h"
+#define STPARSER_C "STreeParser.cpp"
+#endif
+
+#ifdef MPW
+#define CPP_FILE_SUFFIX ".cp"
+#define CPP_FILE_SUFFIX_NO_DOT "cp"
+#define OBJ_FILE_SUFFIX ".o"
+#else
+#ifdef PC
+#define CPP_FILE_SUFFIX ".cpp"
+#define CPP_FILE_SUFFIX_NO_DOT "cpp"
+#define OBJ_FILE_SUFFIX ".obj"
+#else
+#ifdef __VMS
+#define CPP_FILE_SUFFIX ".cpp"
+#define CPP_FILE_SUFFIX_NO_DOT "cpp"
+#define OBJ_FILE_SUFFIX ".obj"
+#else
+#define CPP_FILE_SUFFIX ".cpp"
+#define CPP_FILE_SUFFIX_NO_DOT "cpp"
+#define OBJ_FILE_SUFFIX ".o"
+#endif
+#endif
+#endif
+
+/* User may redefine how line information looks */ /* make it #line MR7 */
+/* MR21 Use #ifndef */
+
+#ifndef LineInfoFormatStr
+#define LineInfoFormatStr "#line %d \"%s\"\n"
+#endif
+
+#ifdef MPW /* Macintosh Programmer's Workshop */
+#define ErrHdr "File \"%s\"; Line %d #"
+#else
+#ifdef _MSC_VER /* MR14 Microsoft Visual C++ environment */
+#define ErrHdr "%s(%d) :"
+#else
+#define ErrHdr "%s, line %d:" /* default */
+#endif
+#endif
+
+/* must assume old K&R cpp here, can't use #if defined(..)... */
+
+#ifdef MPW
+#define TopDirectory ":"
+#define DirectorySymbol ":"
+#define OutputDirectoryOption "Directory where all output files should go (default=\":\")"
+#else
+#ifdef PC
+#define TopDirectory "."
+#define DirectorySymbol "\\"
+#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"
+#else
+#ifdef __VMS
+#define TopDirectory "[000000]"
+#define DirectorySymbol "]"
+#define OutputDirectoryOption "Directory where all output files should go (default=\"[]\")"
+#else
+#define TopDirectory "."
+#define DirectorySymbol "/"
+#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"
+#endif
+#endif
+#endif
+
+#ifdef MPW
+
+/* Make sure we have prototypes for all functions under MPW */
+
+#include "pccts_string.h"
+#include "pccts_stdlib.h"
+
+/* MR6 2-Jun-97 Fixes false dependency caused by VC++ #include scanner */
+/* MR6 Reported by Brad Schick (schick@interaccess.com) */
+#define MPW_CursorCtl_Header <CursorCtl.h>
+#include MPW_CursorCtl_Header
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void fsetfileinfo (const char *filename, unsigned long newcreator, unsigned long newtype);
+#ifdef __cplusplus
+}
+#endif
+
+/* File creators for various popular development environments */
+
+#define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */
+#if 0
+#define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */
+#endif
+#if 0
+#define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */
+#endif
+
+#endif
+
+#ifdef MPW
+#define DAWDLE SpinCursor(1)
+#else
+#define DAWDLE
+#endif
+
+#ifdef MPW
+#define SPECIAL_INITS
+#define SPECIAL_FOPEN
+#endif
+
+#ifdef MPW
+#ifdef __cplusplus
+inline
+#else
+static
+#endif
+void special_inits()
+{
+ InitCursorCtl((acurHandle) 0);
+}
+#endif
+
+#ifdef MPW
+#ifdef __cplusplus
+inline
+#else
+static
+#endif
+void special_fopen_actions(char * s)
+{
+ fsetfileinfo (s, MAC_FILE_CREATOR, 'TEXT');
+}
+#endif
+
+/* Define usable bits for set.c stuff */
+#define BytesPerWord sizeof(unsigned)
+#define WORDSIZE (sizeof(unsigned)*8)
+#define LogWordSize (WORDSIZE==16?4:5)
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#if defined(VAXC) || defined(__VMS)
+#include <ssdef.h>
+#define PCCTS_EXIT_SUCCESS 1
+#define PCCTS_EXIT_FAILURE SS$_ABORT
+#define zzDIE return SS$_ABORT;
+#define zzDONE return 1;
+
+#else /* !VAXC and !__VMS */
+
+#define PCCTS_EXIT_SUCCESS 0
+#define PCCTS_EXIT_FAILURE 1
+#define zzDIE return 1;
+#define zzDONE return 0;
+
+#endif
+
+#ifdef USER_ZZMODE_STACK
+# ifndef ZZSTACK_MAX_MODE
+# define ZZSTACK_MAX_MODE 32
+# endif
+# define ZZMAXSTK (ZZSTACK_MAX_MODE * 2)
+#endif
+
+#ifndef DllExportPCCTS
+#define DllExportPCCTS
+#endif
+
+#ifdef PC
+#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME
+#define PCCTS_CASE_INSENSITIVE_FILE_NAME
+#endif
+#endif
+
+#ifdef PC32
+#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME
+#define PCCTS_CASE_INSENSITIVE_FILE_NAME
+#endif
+#endif
+
+#ifdef __VMS
+#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME
+#define PCCTS_CASE_INSENSITIVE_FILE_NAME
+#endif
+#endif
+
+#ifdef __USE_PROTOS
+#ifndef PCCTS_USE_STDARG
+#define PCCTS_USE_STDARG
+#endif
+#endif
+
+#ifdef __STDC__
+#ifndef PCCTS_USE_STDARG
+#define PCCTS_USE_STDARG
+#endif
+#endif
+
+#ifdef __cplusplus
+#ifndef PCCTS_USE_STDARG
+#define PCCTS_USE_STDARG
+#endif
+#endif
+
+#ifdef _MSC_VER
+/*Turn off the warnings for:
+ unreferenced inline/local function has been removed
+*/
+#pragma warning(disable : 4514)
+/* function not expanded */
+#pragma warning(disable : 4710)
+#endif
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcnames.bat b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcnames.bat
new file mode 100644
index 00000000..8784aee9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/pcnames.bat
@@ -0,0 +1,11 @@
+ren aparser.c aparser.cpp
+ren astbase.c astbase.cpp
+ren atokenbu.c atokbuf.cpp
+ren atokenbu.h atokbuf.h
+ren atokenst.h atokstr.h
+ren dlexerba.c dlexbase.cpp
+ren dlexerba.h dlexbase.h
+ren dlexer.c dlexer.cpp
+ren list.c list.cpp
+ren pblackbo.h pblckbox.h
+ren pcctsast.c pcctsast.cpp
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/slist.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/slist.cpp
new file mode 100644
index 00000000..eceacc47
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/h/slist.cpp
@@ -0,0 +1,116 @@
+/*
+ * SList.C
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
+ * domain. An individual or company may do whatever they wish with
+ * source code distributed with SORCERER or the code generated by
+ * SORCERER, including the incorporation of SORCERER, or its output, into
+ * commerical software.
+ *
+ * We encourage users to develop software with SORCERER. However, we do
+ * ask that credit is given to us for developing SORCERER. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like SORCERER and have developed a nice tool with the
+ * output, please mention that you developed it using SORCERER. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * PCCTS 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1992-2000
+ */
+
+#define ANTLR_SUPPORT_CODE
+
+#include "SList.h"
+#include "pccts_stdarg.h" // MR23
+
+/* Iterate over a list of elements; returns ptr to a new element
+ * in list upon every call and NULL when no more are left.
+ * Very useful like this:
+ *
+ * cursor = mylist;
+ * while ( (p=mylist->iterate(&cursor)) ) {
+ * // place with element p
+ * }
+ *
+ * The cursor must be initialized to point to the list to iterate over.
+ */
+void *SList::
+iterate(SListNode **cursor)
+{
+ void *e;
+
+ if ( cursor == NULL || *cursor==NULL ) return NULL;
+ if ( head == *cursor ) { *cursor = (*cursor)->next(); }
+ e = (*cursor)->elem();
+ (*cursor) = (*cursor)->next();
+ return e;
+}
+
+/* add an element to end of list. */
+void SList::
+add(void *e)
+{
+ SListNode *p, *tail=NULL;
+ require(e!=NULL, "slist_add: attempting to add NULL list element");
+
+ p = new SListNode;
+ require(p!=NULL, "add: cannot alloc new list node");
+ p->setElem(e);
+ if ( head == NULL )
+ {
+ head = tail = p;
+ }
+ else /* find end of list */
+ {
+ tail->setNext(p);
+ tail = p;
+ }
+}
+
+void SList::
+lfree()
+{
+ SListNode *p,*q;
+
+ if ( head==NULL ) return; /* empty list */
+ for (p = head; p!=NULL; p=q)
+ {
+ q = p->next();
+ free(p);
+ }
+}
+
+PCCTS_AST *SList::
+to_ast(SList list)
+{
+ PCCTS_AST *t=NULL, *last=NULL;
+ SListNode *p;
+
+ for (p = head; p!=NULL; p=p->next())
+ {
+ PCCTS_AST *u = (PCCTS_AST *)p->elem();
+ if ( last==NULL ) last = t = u;
+ else { last->setRight(u); last = u; }
+ }
+ return t;
+}
+
+// MR23
+int SList::printMessage(FILE* pFile, const char* pFormat, ...)
+{
+ va_list marker;
+ va_start( marker, pFormat );
+ int iRet = vfprintf(pFile, pFormat, marker);
+ va_end( marker );
+ return iRet;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.ps b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.ps
new file mode 100644
index 00000000..e2600d51
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.ps
@@ -0,0 +1,473 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.06
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Italic
+%%+ font Courier
+%%DocumentSuppliedResources: procset grops 1.06 0
+%%Pages: 3
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.06 0
+
+/setpacking where {
+ pop
+ currentpacking
+ true setpacking
+} if
+
+/grops 120 dict dup begin
+
+% The ASCII code of the space character.
+/SC 32 def
+
+/A /show load def
+/B { 0 SC 3 -1 roll widthshow } bind def
+/C { 0 exch ashow } bind def
+/D { 0 exch 0 SC 5 2 roll awidthshow } bind def
+/E { 0 rmoveto show } bind def
+/F { 0 rmoveto 0 SC 3 -1 roll widthshow } bind def
+/G { 0 rmoveto 0 exch ashow } bind def
+/H { 0 rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+/I { 0 exch rmoveto show } bind def
+/J { 0 exch rmoveto 0 SC 3 -1 roll widthshow } bind def
+/K { 0 exch rmoveto 0 exch ashow } bind def
+/L { 0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+/M { rmoveto show } bind def
+/N { rmoveto 0 SC 3 -1 roll widthshow } bind def
+/O { rmoveto 0 exch ashow } bind def
+/P { rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+/Q { moveto show } bind def
+/R { moveto 0 SC 3 -1 roll widthshow } bind def
+/S { moveto 0 exch ashow } bind def
+/T { moveto 0 exch 0 SC 5 2 roll awidthshow } bind def
+
+% name size font SF -
+
+/SF {
+ findfont exch
+ [ exch dup 0 exch 0 exch neg 0 0 ] makefont
+ dup setfont
+ [ exch /setfont cvx ] cvx bind def
+} bind def
+
+% name a c d font MF -
+
+/MF {
+ findfont
+ [ 5 2 roll
+ 0 3 1 roll % b
+ neg 0 0 ] makefont
+ dup setfont
+ [ exch /setfont cvx ] cvx bind def
+} bind def
+
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+
+% Guess the page length.
+% This assumes that the imageable area is vertically centered on the page.
+% PLG - length
+
+/PLG {
+ gsave newpath clippath pathbbox grestore
+ exch pop add exch pop
+} bind def
+
+% BP -
+
+/BP {
+ /level0 save def
+ 1 setlinecap
+ 1 setlinejoin
+ 72 RES div dup scale
+ LS {
+ 90 rotate
+ } {
+ 0 PL translate
+ } ifelse
+ 1 -1 scale
+} bind def
+
+/EP {
+ level0 restore
+ showpage
+} bind def
+
+
+% centerx centery radius startangle endangle DA -
+
+/DA {
+ newpath arcn stroke
+} bind def
+
+% x y SN - x' y'
+% round a position to nearest (pixel + (.25,.25))
+
+/SN {
+ transform
+ .25 sub exch .25 sub exch
+ round .25 add exch round .25 add exch
+ itransform
+} bind def
+
+% endx endy startx starty DL -
+% we round the endpoints of the line, so that parallel horizontal
+% and vertical lines will appear even
+
+/DL {
+ SN
+ moveto
+ SN
+ lineto stroke
+} bind def
+
+% centerx centery radius DC -
+
+/DC {
+ newpath 0 360 arc closepath
+} bind def
+
+
+/TM matrix def
+
+% width height centerx centery DE -
+
+/DE {
+ TM currentmatrix pop
+ translate scale newpath 0 0 .5 0 360 arc closepath
+ TM setmatrix
+} bind def
+
+% these are for splines
+
+/RC /rcurveto load def
+/RL /rlineto load def
+/ST /stroke load def
+/MT /moveto load def
+/CL /closepath load def
+
+% fill the last path
+
+% amount FL -
+
+/FL {
+ currentgray exch setgray fill setgray
+} bind def
+
+% fill with the ``current color''
+
+/BL /fill load def
+
+/LW /setlinewidth load def
+% new_font_name encoding_vector old_font_name RE -
+
+/RE {
+ findfont
+ dup maxlength dict begin
+ {
+ 1 index /FID ne { def } { pop pop } ifelse
+ } forall
+ /Encoding exch def
+ dup /FontName exch def
+ currentdict end definefont pop
+} bind def
+
+/DEFS 0 def
+
+% hpos vpos EBEGIN -
+
+/EBEGIN {
+ moveto
+ DEFS begin
+} bind def
+
+/EEND /end load def
+
+/CNT 0 def
+/level1 0 def
+
+% llx lly newwid wid newht ht newllx newlly PBEGIN -
+
+/PBEGIN {
+ /level1 save def
+ translate
+ div 3 1 roll div exch scale
+ neg exch neg exch translate
+ % set the graphics state to default values
+ 0 setgray
+ 0 setlinecap
+ 1 setlinewidth
+ 0 setlinejoin
+ 10 setmiterlimit
+ [] 0 setdash
+ /setstrokeadjust where {
+ pop
+ false setstrokeadjust
+ } if
+ /setoverprint where {
+ pop
+ false setoverprint
+ } if
+ newpath
+ /CNT countdictstack def
+ userdict begin
+ /showpage {} def
+} bind def
+
+/PEND {
+ clear
+ countdictstack CNT sub { end } repeat
+ level1 restore
+} bind def
+
+end def
+
+/setpacking where {
+ pop
+ setpacking
+} if
+%%EndResource
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Courier
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
+792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
+/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
+/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
+/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
+/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
+/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
+/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
+/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
+/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
+/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
+/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
+/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
+/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
+/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE/Times-Italic@0
+ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 13/Times-Roman@0 SF(The History of PCCTS)228.232 84 Q/F1 11/Times-Roman@0
+SF(The Purdue Compiler)190.468 108 Q(-Construction T)-.22 E(ool Set)-.88 E/F2
+10/Times-Italic@0 SF -.92(Te)262.245 144 S -.37(re).92 G(nce P).37 E(arr)-.8 E
+/F3 10/Times-Roman@0 SF -.15(Pa)234.755 156 S(rr Research Corporation).15 E
+(Minneapolis, Minnesota)239.39 168 Q(and)280.78 180 Q(Uni)239.315 192 Q -.15
+(ve)-.25 G(rsity of Minnesota).15 E
+(Army High Performance Computing Research Center)180.38 204 Q F2
+([Updated 8-7-94])252.31 228 Q F1 .084(The PCCTS project be)97 259.6 R -.055
+(ga)-.165 G 2.834(na).055 G 2.833(sap)220.547 259.6 S(arser)240.876 259.6 Q
+.083(-generator project for a graduate course at Purdue Uni-)-.22 F -.165(ve)72
+275.6 S 1.085(rsity in the F).165 F 1.086
+(all of 1988 taught by Hank Dietz\212 translator)-.165 F 1.086
+(-writing systems.)-.22 F 1.086(Under the guid-)6.586 F .627
+(ance of Professor Dietz, the parser generator)72 291.6 R 3.377(,A)-.44 G .626
+(NTLR \(originally called YUCC\), continued after)285.18 291.6 R .253
+(the termination of the course and e)72 307.6 R -.165(ve)-.275 G .254
+(ntually became the subject of T).165 F .254(erence P)-.77 F(arr')-.165 E 3.004
+(sM)-.605 G(aster')445.083 307.6 Q 3.004(st)-.605 G(hesis.)479.25 307.6 Q
+(Originally)72 323.6 Q 4.092(,l)-.715 G -.165(ex)126.406 323.6 S 1.342
+(ical analysis w).165 F 1.342(as performed via ALX which w)-.11 F 1.342
+(as soon replaced by W)-.11 F 1.341(ill Cohen')-.44 F(s)-.605 E .594
+(DLG in the F)72 339.6 R .594(all of 1989 \(DF)-.165 F .595(A-based le)-.814 F
+.595(xical-analyzer generator)-.165 F 3.345(,a)-.44 G .595(lso an of)367.188
+339.6 R .595(fshoot of the graduate)-.275 F(translation course\).)72 355.6 Q
+.877(The alpha v)97 375.2 R .877(ersion of ANTLR w)-.165 F .877(as totally re)
+-.11 F .876(written resulting in 1.00B.)-.275 F -1.221(Ve)6.376 G .876
+(rsion 1.00B w)1.221 F(as)-.11 E 1.577(released via an internet ne)72 391.2 R
+1.577(wsgroup \(comp.compilers\) posting in February of 1990 and quickly)-.275
+F -.055(ga)72 407.2 S .356(thered a lar).055 F .356(ge follo)-.198 F 3.106
+(wing. 1.00B)-.275 F .356(generated only LL\(1\) parsers, b)3.106 F .356
+(ut allo)-.22 F .356(wed the mer)-.275 F .356(ged descrip-)-.198 F 1.859
+(tion of le)72 423.2 R 1.859(xical and syntactic analysis.)-.165 F 1.86
+(It had rudimentary attrib)7.359 F 1.86(ute handling similar to that of)-.22 F
+-.55 -1.32(YA C)72 439.2 T 3.549(Ca)1.32 G .799
+(nd did not incorporate rule parameters or return v)109.231 439.2 R .798
+(alues; do)-.275 F(wnw)-.275 E .798(ard inheritance w)-.11 F .798(as v)-.11 F
+(ery)-.165 E -.165(aw)72 455.2 S(kw).165 E 6.433(ard. 1.00B-generated)-.11 F
+3.684(parsers terminated upon the \214rst syntax error)6.433 F 9.184(.L)-.605 G
+-.165(ex)440.916 455.2 S 3.684(ical classes).165 F(\(modes\) were not allo)72
+471.2 Q(wed and DLG did not ha)-.275 E .33 -.165(ve a)-.22 H 2.75(ni).165 G
+(nteracti)305.959 471.2 Q .33 -.165(ve m)-.275 H(ode.).165 E .831
+(Upon starting his Ph.D. at Purdue in the F)97 490.8 R .83(all of 1990, T)-.165
+F .83(erence P)-.77 F .83(arr be)-.165 F -.055(ga)-.165 G 3.58(nt).055 G .83
+(he second total)436.351 490.8 R(re)72 506.8 Q 1.646(write of ANTLR.)-.275 F
+1.646(The method by which grammars may be practically analyzed to generate)
+7.146 F/F4 11/Times-Italic@0 SF(LL)72.638 522.8 Q F1(\().583 E F4(k).396 E F1
+3.849(\)l).737 G 1.099(ookahead information w)105.703 522.8 R 1.099(as disco)
+-.11 F -.165(ve)-.165 G 1.099(red in August of 1990 just before his return.)
+.165 F -1.221(Ve)6.598 G(rsion)1.221 E .626
+(1.00 incorporated this algorithm and included the AST mechanism, le)72 538.8 R
+.626(xical classes, error classes,)-.165 F .354(and automatic error reco)72
+554.8 R -.165(ve)-.165 G .353(ry; code quality and portability were higher).165
+F 5.853(.I)-.605 G 3.103(nF)395.965 554.8 S .353(ebruary of 1992 1.00)410.684
+554.8 R -.11(wa)72 570.8 S 2.76(sr).11 G .01
+(eleased via an article in SIGPLAN Notices.)95.418 570.8 R .01
+(Peter Dahl, Ph.D. candidate, and Professor Matt)5.51 F(O'K)72 586.8 Q 2.074
+(eefe \(both at the Uni)-.275 F -.165(ve)-.275 G 2.073
+(rsity of Minnesota\) tested this v).165 F 2.073(ersion e)-.165 F(xtensi)-.165
+E -.165(ve)-.275 G(ly).165 E 7.573(.D)-.715 G 2.073(ana Hogg)448.522 586.8 R
+(att)-.055 E .078(\(Micro Data Base Systems, Inc.\) came up with the idea of e\
+rror grouping \(strings attached to non-)72 602.8 R
+(terminals\) and tested 1.00 hea)72 618.8 Q(vily)-.22 E(.)-.715 E -1.221(Ve)97
+638.4 S .878(rsion 1.06 w)1.221 F .877
+(as released in December 1992 and represented a lar)-.11 F .877
+(ge feature enhancement)-.198 F -.165(ove)72 654.4 S 3.648(r1).165 G 3.648
+(.00. F)100.365 654.4 R .898(or e)-.165 F .899
+(xample, rudimentary semantic predicates were introduced, error messages were)
+-.165 F 2.281(signi\214cantly impro)72 670.4 R -.165(ve)-.165 G 5.031(df).165 G
+(or)181.953 670.4 Q F4(k)5.427 E F1 2.281
+(>1 lookahead and ANTLR parsers could indicate that lookahead).737 F 1.381
+(fetches were to occur only when necessary for the parse \(normally)72 686.4 R
+4.131(,t)-.715 G 1.381(he lookahead `)387.051 686.4 R(`pipe')-.814 E 4.132('w)
+-.814 G(as)494.837 686.4 Q 1.182(constantly full\).)72 702.4 R 1.182
+(Russell Quong joined the project in the Spring of 1992 to aid in the semantic)
+6.682 F .681(predicate design.)72 718.4 R(Be)6.181 E .681(ginning and adv)-.165
+F .682(anced tutorials were created and released as well.)-.275 F 3.432(Am)
+6.182 G(ak)485.179 718.4 Q(e-)-.11 E .993(\214le generator w)72 734.4 R .993
+(as included that sets up dependencies and such correctly for ANTLR and DLG.)
+-.11 F EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 11/Times-Roman@0 SF 2.75(-2-)278.837 52 S -1.221(Ve)72 88 S 1.414(ry fe)
+1.221 F 4.164(w1)-.275 G 1.414(.00 incompatibilities were introduced \(1.00 w)
+122.81 88 R 1.415(as quite dif)-.11 F 1.415(ferent from 1.00B in some)-.275 F
+(areas\).)72 104 Q 1.089(1.10 w)97 123.6 R 1.088
+(as released on August 31, 1993 and incorporated b)-.11 F 1.088(ug \214x)-.22 F
+1.088(es, a fe)-.165 F 3.838(wf)-.275 G 1.088(eature enhance-)433.59 123.6 R
+3.112(ments and a major ne)72 139.6 R 5.863(wc)-.275 G(apability \212)196.957
+139.6 Q 3.113(an arbitrary lookahead operator \(syntactic predicate\),)5.863 F
+/F1 11/Courier@0 SF(\(alpha\)?beta)72 155.6 Q F0 6.754(.T)C 1.254
+(his feature w)167.425 155.6 R 1.254
+(as co-designed with Professor Russell Quong also at Purdue.)-.11 F 3.297 -.88
+(To s)72 171.6 T 1.537
+(upport in\214nite lookahead, a preprocessor \215ag, ZZINF_LOOK, w).88 F 1.537
+(as created that forced the)-.11 F .21(ANTLR\(\) macro to tok)72 187.6 R .21
+(enize all input prior to parsing.)-.11 F .209(Hence, at an)5.709 F 2.959(ym)
+-.165 G .209(oment, an action or predi-)389.215 187.6 R .936
+(cate can see the entire input sentence.)72 203.6 R .936
+(The predicate mechanism of 1.06 w)6.436 F .937(as e)-.11 F .937
+(xtended to allo)-.165 F(w)-.275 E .55
+(multiple predicates to be hoisted; the syntactic conte)72 219.6 R .55
+(xt of a predicate w)-.165 F .55(as also mo)-.11 F -.165(ve)-.165 G 3.299(da)
+.165 G .549(long with)461.585 219.6 R(the predicate.)72 235.6 Q .754
+(In February of 1994, SORCERER \(a simple tree-parser generator\) w)97 255.2 R
+.755(as released.)-.11 F .755(This tool)6.255 F(allo)72 271.2 Q .6(ws the user\
+ to parse child-sibling trees by specifying a grammar rather than b)-.275 F
+.599(uilding a recur)-.22 F(-)-.22 E(si)72 287.2 Q -.165(ve)-.275 G 1.39
+(-descent tree w).165 F(alk)-.11 E 1.391(er by hand.)-.11 F -.88(Wo)6.891 G
+1.391(rk to).88 F -.11(wa)-.275 G 1.391
+(rds a library of tree transformations is underw).11 F(ay)-.11 E(.)-.715 E .581
+(Aaron Sa)72 303.2 R(wde)-.165 E 3.331(ya)-.165 G 3.331(tT)145.531 303.2 S .581
+(he Uni)158.641 303.2 R -.165(ve)-.275 G .58
+(rsity of Minnesota became a second author of SORCERER after the).165 F
+(initial release.)72 319.2 Q .627(On April 1, 1994, PCCTS 1.20 w)97 338.8 R
+.627(as released.)-.11 F .627(This w)6.127 F .627(as the \214rst v)-.11 F .627
+(ersion to acti)-.165 F -.165(ve)-.275 G .627(ly support).165 F 1.664
+(C++ output.)72 354.8 R 1.664(It also included important \214x)7.164 F 1.663
+(es re)-.165 F -.055(ga)-.165 G 1.663
+(rding semantic predicates and \(..\)+ subrules.).055 F(This v)72 370.8 Q
+(ersion also introduced tok)-.165 E(en classes, the `)-.11 E(`)-.814 E/F2 11
+/Times-Italic@0 SF(not)A F0 1.628 -.814('' o)D(perator).814 E 2.75(,a)-.44 G
+(nd tok)355.294 370.8 Q(en ranges.)-.11 E .764
+(On June 19, 1994, SORCERER 1.00B9 w)97 390.4 R .765(as released.)-.11 F .765
+(Gary Funck of Intrepid T)6.265 F(echnology)-.77 E .807
+(joined the SORCERER team and pro)72 406.4 R .807(vided v)-.165 F .807(ery v)
+-.165 F .807(aluable suggestions re)-.275 F -.055(ga)-.165 G .806(rding the `)
+.055 F(`transform')-.814 E(')-.814 E(mode of SORCERER.)72 422.4 Q 1.137
+(On August 8, 1994, PCCTS 1.21 w)97 442 R 1.137(as released.)-.11 F 1.138
+(It mainly cleaned up the C++ output and)6.637 F(included a number of b)72 458
+Q(ug \214x)-.22 E(es.)-.165 E .316(From the 1.21 release forw)97 477.6 R .316
+(ard, the maintenance and support of all PCCTS tools will be pri-)-.11 F 1.557
+(marily pro)72 493.6 R 1.557(vided by P)-.165 F 1.557
+(arr Research Corporation, Minneapolis MN---an or)-.165 F -.055(ga)-.198 G
+1.558(nization founded on).055 F 1.616(the principles of e)72 509.6 R 1.616
+(xcellence in research and inte)-.165 F 1.616(grity in b)-.165 F 1.616
+(usiness; we are de)-.22 F -.22(vo)-.275 G 1.616(ted to pro).22 F(viding)-.165
+E 1.202(really cool softw)72 525.6 R 1.202(are tools.)-.11 F 1.202
+(Please see \214le PCCTS.FUTURE for more information.)6.702 F 1.203(All PCCTS)
+6.703 F(tools currently in the public domain will continue to be in the public\
+ domain.)72 541.6 Q 1.198(Looking to)97 561.2 R -.11(wa)-.275 G 1.198
+(rds the future, a graphical user).11 F(-interf)-.22 E 1.197
+(ace is in the design phase.)-.11 F 1.197(This w)6.697 F(ould)-.11 E(allo)72
+577.2 Q 2.753(wu)-.275 G .003(sers to vie)104.42 577.2 R 2.753(wt)-.275 G .004
+(he syntax diagram representation of their grammars and w)162.509 577.2 R .004
+(ould highlight non-)-.11 F 1.181(deterministic productions.)72 593.2 R -.165
+(Pa)6.681 G 1.18(rsing can be traced graphically as well.).165 F 1.18
+(This system will be b)6.68 F(uilt)-.22 E .167(using a multiplatform windo)72
+609.2 R 2.917(wl)-.275 G(ibrary)211.73 609.2 Q 5.667(.W)-.715 G 2.917(ea)
+255.204 609.2 S .168(lso anticipate the introduction of a sophisticated error)
+267.889 609.2 R(handling mechanism called `)72 625.2 Q(`parser e)-.814 E
+(xception handling')-.165 E 2.75('i)-.814 G 2.75(nan)327.431 625.2 S
+(ear future release.)348.815 625.2 Q(Currently)97 644.8 Q 3.019(,P)-.715 G .269
+(CCTS is used at o)150.333 644.8 R -.165(ve)-.165 G 3.019(r1).165 G .269
+(000 kno)253.098 644.8 R .268(wn academic, go)-.275 F -.165(ve)-.165 G .268
+(rnment, and commercial sites).165 F .859(in 37 countries.)72 660.8 R .859
+(Of course, the true number of users is unkno)6.359 F .859(wn due to the lar)
+-.275 F .859(ge number of ftp)-.198 F(sites.)72 676.8 Q EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 11/Times-Roman@0 SF 2.75(-3-)278.837 52 S(Credits)272.11 88 Q .44 LW
+472.162 103.75 103.838 103.75 DL(Idea/T)134.236 117 Q 52.987(ool Coder)-.88 F
+(Co-designer\(s\))345.436 117 Q 281.334 103.75 281.334 124.75 DL 209.273 103.75
+209.273 124.75 DL 209.273 124.75 103.838 124.75 DL 103.838 126.75 209.273
+126.75 DL 281.334 124.75 209.273 124.75 DL 209.273 126.75 281.334 126.75 DL
+472.162 124.75 281.334 124.75 DL 281.334 126.75 472.162 126.75 DL(ANTLR 1.00A)
+109.338 140 Q -.77(Te)217.523 140 S(rence P).77 E 13.75(arr Hank)-.165 F(Dietz)
+2.75 E 82.83(ALX T)109.338 156 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz)
+2.75 E(ANTLR 1.00B)109.338 172 Q -.77(Te)217.523 172 S(rence P).77 E 13.75
+(arr Hank)-.165 F(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00B)109.338 188 Q -.44
+(Wi)217.523 188 S(ll Cohen).44 E -.77(Te)289.584 188 S(rence P).77 E(arr)-.165
+E 2.75(,H)-.44 G(ank Dietz)358.147 188 Q(NF)109.338 204 Q 2.75(AR)-.814 G
+30.778(elabelling W)140.611 204 R(ill Cohen)-.44 E/F1 11/Times-Italic@0 SF(LL)
+109.976 220 Q F0(\().583 E F1(k).396 E F0 2.75(\)a).737 G 40.447(nalysis T)
+143.768 220 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz)2.75 E(ANTLR 1.00)
+109.338 236 Q -.77(Te)217.523 236 S(rence P).77 E 13.75(arr Hank)-.165 F
+(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00)109.338 252 Q -.44(Wi)217.523 252 S
+(ll Cohen).44 E -.77(Te)289.584 252 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G
+(ank Dietz)358.147 252 Q(ANTLR 1.06)109.338 268 Q -.77(Te)217.523 268 S
+(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong, Hank Dietz)-.44 E
+(DLG 1.06)109.338 284 Q -.44(Wi)217.523 284 S(ll Cohen).44 E -.77(Te)289.584
+284 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G(ank Dietz)358.147 284 Q
+(ANTLR 1.10)109.338 300 Q -.77(Te)217.523 300 S(rence P).77 E 13.75(arr W)-.165
+F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.20)109.338 316 Q -.77(Te)217.523 316
+S(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.21)
+109.338 332 Q -.77(Te)217.523 332 S(rence P).77 E 13.75(arr Russell)-.165 F
+(Quong)2.75 E(DLG 1.10)109.338 348 Q -.44(Wi)217.523 348 S(ll Cohen).44 E -.77
+(Te)289.584 348 S(rence P).77 E(arr)-.165 E(DLG 1.20)109.338 364 Q -.44(Wi)
+217.523 364 S(ll Cohen).44 E -.77(Te)289.584 364 S(rence P).77 E(arr)-.165 E
+(DLG 1.21)109.338 380 Q -.77(Te)217.523 380 S(rence P).77 E(arr)-.165 E
+(Semantic predicates)109.338 396 Q -.77(Te)217.523 396 S(rence P).77 E 13.75
+(arr Russell)-.165 F(Quonq)2.75 E(Syntactic predicates)109.338 412 Q -.77(Te)
+217.523 412 S(rence P).77 E 13.75(arr Russell)-.165 F(Quonq)2.75 E
+(SORCERER 1.00A)109.338 428 Q -.77(Te)217.523 428 S(rence P).77 E(arr)-.165 E
+(SORCERER 1.00B)109.338 444 Q -.77(Te)217.523 444 S(rence P).77 E 13.75
+(arr Aaron)-.165 F(Sa)2.75 E(wde)-.165 E(y)-.165 E(SORCERER 1.00B9)109.338 460
+Q -.77(Te)217.523 460 S(rence P).77 E 13.75(arr Aaron)-.165 F(Sa)2.75 E(wde)
+-.165 E 1.43 -.715(y, G)-.165 H(ary Funck).715 E 472.162 467.75 103.838 467.75
+DL 472.162 103.75 472.162 467.75 DL 103.838 103.75 103.838 467.75 DL EP
+%%Trailer
+end
+%%EOF
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.txt b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.txt
new file mode 100644
index 00000000..96d66d3c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/history.txt
@@ -0,0 +1,186 @@
+
+
+
+ The History of PCCTS
+
+ The Purdue Compiler-Construction Tool Set
+
+
+ Terence Parr
+ Parr Research Corporation
+ Minneapolis, Minnesota
+ and
+ University of Minnesota
+ Army High Performance Computing Research Center
+
+ [Updated 8-7-94]
+
+
+ The PCCTS project began as a parser-generator project for a gra-
+duate course at Purdue University in the Fall of 1988 taught by Hank
+Dietz- translator-writing systems. Under the guidance of Professor
+Dietz, the parser generator, ANTLR (originally called YUCC), continued
+after the termination of the course and eventually became the subject
+of Terence Parr's Master's thesis. Originally, lexical analysis was
+performed via ALX which was soon replaced by Will Cohen's DLG in the
+Fall of 1989 (DFA-based lexical-analyzer generator, also an offshoot
+of the graduate translation course).
+
+ The alpha version of ANTLR was totally rewritten resulting in
+1.00B. Version 1.00B was released via an internet newsgroup
+(comp.compilers) posting in February of 1990 and quickly gathered a
+large following. 1.00B generated only LL(1) parsers, but allowed the
+merged description of lexical and syntactic analysis. It had rudimen-
+tary attribute handling similar to that of YACC and did not incor-
+porate rule parameters or return values; downward inheritance was very
+awkward. 1.00B-generated parsers terminated upon the first syntax
+error. Lexical classes (modes) were not allowed and DLG did not have
+an interactive mode.
+
+ Upon starting his Ph.D. at Purdue in the Fall of 1990, Terence
+Parr began the second total rewrite of ANTLR. The method by which
+grammars may be practically analyzed to generate LL(k) lookahead
+information was discovered in August of 1990 just before his return.
+Version 1.00 incorporated this algorithm and included the AST mechan-
+ism, lexical classes, error classes, and automatic error recovery;
+code quality and portability were higher. In February of 1992 1.00
+was released via an article in SIGPLAN Notices. Peter Dahl, Ph.D.
+candidate, and Professor Matt O'Keefe (both at the University of Min-
+nesota) tested this version extensively. Dana Hoggatt (Micro Data
+Base Systems, Inc.) came up with the idea of error grouping (strings
+attached to non-terminals) and tested 1.00 heavily.
+
+ Version 1.06 was released in December 1992 and represented a
+large feature enhancement over 1.00. For example, rudimentary seman-
+tic predicates were introduced, error messages were significantly
+improved for k>1 lookahead and ANTLR parsers could indicate that loo-
+kahead fetches were to occur only when necessary for the parse
+
+
+
+ Page 1
+
+ PCCTS
+
+
+(normally, the lookahead "pipe" was constantly full). Russell Quong
+joined the project in the Spring of 1992 to aid in the semantic predi-
+cate design. Beginning and advanced tutorials were created and
+released as well. A makefile generator was included that sets up
+dependencies and such correctly for ANTLR and DLG. Very few 1.00
+incompatibilities were introduced (1.00 was quite different from 1.00B
+in some areas).
+
+ 1.10 was released on August 31, 1993 and incorporated bug fixes,
+a few feature enhancements and a major new capability - an arbitrary
+lookahead operator (syntactic predicate), (alpha)?beta. This feature
+was co-designed with Professor Russell Quong also at Purdue. To sup-
+port infinite lookahead, a preprocessor flag, ZZINF_LOOK, was created
+that forced the ANTLR() macro to tokenize all input prior to parsing.
+Hence, at any moment, an action or predicate can see the entire input
+sentence. The predicate mechanism of 1.06 was extended to allow mul-
+tiple predicates to be hoisted; the syntactic context of a predicate
+was also moved along with the predicate.
+
+ In February of 1994, SORCERER (a simple tree-parser generator)
+was released. This tool allows the user to parse child-sibling trees
+by specifying a grammar rather than building a recursive-descent tree
+walker by hand. Work towards a library of tree transformations is
+underway. Aaron Sawdey at The University of Minnesota became a second
+author of SORCERER after the initial release.
+
+ On April 1, 1994, PCCTS 1.20 was released. This was the first
+version to actively support C++ output. It also included important
+fixes regarding semantic predicates and (..)+ subrules. This version
+also introduced token classes, the "not" operator, and token ranges.
+
+ On June 19, 1994, SORCERER 1.00B9 was released. Gary Funck of
+Intrepid Technology joined the SORCERER team and provided very valu-
+able suggestions regarding the "transform" mode of SORCERER.
+
+ On August 8, 1994, PCCTS 1.21 was released. It mainly cleaned up
+the C++ output and included a number of bug fixes.
+
+ From the 1.21 release forward, the maintenance and support of all
+PCCTS tools will be primarily provided by Parr Research Corporation,
+Minneapolis MN---an organization founded on the principles of excel-
+lence in research and integrity in business; we are devoted to provid-
+ing really cool software tools. Please see file PCCTS.FUTURE for more
+information. All PCCTS tools currently in the public domain will con-
+tinue to be in the public domain.
+
+ Looking towards the future, a graphical user-interface is in the
+design phase. This would allow users to view the syntax diagram
+representation of their grammars and would highlight nondeterministic
+productions. Parsing can be traced graphically as well. This system
+will be built using a multiplatform window library. We also antici-
+pate the introduction of a sophisticated error handling mechanism
+called "parser exception handling" in a near future release.
+
+
+
+
+ Page 2
+
+ PCCTS
+
+
+ Currently, PCCTS is used at over 1000 known academic, government,
+and commercial sites in 37 countries. Of course, the true number of
+users is unknown due to the large number of ftp sites.
+ Credits
+
+_____________________________________________________________________________
+_____________________________________________________________________________
+|ANTLR 1.00A Terence Parr Hank Dietz |
+|ALX Terence Parr Hank Dietz |
+|ANTLR 1.00B Terence Parr Hank Dietz, Will Cohen |
+|DLG 1.00B Will Cohen Terence Parr, Hank Dietz |
+|NFA Relabelling Will Cohen |
+|LL(k) analysis Terence Parr Hank Dietz |
+|ANTLR 1.00 Terence Parr Hank Dietz, Will Cohen |
+|DLG 1.00 Will Cohen Terence Parr, Hank Dietz |
+|ANTLR 1.06 Terence Parr Will Cohen, Russell Quong, Hank Dietz|
+|DLG 1.06 Will Cohen Terence Parr, Hank Dietz |
+|ANTLR 1.10 Terence Parr Will Cohen, Russell Quong |
+|ANTLR 1.20 Terence Parr Will Cohen, Russell Quong |
+|ANTLR 1.21 Terence Parr Russell Quong |
+|DLG 1.10 Will Cohen Terence Parr |
+|DLG 1.20 Will Cohen Terence Parr |
+|DLG 1.21 Terence Parr |
+|Semantic predicates Terence Parr Russell Quonq |
+|Syntactic predicates Terence Parr Russell Quonq |
+|SORCERER 1.00A Terence Parr |
+|SORCERER 1.00B Terence Parr Aaron Sawdey |
+|SORCERER 1.00B9 Terence Parr Aaron Sawdey, Gary Funck |
+|___________________________________________________________________________|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page 3
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/makefile.old b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/makefile.old
new file mode 100644
index 00000000..d8f7f6f7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/makefile.old
@@ -0,0 +1,66 @@
+#
+# Main makefile for PCCTS 1.33MR33 /* MRXXX */
+#
+# Terence Parr
+# Parr Research Corporation
+#
+# verbosity versus silence...
+PSss=
+#
+# this can be set to /user/local/bin etc...
+BINDIR=bin
+# This part added by Thomas Herter, M"unchen, Germany. See also manpages
+# target.
+MANDIR=$(HOME)/man
+MANEXT=1
+MANFILES=dlg/dlg.1 antlr/antlr.1
+
+#CC=cc
+#CC=gcc
+#COPT=-O2
+
+pccts:
+ @echo " "
+ @echo " Welcome to PCCTS 1.33MR33 installation"
+ @echo " "
+ @echo " (Version 1.33 Maintenance Release #33)" # mrxxx
+ @echo " "
+ @echo " Released 19 April 2002"
+ @echo " "
+ @echo " Featuring"
+ @echo " ANTLR -- ANother Tool for Language Recognition"
+ @echo " DLG -- DFA-based Lexical Analyzer Generator"
+ @echo " SORCERER -- Source-to-source translator (tree walker)"
+ @echo " "
+ @echo " http://www.antlr.org"
+ @echo " "
+ @echo " Trouble reports to tmoog@polhode.com"
+ @echo " Additional PCCTS 1.33 information at"
+ @echo " http://www.polhode.com"
+ @echo
+ @echo
+ @echo "To substitute gcc for CC to invoke compiler: make CC=gcc"
+ @echo "If there are problems with cr and lf try: unzip -a ..."
+ @echo
+#
+ @if [ ! -d $(BINDIR) ] ; then mkdir $(BINDIR) ; fi
+ @echo Making executables...
+ (cd ./antlr; $(MAKE) CC="$(CC)" COPT="$(COPT)")
+ @echo antlr executable now in $(BINDIR)
+ (cd ./dlg; $(MAKE) CC="$(CC)" COPT="$(COPT)")
+ @echo dlg executable now in $(BINDIR)
+ @echo
+ @echo " PCCTS 1.33MR33 installation complete" # MRXXX
+
+clean:
+ (cd ./antlr; $(MAKE) -s clean)
+ (cd ./dlg; $(MAKE) -s clean)
+
+
+manpages:
+ # mkdir -p $(MANDIR)/man$(MANEXT)
+ if [ ! -d $(MANDIR) ] ; then \
+ mkdir $(MANDIR) ; fi
+ if [ ! -d $(MANDIR)/man$(MANEXT) ] ; then \
+ mkdir $(MANDIR)/man$(MANEXT); fi
+ cp -p $(MANFILES) $(MANDIR)/man$(MANEXT)
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk.c
new file mode 100644
index 00000000..800a1121
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk.c
@@ -0,0 +1,1063 @@
+/*
+ * genmk -- a program to make makefiles for PCCTS
+ *
+ * ANTLR 1.33MR23
+ * Terence John Parr 1989 - 2000
+ * Purdue University
+ * U of MN
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */
+
+#ifdef VAXC
+#define DIE return 0;
+#define DONE return 1;
+#else
+#define DIE return 1;
+#define DONE return 0;
+#endif
+
+#ifndef require
+#define require(expr, err) {if ( !(expr) ) fatal(err);}
+#endif
+
+#define MAX_FILES 50
+#define MAX_CFILES 1600
+#define MAX_SFILES 50
+#define MAX_SORS 50
+#define MAX_CLASSES 50
+
+char *RENAME_OBJ_FLAG="-o",
+ *RENAME_EXE_FLAG="-o";
+
+char *dlg = "parser.dlg";
+char *err = "err.c";
+char *hdr = "stdpccts.h";
+char *tok = "tokens.h";
+char *mode = "mode.h";
+char *scan = "scan";
+
+char ATOKENBUFFER_O[100];
+char APARSER_O[100];
+char ASTBASE_O[100];
+char PCCTSAST_O[100];
+char LIST_O[100];
+char DLEXERBASE_O[100];
+
+/* Option flags */
+static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];
+static char *cfiles[MAX_CFILES];
+static char *sfiles[MAX_SORS][MAX_SFILES],*sclasses[MAX_SORS];
+static int num_sfiles[MAX_SORS]; /*sorcerer files in group */
+static int num_sors = 0; /*sorcerer groups */
+static int num_files = 0; /* grammar files */
+static int num_cfiles = 0; /* additional C/C++ files */
+static int num_classes = 0; /* ANTLR classes */
+static int user_lexer = 0;
+static char *user_token_types = NULL;
+static int gen_CPP = 0;
+static char *outdir=".";
+static char *dlg_class = "DLGLexer";
+static int gen_trees = 0;
+static int gen_hoist = 0;
+static int nondef_comp = 0; /* 1=compiler is non default */
+static char *compilerCCC="CC";
+static char *compilerCC="cc";
+static char *pccts_path="/usr/local/pccts";
+
+#ifdef __STDC__
+void help(void);
+void mk(char *project, char **files, int n, int argc, char **argv);
+void pfiles(char **files, int n, char *suffix);
+void fatal(char *msg);
+void warn(char *msg);
+#else
+void help();
+void mk();
+void pfiles();
+void fatal();
+void warn();
+#endif
+
+typedef struct _Opt {
+ char *option;
+ int arg;
+#ifdef __cplusplus
+ void (*process)(...);
+#else
+ void (*process)();
+#endif
+ char *descr;
+ } Opt;
+
+#ifdef __STDC__
+static void ProcessArgs(int, char **, Opt *);
+#else
+static void ProcessArgs();
+#endif
+
+static void
+#ifdef __STDC__
+pProj(char *s, char *t )
+#else
+pProj( s, t )
+char *s;
+char *t;
+#endif
+{
+ project = t;
+}
+
+static void
+#ifdef __STDC__
+pUL( char *s )
+#else
+pUL( s )
+char *s;
+#endif
+{
+ user_lexer = 1;
+}
+
+static void
+#ifdef __STDC__
+pCPP( char *s )
+#else
+pCPP( s )
+char *s;
+#endif
+{
+ gen_CPP = 1;
+}
+
+static void
+#ifdef __STDC__
+pUT( char *s, char *t )
+#else
+pUT( s, t )
+char *s;
+char *t;
+#endif
+{
+ user_token_types = t;
+}
+
+static void
+#ifdef __STDC__
+pTrees( char *s )
+#else
+pTrees( s )
+char *s;
+#endif
+{
+ gen_trees = 1;
+}
+
+static void
+#ifdef __STDC__
+pHoist( char *s )
+#else
+pHoist( s )
+char *s;
+#endif
+{
+ gen_hoist = 1;
+}
+
+static void
+#ifdef __STDC__
+pSor( char *s )
+#else
+pSor( s )
+char *s;
+#endif
+{
+ require(num_sors<MAX_SORS, "exceeded max # of sorcerer groups");
+ num_sors++;
+ pTrees(NULL); /* silently turn on tree generation */
+}
+
+static void
+#ifdef __STDC__
+pSFiles( char *s, char *t )
+#else
+pSFiles( s, t )
+char *s;
+char *t;
+#endif
+{
+ if (num_sors==0)
+ {
+ pSor(NULL);
+ warn("sorcerer input file before any '-sor' option");
+ }
+
+ require(num_sfiles[num_sors-1]<MAX_SFILES,
+ "exceeded max # of sorcerer input files");
+ sfiles[num_sors-1][num_sfiles[num_sors-1]++] = t;
+}
+
+static void
+#ifdef __STDC__
+pCFiles( char *s, char *t )
+#else
+pCFiles( s, t )
+char *s;
+char *t;
+#endif
+{
+ require(num_cfiles<MAX_CFILES, "exceeded max # of C/C++ input files");
+ cfiles[num_cfiles++] = t;
+}
+
+int
+#ifdef __STDC__
+isKnownSuffix( char *s )
+#else
+isKnownSuffix( s )
+ char *s;
+#endif
+{
+ if(s==NULL) return 0;
+ if (strcasecmp(s,".c")==0) return 1;
+ if (strcasecmp(s,".cc")==0) return 1;
+ if (strcasecmp(s,".cpp")==0) return 1;
+ if (strcasecmp(s,".cxx")==0) return 1;
+ if (strcasecmp(s,CPP_FILE_SUFFIX)==0) return 1;
+ if (strcasecmp(s,".sor")==0) return 2;
+ return 0;
+}
+
+static void
+#ifdef __STDC__
+pFile( char *s )
+#else
+pFile( s )
+char *s;
+#endif
+{
+ if ( *s=='-' )
+ {
+ fprintf(stderr, "invalid option: '%s'; ignored...",s);
+ return;
+ }
+ switch(isKnownSuffix(strrchr(s,'.')))
+ {
+ case 1: /* c/c++ */
+ pCFiles("-cfiles",s);
+ return;
+ case 2: /* sorcerer */
+ pSFiles("",s);
+ return;
+ default: /* grammar (ANTLR) */
+ break;
+ }
+ require(num_files<MAX_FILES, "exceeded max # of input files");
+ files[num_files++] = s;
+}
+
+static void
+#ifdef __STDC__
+pClass( char *s, char *t )
+#else
+pClass( s, t )
+char *s;
+char *t;
+#endif
+{
+ if (num_sors==0)
+ {
+ require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");
+ classes[num_classes++] = t;
+ } else
+ {
+ sclasses[num_sors-1] = t; /* one class per sorcerer group (last valid) */
+ }
+}
+
+static void
+#ifdef __STDC__
+pDLGClass( char *s, char *t )
+#else
+pDLGClass( s, t )
+char *s;
+char *t;
+#endif
+{
+ if ( !gen_CPP ) {
+ fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");
+ }
+ else dlg_class = t;
+}
+
+static void
+#ifdef __STDC__
+pOdir( char *s, char *t )
+#else
+pOdir( s, t )
+char *s;
+char *t;
+#endif
+{
+ outdir = t;
+}
+
+static void
+#ifdef __STDC__
+pHdr( char *s, char *t )
+#else
+pHdr( s, t )
+char *s;
+char *t;
+#endif
+{
+ hdr = t;
+}
+
+static void
+#ifdef __STDC__
+pCompiler( char *s, char *t )
+#else
+pCompiler( s, t )
+char *s;
+char *t;
+#endif
+{
+ compilerCCC = t;
+ compilerCC = t;
+ nondef_comp = 1;
+}
+
+static void
+#ifdef __STDC__
+ppccts_path( char *s, char *t )
+#else
+ppccts_path( s, t )
+char *s;
+char *t;
+#endif
+{
+ pccts_path = t;
+}
+
+Opt options[] = {
+ { "-CC", 0, pCPP, "Generate C++ output"},
+ { "-class", 1, pClass, "Name of a grammar class defined in grammar (if C++)"},
+ { "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},
+ { "-header", 1,pHdr, "Name of ANTLR standard header info (default=no file)"},
+ { "-o", 1, pOdir, "Directory where output files should go (default=\".\")"},
+ { "-project", 1, pProj, "Name of executable to create (default=t)"},
+ { "-token-types", 1, pUT, "Token types are in this file (don't use tokens.h)"},
+ { "-trees", 0, pTrees, "Generate ASTs"},
+ { "-user-lexer", 0, pUL, "Do not create a DLG-based scanner"},
+ { "-mrhoist",0,pHoist, "Maintenance release style hoisting"},
+ { "-cfiles",1,pCFiles, "Additional files in C or C++ to compile"},
+ { "-sor",0,pSor, "Start of sorcerer group"},
+ { "-pccts_path",1,ppccts_path,
+ "Path for $PCCTS directory (default is /usr/local/pccts)"},
+ { "-compiler",1,pCompiler,
+ "Default compiler (default is CC/cc)"},
+ { "*", 0,pFile, "" }, /* anything else is a file */
+ { NULL, 0, NULL, NULL }
+};
+
+#ifdef __STDC__
+extern char *DIR(void);
+#else
+extern char *DIR();
+#endif
+
+#ifdef __STDC__
+int main(int argc, char **argv)
+#else
+int main(argc, argv)
+int argc;
+char **argv;
+#endif
+{
+ int i;
+
+ if ( argc == 1 ) { help(); DIE; }
+ for(i=0;i<MAX_SORS;i++) num_sfiles[i]=0;
+
+ ProcessArgs(argc-1, &(argv[1]), options);
+
+ strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);
+ ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);
+ strcpy(APARSER_O, APARSER_C);
+ APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(APARSER_O, OBJ_FILE_SUFFIX);
+
+ strcpy(ASTBASE_O, ASTBASE_C);
+ ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(ASTBASE_O, OBJ_FILE_SUFFIX);
+
+ strcpy(PCCTSAST_O, PCCTSAST_C);
+ PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);
+
+ strcpy(LIST_O, LIST_C);
+ LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(LIST_O, OBJ_FILE_SUFFIX);
+
+ strcpy(DLEXERBASE_O, DLEXERBASE_C);
+ DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);
+
+ if ( num_files == 0 ) fatal("no grammar files specified; exiting...");
+ if ( !gen_CPP && num_classes>0 ) {
+ warn("can't define classes w/o C++ mode; turning on C++ mode...\n");
+ gen_CPP=1;
+ }
+ if (!gen_CPP && num_sors) {
+ warn("can't define sorcerer group in C mode (yet); turning on C++ mode...\n");
+ gen_CPP=1;
+ }
+ if ( gen_CPP && num_classes==0 ) {
+ fatal("must define classes >0 grammar classes in C++ mode\n");
+ }
+
+ mk(project, files, num_files, argc, argv);
+ DONE;
+}
+
+#ifdef __STDC__
+void help(void)
+#else
+void help()
+#endif
+{
+ Opt *p = options;
+ static char buf[1000+1];
+
+ fprintf(stderr, "genmk [options] f1.g ... fn.g\n");
+ while ( p->option!=NULL && *(p->option) != '*' )
+ {
+ buf[0]='\0';
+ if ( p->arg ) sprintf(buf, "%s ___", p->option);
+ else strcpy(buf, p->option);
+ fprintf(stderr, "\t%-16s %s\n", buf, p->descr);
+ p++;
+ }
+}
+
+#ifdef __STDC__
+void mk(char *project, char **files, int n, int argc, char **argv)
+#else
+void mk(project, files, n, argc, argv)
+char *project;
+char **files;
+int n;
+int argc;
+char **argv;
+#endif
+{
+ int i,j;
+
+ printf("#\n");
+ printf("# PCCTS makefile for: ");
+ pfiles(files, n, NULL);
+ printf("\n");
+ printf("#\n");
+ printf("# Created from:");
+ for (i=0; i<argc; i++) printf(" %s", argv[i]);
+ printf("\n");
+ printf("#\n");
+ printf("# PCCTS release 1.33MR23\n");
+ printf("# Project: %s\n", project);
+ if ( gen_CPP ) printf("# C++ output\n");
+ else printf("# C output\n");
+ if ( user_lexer ) printf("# User-defined scanner\n");
+ else printf("# DLG scanner\n");
+ if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);
+ else printf("# ANTLR-defined token types\n");
+ printf("#\n");
+/***********
+ printf(".SUFFIXES:\n.SUFFIXES:\t.o .cpp .c .h .g .i .dlg .sor\n");
+ ***********/
+ if ( user_token_types!=NULL ) {
+ printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");
+ printf("TOKENS = %s", user_token_types);
+ }
+ else printf("TOKENS = %stokens.h", DIR());
+ printf("\n");
+ printf("#\n");
+ printf("# The following filenames must be consistent with ANTLR/DLG flags\n");
+ printf("DLG_FILE = %s%s\n", DIR(), dlg);
+ printf("ERR = %serr\n", DIR());
+ if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);
+ else printf("HDR_FILE =\n");
+ if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);
+ if ( !gen_CPP ) printf("SCAN = %s\n", scan);
+ else printf("SCAN = %s%s\n", DIR(), dlg_class);
+
+ printf("PCCTS = %s\n",pccts_path);
+ printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);
+ if (num_sors>0) {
+ printf("SOR_H = $(PCCTS)%ssorcerer%sh\n", DirectorySymbol, DirectorySymbol);
+ printf("SOR_LIB = $(PCCTS)%ssorcerer%slib\n",
+ DirectorySymbol, DirectorySymbol);
+ }
+ printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);
+ printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);
+ printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);
+ if (num_sors>0) printf("SOR = $(BIN)%ssor\n", DirectorySymbol);
+ printf("CFLAGS = -I. -I$(ANTLR_H)");
+ if (num_sors>0) printf(" -I$(SOR_H)");
+ if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);
+ printf(" $(COTHER)");
+ printf("\n");
+ printf("AFLAGS =");
+ if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
+ if ( user_lexer ) printf(" -gx");
+ if ( gen_CPP ) printf(" -CC");
+ if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);
+ if ( gen_trees ) printf(" -gt");
+ if ( gen_hoist ) {
+ printf(" -mrhoist on") ;
+ } else {
+ printf(" -mrhoist off");
+ };
+ printf(" $(AOTHER)");
+ printf("\n");
+ printf("DFLAGS = -C2 -i");
+ if ( gen_CPP ) printf(" -CC");
+ if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);
+ if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
+ printf(" $(DOTHER)");
+ printf("\n");
+ if (num_sors>0)
+ {
+ printf("SFLAGS = -CPP");
+ if ( strcmp(outdir,".")!=0 ) printf(" -out-dir %s", outdir);
+ printf(" $(SOTHER)\n");
+ }
+ printf("GRM = ");
+ pfiles(files, n, NULL);
+ printf("\n");
+ printf("SRC = ");
+ if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(files, n, "c");
+ if ( gen_CPP ) {
+ printf(" \\\n\t");
+ pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" \\\n\t");
+ printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);
+ if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);
+ if ( gen_trees ) {
+ printf(" \\\n\t");
+ printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);
+ printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C);
+/* printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */
+ printf(" \\\n\t");
+ }
+ printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);
+ }
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);
+ else printf(" %s$(SCAN).c", DIR());
+ }
+ if ( !gen_CPP ) printf(" $(ERR).c");
+ for (i=0;i<num_sors;i++)
+ {
+ printf(" \\\n\t");
+ pclasses(&sclasses[i],1,CPP_FILE_SUFFIX_NO_DOT);
+ printf(" ");
+ pfiles(&sfiles[i][0],num_sfiles[i],CPP_FILE_SUFFIX_NO_DOT);
+ }
+ if(num_sors>0)
+ printf(" \\\n\t$(SOR_LIB)%sSTreeParser.cpp", DirectorySymbol);
+ if (num_cfiles>0)
+ {
+ printf(" \\\n\t");
+ pfiles(cfiles,num_cfiles,NULL);
+ }
+ printf("\n\n");
+ printf("OBJ = ");
+ pfiles(files, n, "o");
+ if ( gen_CPP ) {
+ printf(" \\\n\t");
+ pclasses(classes, num_classes, "o");
+ printf(" \\\n\t");
+ printf("%s%s", DIR(), APARSER_O);
+ if ( !user_lexer ) {
+ printf(" %s%s", DIR(), DLEXERBASE_O);
+ }
+ if ( gen_trees ) {
+ printf(" \\\n\t");
+ printf("%s%s", DIR(), ASTBASE_O);
+ printf(" %s%s", DIR(), PCCTSAST_O);
+/* printf(" %s%s", DIR(), LIST_O); */
+ printf(" \\\n\t");
+ }
+ printf(" %s%s", DIR(), ATOKENBUFFER_O);
+ }
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX);
+ else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX);
+ }
+ if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX);
+ for (i=0;i<num_sors;i++)
+ {
+ printf(" \\\n\t");
+ pclasses(&sclasses[i],1,"o");
+ printf(" ");
+ pfiles(&sfiles[i][0],num_sfiles[i],"o");
+ }
+ if(num_sors>0) printf(" \\\n\tSTreeParser.o");
+ if (num_cfiles>0)
+ {
+ printf(" \\\n\t");
+ pfiles(cfiles,num_cfiles,"o");
+ }
+ printf("\n\n");
+
+ printf("ANTLR_SPAWN = ");
+ if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(files, n, "c");
+ if ( gen_CPP ) {
+ printf(" ");
+ pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" \\\n\t\t");
+ pclasses(classes, num_classes, "h");
+ if ( strcmp(hdr,"stdpccts.h")!=0 ) {
+ printf(" \\\n\t\t");
+ printf("$(HDR_FILE) stdpccts.h");
+ }
+ }
+ if ( user_lexer ) {
+ if ( !user_token_types ) printf(" $(TOKENS)");
+ }
+ else {
+ printf(" $(DLG_FILE)");
+ if ( !user_token_types ) printf(" $(TOKENS)");
+ }
+ if ( !gen_CPP ) printf(" $(ERR).c");
+ printf("\n");
+
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);
+ else printf("DLG_SPAWN = %s$(SCAN).c", DIR());
+ if ( gen_CPP ) printf(" $(SCAN).h");
+ if ( !gen_CPP ) printf(" $(MOD_FILE)");
+ printf("\n");
+ }
+
+ if ( gen_CPP ) {
+ if ( !nondef_comp )
+ printf("ifdef CXX\nCCC = $(CXX)\nendif\n\nifndef CCC\n");
+ printf("CCC = %s\n",compilerCCC);
+ if ( !nondef_comp ) printf("endif\n\n");
+ }
+ else
+ {
+ if ( !nondef_comp ) printf("ifndef CC\n");
+ printf("CC = %s\n",compilerCC);
+ if ( !nondef_comp ) printf("endif\n\n");
+ }
+
+ /* set up dependencies */
+ printf("\n%s : $(SRC) $(OBJ)\n", project);
+ printf("\t%s %s %s $(CFLAGS) $(OBJ)\n",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_EXE_FLAG,
+ project);
+ printf("\n");
+
+ /* implicit rules */
+
+/* if(gen_CPP)
+ printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n");
+
+ printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n",
+ gen_CPP?"$(CCC)":"$(CC)");
+*/
+ /* how to compile parser files */
+
+ for (i=0; i<num_files; i++)
+ {
+ pfiles(&files[i], 1, "o");
+ if ( user_lexer ) {
+ printf(" : $(TOKENS)");
+ }
+ else {
+ if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");
+ else printf(" : $(MOD_FILE) $(TOKENS)");
+ }
+ printf(" ");
+ if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&files[i], 1, "c");
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+ printf("\n");
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ pfiles(&files[i], 1, "o");
+ printf(" ");
+ if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&files[i], 1, "c");
+ printf("\n\n");
+ }
+
+ for (i=0; i<num_cfiles; i++)
+ {
+ pfiles(&cfiles[i], 1, "o");
+ printf(" : ");
+ pfiles(&cfiles[i], 1, NULL);
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+/*** printf(" "); ***/
+/*** pfiles(&cfiles[i], 1, "h"); ***/
+ printf("\n");
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ pfiles(&cfiles[i], 1, "o");
+ printf(" ");
+ pfiles(&cfiles[i], 1, NULL);
+ printf("\n\n");
+
+/*
+ * pfiles(&cfiles[i], 1, "h");
+ * printf(" :\ntouch ");
+ * pfiles(&cfiles[i], 1, "h");
+ * printf("\n\n");
+ */
+ }
+
+ /* how to compile err.c */
+ if ( !gen_CPP ) {
+ printf("$(ERR)%s : $(ERR).c", OBJ_FILE_SUFFIX);
+ if ( !user_lexer ) printf(" $(TOKENS)");
+ printf("\n");
+ printf("\t%s -c $(CFLAGS) %s $(ERR)%s $(ERR).c",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG,
+ OBJ_FILE_SUFFIX);
+ printf("\n\n");
+ }
+
+ /* how to compile Class.c */
+ for (i=0; i<num_classes; i++)
+ {
+ pclasses(&classes[i], 1, "o");
+ if ( user_lexer ) {
+ printf(" : $(TOKENS)");
+ }
+ else {
+ printf(" : $(TOKENS) $(SCAN).h");
+ }
+ printf(" ");
+ pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" ");
+ pclasses(&classes[i], 1, "h");
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+ printf("\n");
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ pclasses(&classes[i], 1, "o");
+ printf(" ");
+ pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf("\n\n");
+ }
+
+ /* how to compile scan.c */
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf("$(SCAN)%s : $(SCAN)%s", OBJ_FILE_SUFFIX, CPP_FILE_SUFFIX);
+ else printf("%s$(SCAN)%s : %s$(SCAN).c", DIR(), OBJ_FILE_SUFFIX, DIR());
+ if ( !user_lexer ) printf(" $(TOKENS)");
+ printf("\n");
+ if ( gen_CPP ) printf("\t$(CCC) -c $(CFLAGS) %s $(SCAN)%s $(SCAN)%s",
+ RENAME_OBJ_FLAG,
+ OBJ_FILE_SUFFIX,
+ CPP_FILE_SUFFIX);
+ else printf("\t$(CC) -c $(CFLAGS) %s %s$(SCAN)%s %s$(SCAN).c",
+ RENAME_OBJ_FLAG,
+ DIR(),
+ OBJ_FILE_SUFFIX,
+ DIR());
+ printf("\n\n");
+ }
+/* how to compile sorcerer classes */
+ for (i=0;i<num_sors;i++)
+ {
+ pclasses(&sclasses[i], 1, "o");
+ printf(" : ");
+ pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" ");
+ pclasses(&sclasses[i], 1, "h");
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+ printf("\n");
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ pclasses(&sclasses[i], 1, "o");
+ printf(" ");
+ pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf("\n\n");
+/* how to compile i-th sorcerer's files*/
+ for (j=0; j<num_sfiles[i]; j++)
+ {
+ pfiles(&sfiles[i][j], 1, "o");
+ printf(" : ");
+ if ( gen_CPP ) pfiles(&sfiles[i][j], 1, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&sfiles[i][j], 1, "c");
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+ printf("\n");
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ pfiles(&sfiles[i][j], 1, "o");
+ printf(" ");
+ if ( gen_CPP ) pfiles(&sfiles[i][j], 1, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&sfiles[i][j], 1, "c");
+ printf("\n\n");
+ }
+ if ( gen_CPP ) pfiles(&sfiles[i][0], num_sfiles[i], CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&sfiles[i][0], num_sfiles[i], "c");
+ if ( gen_CPP )
+ {
+ printf(" ");
+ pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" ");
+ pclasses(&sclasses[i], 1, "h");
+ if ( strcmp(hdr,"stdpccts.h")!=0 )
+ {
+ printf(" ");
+ printf("$(HDR_FILE) stdpccts.h");
+ }
+ }
+ printf(" : ");
+ pfiles(&sfiles[i][0],num_sfiles[i],NULL);
+ printf("\n\t$(SOR) $(SFLAGS) ");
+ pfiles(&sfiles[i][0],num_sfiles[i],NULL);
+ printf("\n\n");
+ }
+ if(num_sors>0)
+ {
+ printf("STreeParser%s : $(SOR_LIB)%sSTreeParser.cpp\n",
+ OBJ_FILE_SUFFIX,DirectorySymbol);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ printf("STreeParser%s ",OBJ_FILE_SUFFIX);
+ printf("$(SOR_LIB)%sSTreeParser.cpp\n\n",DirectorySymbol);
+ }
+
+ printf("$(ANTLR_SPAWN) : $(GRM)\n");
+ printf("\t$(ANTLR) $(AFLAGS) $(GRM)\n");
+
+ if ( !user_lexer )
+ {
+ printf("\n");
+ printf("$(DLG_SPAWN) : $(DLG_FILE)\n");
+ if ( gen_CPP ) printf("\t$(DLG) $(DFLAGS) $(DLG_FILE)\n");
+ else printf("\t$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");
+ }
+
+ /* do the makes for ANTLR/DLG support */
+ if ( gen_CPP ) {
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
+ if ( !user_lexer ) {
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
+ }
+ if ( gen_trees ) {
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
+ printf("\n");
+/*
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
+ printf("\t%s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
+*/
+ }
+ }
+
+ /* clean and scrub targets */
+
+ printf("\nclean:\n");
+ printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project);
+ if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);
+ printf("\n");
+
+ printf("\nscrub: clean\n");
+/* printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); */
+/* if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); */
+ printf("\trm -f $(ANTLR_SPAWN)");
+ if ( !user_lexer ) printf(" $(DLG_SPAWN)");
+ for (i=0;i<num_sors;i++)
+ {
+ printf(" ");
+ if ( gen_CPP ) pfiles(&sfiles[i][0], num_sfiles[i], CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&sfiles[i][0], num_sfiles[i], "c");
+ if ( gen_CPP )
+ {
+ printf(" ");
+ pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" ");
+ pclasses(&sclasses[i], 1, "h");
+ }
+ }
+ printf("\n\n");
+}
+
+#ifdef __STDC__
+void pfiles(char **files, int n, char *suffix)
+#else
+void pfiles(files, n, suffix)
+char **files;
+int n;
+char *suffix;
+#endif
+{
+ int first=1;
+
+ while ( n>0 )
+ {
+ char *p = &(*files)[strlen(*files)-1];
+ if ( !first ) putchar(' ');
+ first=0;
+ while ( p > *files && *p != '.' ) --p;
+ if ( p == *files )
+ {
+ fprintf(stderr,
+ "genmk: filenames must be file.suffix format: %s\n",
+ *files);
+ exit(-1);
+ }
+ if ( suffix == NULL ) printf("%s", *files);
+ else
+ {
+ *p = '\0';
+ printf("%s", DIR());
+ if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX);
+ else printf("%s.%s", *files, suffix);
+ *p = '.';
+ }
+ files++;
+ --n;
+ }
+}
+
+#ifdef __STDC__
+pclasses(char **classes, int n, char *suffix)
+#else
+pclasses(classes, n, suffix)
+char **classes;
+int n;
+char *suffix;
+#endif
+{
+ int first=1;
+
+ while ( n>0 )
+ {
+ if ( !first ) putchar(' ');
+ first=0;
+ if ( suffix == NULL ) printf("%s", *classes);
+ else {
+ printf("%s", DIR());
+ if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX);
+ else printf("%s.%s", *classes, suffix);
+ }
+ classes++;
+ --n;
+ }
+}
+
+static void
+#ifdef __STDC__
+ProcessArgs( int argc, char **argv, Opt *options )
+#else
+ProcessArgs( argc, argv, options )
+int argc;
+char **argv;
+Opt *options;
+#endif
+{
+ Opt *p;
+ require(argv!=NULL, "ProcessArgs: command line NULL");
+
+ while ( argc-- > 0 )
+ {
+ p = options;
+ while ( p->option != NULL )
+ {
+ if ( strcmp(p->option, "*") == 0 ||
+ strcmp(p->option, *argv) == 0 )
+ {
+ if ( p->arg )
+ {
+ (*p->process)( *argv, *(argv+1) );
+ argv++;
+ argc--;
+ }
+ else
+ (*p->process)( *argv );
+ break;
+ }
+ p++;
+ }
+ argv++;
+ }
+}
+
+#ifdef __STDC__
+void fatal( char *err_)
+#else
+void fatal( err_)
+char *err_;
+#endif
+{
+ fprintf(stderr, "genmk: %s\n", err_);
+ exit(1);
+}
+
+#ifdef __STDC__
+void warn( char *err_)
+#else
+void warn( err_)
+char *err_;
+#endif
+{
+ fprintf(stderr, "genmk: %s\n", err_);
+}
+
+#ifdef __STDC__
+char *DIR(void)
+#else
+char *DIR()
+#endif
+{
+ static char buf[200+1];
+
+ if ( strcmp(outdir,TopDirectory)==0 ) return "";
+ sprintf(buf, "%s%s", outdir, DirectorySymbol);
+ return buf;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk_old.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk_old.c
new file mode 100644
index 00000000..19858cb6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/genmk_old.c
@@ -0,0 +1,762 @@
+/*
+ * genmk -- a program to make makefiles for PCCTS
+ *
+ * ANTLR 1.33MR10
+ * Terence John Parr 1989 - 1998
+ * Purdue University
+ * U of MN
+ */
+
+#include <stdio.h>
+#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */
+
+#ifdef VAXC
+#define DIE return 0;
+#define DONE return 1;
+#else
+#define DIE return 1;
+#define DONE return 0;
+#endif
+
+#ifndef require
+#define require(expr, err) {if ( !(expr) ) fatal(err);}
+#endif
+
+#define MAX_FILES 50
+#define MAX_CLASSES 50
+
+char *RENAME_OBJ_FLAG="-o",
+ *RENAME_EXE_FLAG="-o";
+
+char *dlg = "parser.dlg";
+char *err = "err.c";
+char *hdr = "stdpccts.h";
+char *tok = "tokens.h";
+char *mode = "mode.h";
+char *scan = "scan";
+
+char ATOKENBUFFER_O[100];
+char APARSER_O[100];
+char ASTBASE_O[100];
+char PCCTSAST_O[100];
+char LIST_O[100];
+char DLEXERBASE_O[100];
+
+/* Option flags */
+static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];
+static int num_files = 0;
+static int num_classes = 0;
+static int user_lexer = 0;
+static char *user_token_types = NULL;
+static int gen_CPP = 0;
+static char *outdir=".";
+static char *dlg_class = "DLGLexer";
+static int gen_trees = 0;
+static int gen_hoist = 0;
+static char cfiles[1600]="";
+static char *compilerCCC="CC";
+static char *compilerCC="cc";
+static char *pccts_path="/usr/local/pccts";
+
+void help();
+void mk();
+void pfiles();
+void pclasses();
+void fatal();
+void warn();
+
+typedef struct _Opt {
+ char *option;
+ int arg;
+#ifdef __cplusplus
+ void (*process)(...);
+#else
+ void (*process)();
+#endif
+ char *descr;
+ } Opt;
+
+#ifdef __STDC__
+static void ProcessArgs(int, char **, Opt *);
+#else
+static void ProcessArgs();
+#endif
+
+static void
+pProj( s, t )
+char *s;
+char *t;
+{
+ project = t;
+}
+
+static void
+pUL( s )
+char *s;
+{
+ user_lexer = 1;
+}
+
+static void
+pCPP( s )
+char *s;
+{
+ gen_CPP = 1;
+}
+
+static void
+pUT( s, t )
+char *s;
+char *t;
+{
+ user_token_types = t;
+}
+
+static void
+pTrees( s )
+char *s;
+{
+ gen_trees = 1;
+}
+
+static void
+pHoist( s )
+char *s;
+{
+ gen_hoist = 1;
+}
+
+static void
+#ifdef __STDC__
+pFile( char *s )
+#else
+pFile( s )
+char *s;
+#endif
+{
+ if ( *s=='-' )
+ {
+ fprintf(stderr, "invalid option: '%s'; ignored...",s);
+ return;
+ }
+
+ require(num_files<MAX_FILES, "exceeded max # of input files");
+ files[num_files++] = s;
+}
+
+static void
+#ifdef __STDC__
+pClass( char *s, char *t )
+#else
+pClass( s, t )
+char *s;
+char *t;
+#endif
+{
+ require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");
+ classes[num_classes++] = t;
+}
+
+static void
+#ifdef __STDC__
+pDLGClass( char *s, char *t )
+#else
+pDLGClass( s, t )
+char *s;
+char *t;
+#endif
+{
+ if ( !gen_CPP ) {
+ fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");
+ }
+ else dlg_class = t;
+}
+
+static void
+#ifdef __STDC__
+pOdir( char *s, char *t )
+#else
+pOdir( s, t )
+char *s;
+char *t;
+#endif
+{
+ outdir = t;
+}
+
+static void
+#ifdef __STDC__
+pHdr( char *s, char *t )
+#else
+pHdr( s, t )
+char *s;
+char *t;
+#endif
+{
+ hdr = t;
+}
+
+static void
+#ifdef __STDC__
+pCFiles( char *s, char *t )
+#else
+pCFiles( s, t )
+char *s;
+char *t;
+#endif
+{
+ strcat(strcat(cfiles," "), t);
+}
+
+static void
+#ifdef __STDC__
+pCompiler( char *s, char *t )
+#else
+pCompiler( s, t )
+char *s;
+char *t;
+#endif
+{
+ compilerCCC = t;
+ compilerCC = t;
+}
+
+static void
+#ifdef __STDC__
+ppccts_path( char *s, char *t )
+#else
+ppccts_path( s, t )
+char *s;
+char *t;
+#endif
+{
+ pccts_path = t;
+}
+
+Opt options[] = {
+ { "-CC", 0, pCPP, "Generate C++ output"},
+ { "-class", 1, pClass, "Name of a grammar class defined in grammar (if C++)"},
+ { "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},
+ { "-header", 1,pHdr, "Name of ANTLR standard header info (default=no file)"},
+ { "-o", 1, pOdir, "Directory where output files should go (default=\".\")"},
+ { "-project", 1, pProj, "Name of executable to create (default=t)"},
+ { "-token-types", 1, pUT, "Token types are in this file (don't use tokens.h)"},
+ { "-trees", 0, pTrees, "Generate ASTs"},
+ { "-user-lexer", 0, pUL, "Do not create a DLG-based scanner"},
+ { "-mrhoist",0,pHoist, "Maintenance release style hoisting"},
+ { "-cfiles",1,pCFiles, "Additional files in C or C++ to compile"},
+ { "-pccts_path",1,ppccts_path,
+ "Path for $PCCTS directory (default is /usr/local/pccts)"},
+ { "-compiler",1,pCompiler,
+ "Default compiler (default is CC/cc)"},
+ { "*", 0,pFile, "" }, /* anything else is a file */
+ { NULL, 0, NULL, NULL }
+};
+
+extern char *DIR();
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ if ( argc == 1 ) { help(); DIE; }
+ ProcessArgs(argc-1, &(argv[1]), options);
+
+ strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);
+ ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);
+ strcpy(APARSER_O, APARSER_C);
+ APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(APARSER_O, OBJ_FILE_SUFFIX);
+
+ strcpy(ASTBASE_O, ASTBASE_C);
+ ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(ASTBASE_O, OBJ_FILE_SUFFIX);
+
+ strcpy(PCCTSAST_O, PCCTSAST_C);
+ PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);
+
+ strcpy(LIST_O, LIST_C);
+ LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(LIST_O, OBJ_FILE_SUFFIX);
+
+ strcpy(DLEXERBASE_O, DLEXERBASE_C);
+ DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
+ strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);
+
+ if ( num_files == 0 ) fatal("no grammar files specified; exiting...");
+ if ( !gen_CPP && num_classes>0 ) {
+ warn("can't define classes w/o C++ mode; turning on C++ mode...\n");
+ gen_CPP=1;
+ }
+ if ( gen_CPP && num_classes==0 ) {
+ fatal("must define classes >0 grammar classes in C++ mode\n");
+ }
+
+ mk(project, files, num_files, argc, argv);
+ DONE;
+}
+
+void help()
+{
+ Opt *p = options;
+ static char buf[1000+1];
+
+ fprintf(stderr, "genmk [options] f1.g ... fn.g\n");
+ while ( p->option!=NULL && *(p->option) != '*' )
+ {
+ buf[0]='\0';
+ if ( p->arg ) sprintf(buf, "%s ___", p->option);
+ else strcpy(buf, p->option);
+ fprintf(stderr, "\t%-16s %s\n", buf, p->descr);
+ p++;
+ }
+}
+
+void mk(project, files, n, argc, argv)
+char *project;
+char **files;
+int n;
+int argc;
+char **argv;
+{
+ int i;
+
+ printf("#\n");
+ printf("# PCCTS makefile for: ");
+ pfiles(files, n, NULL);
+ printf("\n");
+ printf("#\n");
+ printf("# Created from:");
+ for (i=0; i<argc; i++) printf(" %s", argv[i]);
+ printf("\n");
+ printf("#\n");
+ printf("# PCCTS release 1.33MR21\n");
+ printf("# Project: %s\n", project);
+ if ( gen_CPP ) printf("# C++ output\n");
+ else printf("# C output\n");
+ if ( user_lexer ) printf("# User-defined scanner\n");
+ else printf("# DLG scanner\n");
+ if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);
+ else printf("# ANTLR-defined token types\n");
+ printf("#\n");
+ printf(".SUFFIXES:\n.SUFFIXES: .o .cpp .c .h .g .i .dlg\n");
+ if ( user_token_types!=NULL ) {
+ printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");
+ printf("TOKENS = %s", user_token_types);
+ }
+ else printf("TOKENS = %stokens.h", DIR());
+ printf("\n");
+ printf("#\n");
+ printf("# The following filenames must be consistent with ANTLR/DLG flags\n");
+ printf("DLG_FILE = %s%s\n", DIR(), dlg);
+ printf("ERR = %serr\n", DIR());
+ if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);
+ else printf("HDR_FILE =\n");
+ if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);
+ if ( !gen_CPP ) printf("SCAN = %s\n", scan);
+ else printf("SCAN = %s%s\n", DIR(), dlg_class);
+
+ printf("PCCTS = %s\n",pccts_path);
+ printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);
+ printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);
+ printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);
+ printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);
+ printf("CFLAGS = -I. -I$(ANTLR_H)");
+ if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);
+ printf(" $(COTHER)");
+ printf("\n");
+ printf("AFLAGS =");
+ if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
+ if ( user_lexer ) printf(" -gx");
+ if ( gen_CPP ) printf(" -CC");
+ if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);
+ if ( gen_trees ) printf(" -gt");
+ if ( gen_hoist ) {
+ printf(" -mrhoist on") ;
+ } else {
+ printf(" -mrhoist off");
+ };
+ printf(" $(AOTHER)");
+ printf("\n");
+ printf("DFLAGS = -C2 -i");
+ if ( gen_CPP ) printf(" -CC");
+ if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);
+ if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
+ printf(" $(DOTHER)");
+ printf("\n");
+ printf("GRM = ");
+ pfiles(files, n, NULL);
+ printf("\n");
+ printf("MYFILES = %s\n",cfiles);
+ printf("SRC = ");
+ if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(files, n, "c");
+ if ( gen_CPP ) {
+ printf(" \\\n ");
+ printf(" ");
+ pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" \\\n ");
+ printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);
+ if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);
+ if ( gen_trees ) {
+ printf(" \\\n ");
+ printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);
+ printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C);
+/* printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */
+ printf(" \\\n ");
+ }
+ printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);
+ }
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);
+ else printf(" %s$(SCAN).c", DIR());
+ }
+ if ( !gen_CPP ) printf(" $(ERR).c");
+ printf("\\\n $(MYFILES)\n");
+ printf("OBJ = ");
+ pfiles(files, n, "o");
+ if ( gen_CPP ) {
+ printf(" \\\n ");
+ printf(" ");
+ pclasses(classes, num_classes, "o");
+ printf(" \\\n ");
+ printf(" %s%s", DIR(), APARSER_O);
+ if ( !user_lexer ) {
+ printf(" %s%s", DIR(), DLEXERBASE_O);
+ }
+ if ( gen_trees ) {
+ printf(" \\\n ");
+ printf("%s%s", DIR(), ASTBASE_O);
+ printf(" %s%s", DIR(), PCCTSAST_O);
+/* printf(" %s%s", DIR(), LIST_O); */
+ printf(" \\\n ");
+ }
+ printf(" %s%s", DIR(), ATOKENBUFFER_O);
+ }
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX);
+ else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX);
+ }
+ if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX);
+ printf("\\\n $(MYFILES:.cpp=.o)\n");
+
+ printf("ANTLR_SPAWN = ");
+ if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(files, n, "c");
+ if ( gen_CPP ) {
+ printf(" ");
+ pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" \\\n ");
+ pclasses(classes, num_classes, "h");
+ if ( strcmp(hdr,"stdpccts.h")!=0 ) {
+ printf(" \\\n ");
+ printf("$(HDR_FILE) stdpccts.h");
+ }
+ }
+ if ( user_lexer ) {
+ if ( !user_token_types ) printf(" $(TOKENS)");
+ }
+ else {
+ printf(" $(DLG_FILE)");
+ if ( !user_token_types ) printf(" $(TOKENS)");
+ }
+ if ( !gen_CPP ) printf(" $(ERR).c");
+ printf("\n");
+
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);
+ else printf("DLG_SPAWN = %s$(SCAN).c", DIR());
+ if ( gen_CPP ) printf(" $(SCAN).h");
+ if ( !gen_CPP ) printf(" $(MOD_FILE)");
+ printf("\n");
+ }
+
+ if ( gen_CPP ) {
+ printf("CCC = %s\n",compilerCCC);
+ }
+ else printf("CC = %s\n",compilerCC);
+
+ /* set up dependencies */
+ printf("\n%s : $(OBJ) $(SRC)\n", project);
+ printf(" %s %s %s $(CFLAGS) $(OBJ)\n",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_EXE_FLAG,
+ project);
+ printf("\n");
+
+ /* implicit rules */
+
+ if(gen_CPP)
+ printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n");
+
+ printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n",
+ gen_CPP?"$(CCC)":"$(CC)");
+
+ /* how to compile parser files */
+
+ for (i=0; i<num_files; i++)
+ {
+ pfiles(&files[i], 1, "o");
+ if ( user_lexer ) {
+ printf(" : $(TOKENS)");
+ }
+ else {
+ if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");
+ else printf(" : $(MOD_FILE) $(TOKENS)");
+ }
+ printf(" ");
+ if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&files[i], 1, "c");
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+ printf("\n");
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ pfiles(&files[i], 1, "o");
+ printf(" ");
+ if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ else pfiles(&files[i], 1, "c");
+ printf("\n\n");
+ }
+
+ /* how to compile err.c */
+ if ( !gen_CPP ) {
+ printf("$(ERR)%s : $(ERR).c", OBJ_FILE_SUFFIX);
+ if ( !user_lexer ) printf(" $(TOKENS)");
+ printf("\n");
+ printf(" %s -c $(CFLAGS) %s $(ERR)%s $(ERR).c",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG,
+ OBJ_FILE_SUFFIX);
+ printf("\n\n");
+ }
+
+ /* how to compile Class.c */
+ for (i=0; i<num_classes; i++)
+ {
+ pclasses(&classes[i], 1, "o");
+ if ( user_lexer ) {
+ printf(" : $(TOKENS)");
+ }
+ else {
+ printf(" : $(TOKENS) $(SCAN).h");
+ }
+ printf(" ");
+ pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf(" ");
+ pclasses(&classes[i], 1, "h");
+ if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
+ printf("\n");
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ pclasses(&classes[i], 1, "o");
+ printf(" ");
+ pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
+ printf("\n\n");
+ }
+
+ /* how to compile scan.c */
+ if ( !user_lexer ) {
+ if ( gen_CPP ) printf("$(SCAN)%s : $(SCAN)%s", OBJ_FILE_SUFFIX, CPP_FILE_SUFFIX);
+ else printf("%s$(SCAN)%s : %s$(SCAN).c", DIR(), OBJ_FILE_SUFFIX, DIR());
+ if ( !user_lexer ) printf(" $(TOKENS)");
+ printf("\n");
+ if ( gen_CPP ) printf(" $(CCC) -c $(CFLAGS) %s $(SCAN)%s $(SCAN)%s",
+ RENAME_OBJ_FLAG,
+ OBJ_FILE_SUFFIX,
+ CPP_FILE_SUFFIX);
+ else printf(" $(CC) -c $(CFLAGS) %s %s$(SCAN)%s %s$(SCAN).c",
+ RENAME_OBJ_FLAG,
+ DIR(),
+ OBJ_FILE_SUFFIX,
+ DIR());
+ printf("\n\n");
+ }
+
+ printf("$(ANTLR_SPAWN) : $(GRM)\n");
+ printf(" $(ANTLR) $(AFLAGS) $(GRM)\n");
+
+ if ( !user_lexer )
+ {
+ printf("\n");
+ printf("$(DLG_SPAWN) : $(DLG_FILE)\n");
+ if ( gen_CPP ) printf(" $(DLG) $(DFLAGS) $(DLG_FILE)\n");
+ else printf(" $(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");
+ }
+
+ /* do the makes for ANTLR/DLG support */
+ if ( gen_CPP ) {
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
+ if ( !user_lexer ) {
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
+ }
+ if ( gen_trees ) {
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
+ printf("\n");
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",
+ RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
+ printf("\n");
+/*
+ printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
+ printf(" %s -c $(CFLAGS) %s ",
+ gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
+ printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
+*/
+ }
+ }
+
+ /* clean and scrub targets */
+
+ printf("\nclean:\n");
+ printf(" rm -f *%s core %s", OBJ_FILE_SUFFIX, project);
+ if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);
+ printf("\n");
+
+ printf("\nscrub:\n");
+ printf(" rm -f *%s core %s", OBJ_FILE_SUFFIX, project);
+ if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);
+ printf(" $(ANTLR_SPAWN)");
+ if ( !user_lexer ) printf(" $(DLG_SPAWN)");
+ printf("\n");
+}
+
+void pfiles(files, n, suffix)
+char **files;
+int n;
+char *suffix;
+{
+ int first=1;
+
+ while ( n>0 )
+ {
+ char *p = &(*files)[strlen(*files)-1];
+ if ( !first ) putchar(' ');
+ first=0;
+ while ( p > *files && *p != '.' ) --p;
+ if ( p == *files )
+ {
+ fprintf(stderr,
+ "genmk: filenames must be file.suffix format: %s\n",
+ *files);
+ exit(-1);
+ }
+ if ( suffix == NULL ) printf("%s", *files);
+ else
+ {
+ *p = '\0';
+ printf("%s", DIR());
+ if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX);
+ else printf("%s.%s", *files, suffix);
+ *p = '.';
+ }
+ files++;
+ --n;
+ }
+}
+
+void pclasses(classes, n, suffix)
+char **classes;
+int n;
+char *suffix;
+{
+ int first=1;
+
+ while ( n>0 )
+ {
+ if ( !first ) putchar(' ');
+ first=0;
+ if ( suffix == NULL ) printf("%s", *classes);
+ else {
+ printf("%s", DIR());
+ if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX);
+ else printf("%s.%s", *classes, suffix);
+ }
+ classes++;
+ --n;
+ }
+}
+
+static void
+#ifdef __STDC__
+ProcessArgs( int argc, char **argv, Opt *options )
+#else
+ProcessArgs( argc, argv, options )
+int argc;
+char **argv;
+Opt *options;
+#endif
+{
+ Opt *p;
+ require(argv!=NULL, "ProcessArgs: command line NULL");
+
+ while ( argc-- > 0 )
+ {
+ p = options;
+ while ( p->option != NULL )
+ {
+ if ( strcmp(p->option, "*") == 0 ||
+ strcmp(p->option, *argv) == 0 )
+ {
+ if ( p->arg )
+ {
+ (*p->process)( *argv, *(argv+1) );
+ argv++;
+ argc--;
+ }
+ else
+ (*p->process)( *argv );
+ break;
+ }
+ p++;
+ }
+ argv++;
+ }
+}
+
+void fatal( err_)
+char *err_;
+{
+ fprintf(stderr, "genmk: %s\n", err_);
+ exit(1);
+}
+
+void warn( err_)
+char *err_;
+{
+ fprintf(stderr, "genmk: %s\n", err_);
+}
+
+char *DIR()
+{
+ static char buf[200+1];
+
+ if ( strcmp(outdir,TopDirectory)==0 ) return "";
+ sprintf(buf, "%s%s", outdir, DirectorySymbol);
+ return buf;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/makefile
new file mode 100644
index 00000000..1631f74a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/genmk/makefile
@@ -0,0 +1,29 @@
+##
+## 7-Apr-97
+## added support/genmk/makefile to pccts 1.33MR1 distribution kit
+## (support/genmk/makefile" omitted from 1.33 distribution kit)
+##
+SRC=genmk.c
+OBJ=genmk.o
+# Define PC if you use a PC OS (changes directory symbol and object file extension)
+# see pccts/h/pcctscfg.h
+CC=cc
+COPT=-O
+#CFLAGS=-I../../h -DPC
+CFLAGS=$(COPT) -I../../h
+BAG=../../bin/bag
+
+genmk: $(OBJ) $(SRC) ../../h/pcctscfg.h
+ $(CC) -o genmk $(OBJ)
+
+clean:
+ rm -rf core *.o
+
+scrub:
+ rm -rf genmk core *.o
+
+shar:
+ shar genmk.c makefile > genmk.shar
+
+archive:
+ $(BAG) genmk.c makefile > genmk.bag
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/makefile
new file mode 100644
index 00000000..c0f343e0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/makefile
@@ -0,0 +1,19 @@
+BAG=../../bin/bag
+SRC=test.c rexpr.c
+OBJ=test.o rexpr.o
+CFLAGS = -g
+
+test: $(OBJ) $(SRC)
+ cc -g -o texpr $(OBJ)
+
+shar:
+ shar makefile test.c rexpr.c rexpr.h > rexpr.shar
+
+archive:
+ $(BAG) makefile test.c rexpr.c rexpr.h > rexpr.bag
+
+clean:
+ rm -rf *.o core texpr
+
+scrub:
+ rm -rf *.o core texpr
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.c
new file mode 100644
index 00000000..9d284b77
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.c
@@ -0,0 +1,586 @@
+/*
+ * This file contains code for
+ *
+ * int rexpr(char *expr, char *s);
+ *
+ * which answers
+ *
+ * 1 if 's' is in the language described by the regular expression 'expr'
+ * 0 if it is not
+ * -1 if the regular expression is invalid
+ *
+ * Language membership is determined by constructing a non-deterministic
+ * finite automata (NFA) from the regular expression. A depth-
+ * first-search is performed on the NFA (graph) to check for a match of 's'.
+ * Each non-epsilon arc consumes one character from 's'. Backtracking is
+ * performed to check all possible paths through the NFA.
+ *
+ * Regular expressions follow the meta-language:
+ *
+ * <regExpr> ::= <andExpr> ( '|' <andExpr> )*
+ *
+ * <andExpr> ::= <expr> ( <expr> )*
+ *
+ * <expr> ::= {'~'} '[' <atomList> ']' <repeatSymbol>
+ * | '(' <regExpr> ')' <repeatSymbol>
+ * | '{' <regExpr> '}' <repeatSymbol>
+ * | <atom> <repeatSymbol>
+ *
+ * <repeatSymbol> ::= { '*' | '+' }
+ *
+ * <atomList> ::= <atom> ( <atom> )*
+ * | { <atomList> } <atom> '-' <atom> { <atomList> }
+ *
+ * <atom> ::= Token[Atom]
+ *
+ * Notes:
+ * ~ means complement the set in [..]. i.e. all characters not listed
+ * * means match 0 or more times (can be on expression or atom)
+ * + means match 1 or more times (can be on expression or atom)
+ * {} optional
+ * () grouping
+ * [] set of atoms
+ * x-y all characters from x to y (found only in [..])
+ * \xx the character with value xx
+ *
+ * Examples:
+ * [a-z]+
+ * match 1 or more lower-case letters (e.g. variable)
+ *
+ * 0x[0-9A-Fa-f]+
+ * match a hex number with 0x on front (e.g. 0xA1FF)
+ *
+ * [0-9]+.[0-9]+{e[0-9]+}
+ * match a floating point number (e.g. 3.14e21)
+ *
+ * Code example:
+ * if ( rexpr("[a-zA-Z][a-zA-Z0-9]+", str) ) then str is keyword
+ *
+ * Terence Parr
+ * Purdue University
+ * April 1991
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include "rexpr.h"
+
+#ifdef __USE_PROTOS
+static int regExpr( GraphPtr g );
+static int andExpr( GraphPtr g );
+static int expr( GraphPtr g );
+static int repeatSymbol( GraphPtr g );
+static int atomList( char *p, int complement );
+static void next( void );
+static ArcPtr newGraphArc( void );
+static NodePtr newNode( void );
+static int ArcBetweenGraphNode( NodePtr i, NodePtr j, int label );
+static Graph BuildNFA_atom( int label );
+static Graph BuildNFA_AB( Graph A, Graph B );
+static Graph BuildNFA_AorB( Graph A, Graph B );
+static Graph BuildNFA_set( char *s );
+static Graph BuildNFA_Astar( Graph A );
+static Graph BuildNFA_Aplus( Graph A );
+static Graph BuildNFA_Aoptional( Graph A );
+#else
+static int regExpr();
+static int andExpr();
+static int expr();
+static int repeatSymbol();
+static int atomList();
+static void next();
+static ArcPtr newGraphArc();
+static NodePtr newNode();
+static int ArcBetweenGraphNode();
+static Graph BuildNFA_atom();
+static Graph BuildNFA_AB();
+static Graph BuildNFA_AorB();
+static Graph BuildNFA_set();
+static Graph BuildNFA_Astar();
+static Graph BuildNFA_Aplus();
+static Graph BuildNFA_Aoptional();
+#endif
+
+static char *_c;
+static int token, tokchar;
+static NodePtr accept;
+static NodePtr freelist = NULL;
+
+/*
+ * return 1 if s in language described by expr
+ * 0 if s is not
+ * -1 if expr is an invalid regular expression
+ */
+#ifdef __USE_PROTOS
+static int rexpr(char *expr,char *s)
+#else
+static int rexpr(expr, s)
+char *expr, *s;
+#endif
+{
+ NodePtr p,q;
+ Graph nfa;
+ int result;
+
+ fprintf(stderr, "rexpr(%s,%s);\n", expr,s);
+ freelist = NULL;
+ _c = expr;
+ next();
+ if ( regExpr(&nfa) == -1 ) return -1;
+ accept = nfa.right;
+ result = match(nfa.left, s);
+ /* free all your memory */
+ p = q = freelist;
+ while ( p!=NULL ) { q = p->track; free(p); p = q; }
+ return result;
+}
+
+/*
+ * do a depth-first-search on the NFA looking for a path from start to
+ * accept state labelled with the characters of 's'.
+ */
+
+#ifdef __USE_PROTOS
+static int match(NodePtr automaton,char *s)
+#else
+static int match(automaton, s)
+NodePtr automaton;
+char *s;
+#endif
+{
+ ArcPtr p;
+
+ if ( automaton == accept && *s == '\0' ) return 1; /* match */
+
+ for (p=automaton->arcs; p!=NULL; p=p->next) /* try all arcs */
+ {
+ if ( p->label == Epsilon )
+ {
+ if ( match(p->target, s) ) return 1;
+ }
+ else if ( p->label == *s )
+ if ( match(p->target, s+1) ) return 1;
+ }
+ return 0;
+}
+
+/*
+ * <regExpr> ::= <andExpr> ( '|' {<andExpr>} )*
+ *
+ * Return -1 if syntax error
+ * Return 0 if none found
+ * Return 1 if a regExrp was found
+ */
+
+#ifdef __USE_PROTOS
+static int regExpr(GraphPtr g)
+#else
+static int regExpr(g)
+GraphPtr g;
+#endif
+{
+ Graph g1, g2;
+
+ if ( andExpr(&g1) == -1 )
+ {
+ return -1;
+ }
+
+ while ( token == '|' )
+ {
+ int a;
+ next();
+ a = andExpr(&g2);
+ if ( a == -1 ) return -1; /* syntax error below */
+ else if ( !a ) return 1; /* empty alternative */
+ g1 = BuildNFA_AorB(g1, g2);
+ }
+
+ if ( token!='\0' ) return -1;
+
+ *g = g1;
+ return 1;
+}
+
+/*
+ * <andExpr> ::= <expr> ( <expr> )*
+ */
+
+#ifdef __USE_PROTOS
+static int andExpr(GraphPtr g)
+#else
+static int andExpr(g)
+GraphPtr g;
+#endif
+{
+ Graph g1, g2;
+
+ if ( expr(&g1) == -1 )
+ {
+ return -1;
+ }
+
+ while ( token==Atom || token=='{' || token=='(' || token=='~' || token=='[' )
+ {
+ if (expr(&g2) == -1) return -1;
+ g1 = BuildNFA_AB(g1, g2);
+ }
+
+ *g = g1;
+ return 1;
+}
+
+/*
+ * <expr> ::= {'~'} '[' <atomList> ']' <repeatSymbol>
+ * | '(' <regExpr> ')' <repeatSymbol>
+ * | '{' <regExpr> '}' <repeatSymbol>
+ * | <atom> <repeatSymbol>
+ */
+
+#ifdef __USE_PROTOS
+static int expr(GraphPtr g)
+#else
+static int expr(g)
+GraphPtr g;
+#endif
+{
+ int complement = 0;
+ char s[257]; /* alloc space for string of char in [] */
+
+ if ( token == '~' || token == '[' )
+ {
+ if ( token == '~' ) {complement = 1; next();}
+ if ( token != '[' ) return -1;
+ next();
+ if ( atomList( s, complement ) == -1 ) return -1;
+ *g = BuildNFA_set( s );
+ if ( token != ']' ) return -1;
+ next();
+ repeatSymbol( g );
+ return 1;
+ }
+ if ( token == '(' )
+ {
+ next();
+ if ( regExpr( g ) == -1 ) return -1;
+ if ( token != ')' ) return -1;
+ next();
+ repeatSymbol( g );
+ return 1;
+ }
+ if ( token == '{' )
+ {
+ next();
+ if ( regExpr( g ) == -1 ) return -1;
+ if ( token != '}' ) return -1;
+ next();
+ /* S p e c i a l C a s e O p t i o n a l { } */
+ if ( token != '*' && token != '+' )
+ {
+ *g = BuildNFA_Aoptional( *g );
+ }
+ repeatSymbol( g );
+ return 1;
+ }
+ if ( token == Atom )
+ {
+ *g = BuildNFA_atom( tokchar );
+ next();
+ repeatSymbol( g );
+ return 1;
+ }
+
+ return -1;
+}
+
+/*
+ * <repeatSymbol> ::= { '*' | '+' }
+ */
+#ifdef __USE_PROTOS
+static int repeatSymbol(GraphPtr g)
+#else
+static int repeatSymbol(g)
+GraphPtr g;
+#endif
+{
+ switch ( token )
+ {
+ case '*' : *g = BuildNFA_Astar( *g ); next(); break;
+ case '+' : *g = BuildNFA_Aplus( *g ); next(); break;
+ }
+ return 1;
+}
+
+/*
+ * <atomList> ::= <atom> { <atom> }*
+ * { <atomList> } <atom> '-' <atom> { <atomList> }
+ *
+ * a-b is same as ab
+ * q-a is same as q
+ */
+
+#ifdef __USE_PROTOS
+static int atomList(char *p, int complement)
+#else
+static int atomList(p, complement)
+char *p;
+int complement;
+#endif
+{
+ static unsigned char set[256]; /* no duplicates */
+ int first, last, i;
+ char *s = p;
+
+ if ( token != Atom ) return -1;
+
+ for (i=0; i<256; i++) set[i] = 0;
+ while ( token == Atom )
+ {
+ if ( !set[tokchar] ) *s++ = tokchar;
+ set[tokchar] = 1; /* Add atom to set */
+ next();
+ if ( token == '-' ) /* have we found '-' */
+ {
+ first = *(s-1); /* Get last char */
+ next();
+ if ( token != Atom ) return -1;
+ else
+ {
+ last = tokchar;
+ }
+ for (i = first+1; i <= last; i++)
+ {
+ if ( !set[tokchar] ) *s++ = i;
+ set[i] = 1; /* Add atom to set */
+ }
+ next();
+ }
+ }
+ *s = '\0';
+ if ( complement )
+ {
+ for (i=0; i<256; i++) set[i] = !set[i];
+ for (i=1,s=p; i<256; i++) if ( set[i] ) *s++ = i;
+ *s = '\0';
+ }
+ return 1;
+}
+
+/* a somewhat stupid lexical analyzer */
+
+#ifdef __USE_PROTOS
+static void next(void)
+#else
+static void next()
+#endif
+{
+ while ( *_c==' ' || *_c=='\t' || *_c=='\n' ) _c++;
+ if ( *_c=='\\' )
+ {
+ _c++;
+ if ( isdigit(*_c) )
+ {
+ int n=0;
+ while ( isdigit(*_c) )
+ {
+ n = n*10 + (*_c++ - '0');
+ }
+ if ( n>255 ) n=255;
+ tokchar = n;
+ }
+ else
+ {
+ switch (*_c)
+ {
+ case 'n' : tokchar = '\n'; break;
+ case 't' : tokchar = '\t'; break;
+ case 'r' : tokchar = '\r'; break;
+ default : tokchar = *_c;
+ }
+ _c++;
+ }
+ token = Atom;
+ }
+ else if ( isgraph(*_c) && *_c!='[' && *_c!='(' && *_c!='{' &&
+ *_c!='-' && *_c!='}' && *_c!=')' && *_c!=']' &&
+ *_c!='+' && *_c!='*' && *_c!='~' && *_c!='|' )
+ {
+ token = Atom;
+ tokchar = *_c++;
+ }
+ else
+ {
+ token = tokchar = *_c++;
+ }
+}
+
+/* N F A B u i l d i n g R o u t i n e s */
+
+#ifdef __USE_PROTOS
+static ArcPtr newGraphArc(void)
+#else
+static ArcPtr newGraphArc()
+#endif
+{
+ ArcPtr p;
+ p = (ArcPtr) calloc(1, sizeof(Arc));
+ if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);}
+ if ( freelist != NULL ) p->track = (ArcPtr) freelist;
+ freelist = (NodePtr) p;
+ return p;
+}
+
+#ifdef __USE_PROTOS
+static NodePtr newNode(void)
+#else
+static NodePtr newNode()
+#endif
+{
+ NodePtr p;
+ p = (NodePtr) calloc(1, sizeof(Node));
+ if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);}
+ if ( freelist != NULL ) p->track = freelist;
+ freelist = p;
+ return p;
+}
+
+#ifdef __USE_PROTOS
+static void ArcBetweenGraphNodes(NodePtr i,NodePtr j,int label)
+#else
+static void ArcBetweenGraphNodes(i, j, label)
+NodePtr i, j;
+int label;
+#endif
+{
+ ArcPtr a;
+
+ a = newGraphArc();
+ if ( i->arcs == NULL ) i->arctail = i->arcs = a;
+ else {(i->arctail)->next = a; i->arctail = a;}
+ a->label = label;
+ a->target = j;
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_atom(int label)
+#else
+static Graph BuildNFA_atom(label)
+int label;
+#endif
+{
+ Graph g;
+
+ g.left = newNode();
+ g.right = newNode();
+ ArcBetweenGraphNodes(g.left, g.right, label);
+ return( g );
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_AB(Graph A,Graph B)
+#else
+static Graph BuildNFA_AB(A, B)
+Graph A, B;
+#endif
+{
+ Graph g;
+
+ ArcBetweenGraphNodes(A.right, B.left, Epsilon);
+ g.left = A.left;
+ g.right = B.right;
+ return( g );
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_AorB(Graph A,Graph B)
+#else
+static Graph BuildNFA_AorB(A, B)
+Graph A, B;
+#endif
+{
+ Graph g;
+
+ g.left = newNode();
+ ArcBetweenGraphNodes(g.left, A.left, Epsilon);
+ ArcBetweenGraphNodes(g.left, B.left, Epsilon);
+ g.right = newNode();
+ ArcBetweenGraphNodes(A.right, g.right, Epsilon);
+ ArcBetweenGraphNodes(B.right, g.right, Epsilon);
+ return( g );
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_set(char *s)
+#else
+static Graph BuildNFA_set( s )
+char *s;
+#endif
+{
+ Graph g;
+
+ if ( s == NULL ) return g;
+
+ g.left = newNode();
+ g.right = newNode();
+ while ( *s != '\0' )
+ {
+ ArcBetweenGraphNodes(g.left, g.right, *s++);
+ }
+ return g;
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_Astar(Graph A)
+#else
+static Graph BuildNFA_Astar( A )
+Graph A;
+#endif
+{
+ Graph g;
+
+ g.left = newNode();
+ g.right = newNode();
+
+ ArcBetweenGraphNodes(g.left, A.left, Epsilon);
+ ArcBetweenGraphNodes(g.left, g.right, Epsilon);
+ ArcBetweenGraphNodes(A.right, g.right, Epsilon);
+ ArcBetweenGraphNodes(A.right, A.left, Epsilon);
+
+ return( g );
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_Aplus(Graph A)
+#else
+static Graph BuildNFA_Aplus( A )
+Graph A;
+#endif
+{
+ ArcBetweenGraphNodes(A.right, A.left, Epsilon);
+
+ return( A );
+}
+
+#ifdef __USE_PROTOS
+static Graph BuildNFA_Aoptional(Graph A)
+#else
+static Graph BuildNFA_Aoptional( A )
+Graph A;
+#endif
+{
+ Graph g;
+
+ g.left = newNode();
+ g.right = newNode();
+
+ ArcBetweenGraphNodes(g.left, A.left, Epsilon);
+ ArcBetweenGraphNodes(g.left, g.right, Epsilon);
+ ArcBetweenGraphNodes(A.right, g.right, Epsilon);
+
+ return( g );
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.h
new file mode 100644
index 00000000..4507330d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/rexpr.h
@@ -0,0 +1,30 @@
+#define Atom 256 /* token Atom (an impossible char value) */
+#define Epsilon 257 /* epsilon arc (an impossible char value) */
+
+/* track field must be same for all node types */
+typedef struct _a {
+ struct _a *track; /* track mem allocation */
+ int label;
+ struct _a *next;
+ struct _n *target;
+ } Arc, *ArcPtr;
+
+typedef struct _n {
+ struct _n *track;
+ ArcPtr arcs, arctail;
+ } Node, *NodePtr;
+
+typedef struct {
+ NodePtr left,
+ right;
+ } Graph, *GraphPtr;
+
+#ifdef __USE_PROTOS
+int rexpr( char *expr, char *s );
+int match( NodePtr automaton, char *s );
+#else
+int rexpr();
+int match();
+#endif
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/test.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/test.c
new file mode 100644
index 00000000..e159cc41
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/rexpr/test.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include "rexpr.h"
+
+/*
+ * test for rexpr().
+ * To make this test:
+ * cc -o rexpr test.c rexpr.c
+ * Then from command line type:
+ * rexpr r string
+ * where r is the regular expression that decribes a language
+ * and string is the string to verify.
+ */
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ if ( argc!=3 ) fprintf(stderr,"rexpr: expr s\n");
+ else printf("%d\n", rexpr(argv[1], argv[2]));
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.c
new file mode 100644
index 00000000..b90005a8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.c
@@ -0,0 +1,816 @@
+/* set.c
+
+ The following is a general-purpose set library originally developed
+ by Hank Dietz and enhanced by Terence Parr to allow dynamic sets.
+
+ Sets are now structs containing the #words in the set and
+ a pointer to the actual set words.
+
+ Generally, sets need not be explicitly allocated. They are
+ created/extended/shrunk when appropriate (e.g. in set_of()).
+ HOWEVER, sets need to be destroyed (free()ed) when they go out of scope
+ or are otherwise no longer needed. A routine is provided to
+ free a set.
+
+ Sets can be explicitly created with set_new(s, max_elem).
+
+ Sets can be declared to have minimum size to reduce realloc traffic.
+ Default minimum size = 1.
+
+ Sets can be explicitly initialized to have no elements (set.n == 0)
+ by using the 'empty' initializer:
+
+ Examples:
+ set a = empty; -- set_deg(a) == 0
+
+ return( empty );
+
+ Example set creation and destruction:
+
+ set
+ set_of2(e,g)
+ unsigned e,g;
+ {
+ set a,b,c;
+
+ b = set_of(e); -- Creates space for b and sticks in e
+ set_new(c, g); -- set_new(); set_orel() ==> set_of()
+ set_orel(g, &c);
+ a = set_or(b, c);
+ .
+ .
+ .
+ set_free(b);
+ set_free(c);
+ return( a );
+ }
+
+ 1987 by Hank Dietz
+
+ Modified by:
+ Terence Parr
+ Purdue University
+ October 1989
+
+ Made it smell less bad to C++ 7/31/93 -- TJP
+*/
+
+#include <stdio.h>
+#include "pcctscfg.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include <string.h>
+
+#include "set.h"
+
+#define MIN(i,j) ( (i) > (j) ? (j) : (i))
+#define MAX(i,j) ( (i) < (j) ? (j) : (i))
+
+/* elems can be a maximum of 32 bits */
+static unsigned bitmask[] = {
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x00000100, 0x00000200, 0x00000400, 0x00000800,
+ 0x00001000, 0x00002000, 0x00004000, 0x00008000,
+#if !defined(PC) || defined(PC32)
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x00400000, 0x00800000,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000
+#endif
+};
+
+set empty = set_init;
+static unsigned min=1;
+
+#define StrSize 200
+
+#ifdef MEMCHK
+#define CHK(a) \
+ if ( a.setword != NULL ) \
+ if ( !valid(a.setword) ) \
+ {fprintf(stderr, "%s(%d): invalid set\n",__FILE__,__LINE__); exit(-1);}
+#else
+#define CHK(a)
+#endif
+
+/*
+ * Set the minimum size (in words) of a set to reduce realloc calls
+ */
+void
+#ifdef __USE_PROTOS
+set_size( unsigned n )
+#else
+set_size( n )
+unsigned n;
+#endif
+{
+ min = n;
+}
+
+unsigned int
+#ifdef __USE_PROTOS
+set_deg( set a )
+#else
+set_deg( a )
+set a;
+#endif
+{
+ /* Fast compute degree of a set... the number
+ of elements present in the set. Assumes
+ that all word bits are used in the set
+ and that SETSIZE(a) is a multiple of WORDSIZE.
+ */
+ register unsigned *p = &(a.setword[0]);
+ register unsigned *endp = NULL; /* MR27 Avoid false memory check report */
+ register unsigned degree = 0;
+
+ CHK(a);
+ if ( a.n == 0 ) return(0);
+ endp = &(a.setword[a.n]);
+ while ( p < endp )
+ {
+ register unsigned t = *p;
+ register unsigned *b = &(bitmask[0]);
+ do {
+ if (t & *b) ++degree;
+ } while (++b < &(bitmask[WORDSIZE]));
+ p++;
+ }
+
+ return(degree);
+}
+
+set
+#ifdef __USE_PROTOS
+set_or( set b, set c )
+#else
+set_or( b, c )
+set b;
+set c;
+#endif
+{
+ /* Fast set union operation */
+ /* resultant set size is max(b, c); */
+ set *big;
+ set t;
+ unsigned int m,n;
+ register unsigned *r, *p, *q, *endp;
+
+ CHK(b); CHK(c);
+ t = empty;
+ if (b.n > c.n) {big= &b; m=b.n; n=c.n;} else {big= &c; m=c.n; n=b.n;}
+ set_ext(&t, m);
+ r = t.setword;
+
+ /* Or b,c until max of smaller set */
+ q = c.setword;
+ p = b.setword;
+ endp = &(b.setword[n]);
+ while ( p < endp ) *r++ = *p++ | *q++;
+
+ /* Copy rest of bigger set into result */
+ p = &(big->setword[n]);
+ endp = &(big->setword[m]);
+ while ( p < endp ) *r++ = *p++;
+
+ return(t);
+}
+
+set
+#ifdef __USE_PROTOS
+set_and( set b, set c )
+#else
+set_and( b, c )
+set b;
+set c;
+#endif
+{
+ /* Fast set intersection operation */
+ /* resultant set size is min(b, c); */
+ set t;
+ unsigned int n;
+ register unsigned *r, *p, *q, *endp;
+
+ CHK(b); CHK(c);
+ t = empty;
+ n = (b.n > c.n) ? c.n : b.n;
+ if ( n == 0 ) return t; /* TJP 4-27-92 fixed for empty set */
+ set_ext(&t, n);
+ r = t.setword;
+
+ /* & b,c until max of smaller set */
+ q = c.setword;
+ p = b.setword;
+ endp = &(b.setword[n]);
+ while ( p < endp ) *r++ = *p++ & *q++;
+
+ return(t);
+}
+
+set
+#ifdef __USE_PROTOS
+set_dif( set b, set c )
+#else
+set_dif( b, c )
+set b;
+set c;
+#endif
+{
+ /* Fast set difference operation b - c */
+ /* resultant set size is size(b) */
+ set t;
+ unsigned int n;
+ register unsigned *r, *p, *q, *endp;
+
+ CHK(b); CHK(c);
+ t = empty;
+ n = (b.n <= c.n) ? b.n : c.n ;
+ if ( b.n == 0 ) return t; /* TJP 4-27-92 fixed for empty set */
+ /* WEC 12-1-92 fixed for c.n = 0 */
+ set_ext(&t, b.n);
+ r = t.setword;
+
+ /* Dif b,c until smaller set size */
+ q = c.setword;
+ p = b.setword;
+ endp = &(b.setword[n]);
+ while ( p < endp ) *r++ = *p++ & (~ *q++);
+
+ /* Copy rest of b into result if size(b) > c */
+ if ( b.n > n )
+ {
+ p = &(b.setword[n]);
+ endp = &(b.setword[b.n]);
+ while ( p < endp ) *r++ = *p++;
+ }
+
+ return(t);
+}
+
+set
+#ifdef __USE_PROTOS
+set_of( unsigned b )
+#else
+set_of( b )
+unsigned b;
+#endif
+{
+ /* Fast singleton set constructor operation */
+ static set a;
+
+ if ( b == nil ) return( empty );
+ set_new(a, b);
+ a.setword[DIVWORD(b)] = bitmask[MODWORD(b)];
+
+ return(a);
+}
+
+/*
+ * Extend (or shrink) the set passed in to have n words.
+ *
+ * if n is smaller than the minimum, boost n to have the minimum.
+ * if the new set size is the same as the old one, do nothing.
+ *
+ * TJP 4-27-92 Fixed so won't try to alloc 0 bytes
+ */
+void
+#ifdef __USE_PROTOS
+set_ext( set *a, unsigned int n )
+#else
+set_ext( a, n )
+set *a;
+unsigned int n;
+#endif
+{
+ register unsigned *p;
+ register unsigned *endp;
+ unsigned int size;
+
+ CHK((*a));
+ if ( a->n == 0 )
+ {
+ if ( n == 0 ) return;
+ if (a->setword != NULL) {
+ free (a->setword); /* MR20 */
+ }
+ a->setword = (unsigned *) calloc(n, BytesPerWord);
+ if ( a->setword == NULL )
+ {
+ fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n);
+ exit(-1);
+ }
+ a->n = n;
+ return;
+ }
+ if ( n < min ) n = min;
+ if ( a->n == n || n == 0 ) return;
+ size = a->n;
+ a->n = n;
+ a->setword = (unsigned *) realloc( (char *)a->setword, (n*BytesPerWord) );
+ if ( a->setword == NULL )
+ {
+ fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n);
+ exit(-1);
+ }
+
+ p = &(a->setword[size]); /* clear from old size to new size */
+ endp = &(a->setword[a->n]);
+ do {
+ *p++ = 0;
+ } while ( p < endp );
+}
+
+set
+#ifdef __USE_PROTOS
+set_not( set a )
+#else
+set_not( a )
+set a;
+#endif
+{
+ /* Fast not of set a (assumes all bits used) */
+ /* size of resultant set is size(a) */
+ /* ~empty = empty cause we don't know how bit to make set */
+ set t;
+ register unsigned *r;
+ register unsigned *p = a.setword;
+ register unsigned *endp = &(a.setword[a.n]);
+
+ CHK(a);
+ t = empty;
+ if ( a.n == 0 ) return( empty );
+ set_ext(&t, a.n);
+ r = t.setword;
+
+ do {
+ *r++ = (~ *p++);
+ } while ( p < endp );
+
+ return(t);
+}
+
+int
+#ifdef __USE_PROTOS
+set_equ( set a, set b )
+#else
+set_equ( a, b )
+set a;
+set b;
+#endif
+{
+/* 8-Nov-97 Make it work with sets of different sizes */
+/* Easy to understand, too. Probably faster. */
+/* Check for a equal to b */
+
+ unsigned int count; /* MR11 */
+ unsigned int i; /* MR11 */
+
+ CHK(a); CHK(b);
+
+ count=MIN(a.n,b.n);
+ if (count == 0) return 1;
+ for (i=0; i < count; i++) {
+ if (a.setword[i] != b.setword[i]) return 0;
+ };
+ if (a.n < b.n) {
+ for (i=count; i < b.n; i++) {
+ if (b.setword[i] != 0) return 0;
+ }
+ return 1;
+ } else if (a.n > b.n) {
+ for (i=count; i < a.n; i++) {
+ if (a.setword[i] != 0) return 0;
+ }
+ return 1;
+ } else {
+ return 1;
+ };
+}
+
+int
+#ifdef __USE_PROTOS
+set_sub( set a, set b )
+#else
+set_sub( a, b )
+set a;
+set b;
+#endif
+{
+
+/* 8-Nov-97 Make it work with sets of different sizes */
+/* Easy to understand, too. Probably faster. */
+/* Check for a is a PROPER subset of b */
+
+ unsigned int count;
+ unsigned int i;
+
+ CHK(a); CHK(b);
+
+ if (a.n == 0) return 1;
+ count=MIN(a.n,b.n);
+ for (i=0; i < count; i++) {
+ if (a.setword[i] & ~b.setword[i]) return 0;
+ };
+ if (a.n <= b.n) {
+ return 1;
+ } else {
+ for (i=count; i<a.n ; i++) {
+ if (a.setword[i]) return 0;
+ };
+ };
+ return 1;
+}
+
+unsigned
+#ifdef __USE_PROTOS
+set_int( set b )
+#else
+set_int( b )
+set b;
+#endif
+{
+ /* Fast pick any element of the set b */
+ register unsigned *p = b.setword;
+ register unsigned *endp = &(b.setword[b.n]);
+
+ CHK(b);
+ if ( b.n == 0 ) return( nil );
+
+ do {
+ if (*p) {
+ /* Found a non-empty word of the set */
+ register unsigned i = ((p - b.setword) << LogWordSize);
+ register unsigned t = *p;
+ p = &(bitmask[0]);
+ while (!(*p & t)) {
+ ++i; ++p;
+ }
+ return(i);
+ }
+ } while (++p < endp);
+
+ /* Empty -- only element it contains is nil */
+ return(nil);
+}
+
+int
+#ifdef __USE_PROTOS
+set_el( unsigned b, set a )
+#else
+set_el( b, a )
+unsigned b;
+set a;
+#endif
+{
+ CHK(a);
+ /* nil is an element of every set */
+ if (b == nil) return(1);
+ if ( a.n == 0 || NumWords(b) > a.n ) return(0);
+
+ /* Otherwise, we have to check */
+ return( a.setword[DIVWORD(b)] & bitmask[MODWORD(b)] );
+}
+
+int
+#ifdef __USE_PROTOS
+set_nil( set a )
+#else
+set_nil( a )
+set a;
+#endif
+{
+ /* Fast check for nil set */
+ register unsigned *p = a.setword;
+ register unsigned *endp;
+
+ CHK(a);
+ if ( a.n == 0 ) return(1);
+ endp = &(a.setword[a.n]);
+
+ /* The set is not empty if any word used to store
+ the set is non-zero. This means one must be a
+ bit careful about doing things like negation.
+ */
+ do {
+ if (*p) return(0);
+ } while (++p < endp);
+
+ return(1);
+}
+
+char *
+#ifdef __USE_PROTOS
+set_str( set a )
+#else
+set_str( a )
+set a;
+#endif
+{
+ /* Fast convert set a into ASCII char string...
+ assumes that all word bits are used in the set
+ and that SETSIZE is a multiple of WORDSIZE.
+ Trailing 0 bits are removed from the string.
+ if no bits are on or set is empty, "" is returned.
+ */
+ register unsigned *p = a.setword;
+ register unsigned *endp = &(a.setword[a.n]);
+ static char str_tmp[StrSize+1];
+ register char *q = &(str_tmp[0]);
+
+ CHK(a);
+ if ( a.n==0 ) {*q=0; return( &(str_tmp[0]) );}
+ do {
+ register unsigned t = *p;
+ register unsigned *b = &(bitmask[0]);
+ do {
+ *(q++) = (char) ((t & *b) ? '1' : '0');
+ } while (++b < &(bitmask[WORDSIZE]));
+ } while (++p < endp);
+
+ /* Trim trailing 0s & NULL terminate the string */
+ while ((q > &(str_tmp[0])) && (*(q-1) != '1')) --q;
+ *q = 0;
+
+ return(&(str_tmp[0]));
+}
+
+set
+#ifdef __USE_PROTOS
+set_val( register char *s )
+#else
+set_val( s )
+register char *s;
+#endif
+{
+ /* Fast convert set ASCII char string into a set.
+ If the string ends early, the remaining set bits
+ are all made zero.
+ The resulting set size is just big enough to hold all elements.
+ */
+ static set a;
+ register unsigned *p, *endp;
+
+ set_new(a, (unsigned) strlen(s));
+ p = a.setword;
+ endp = &(a.setword[a.n]);
+ do {
+ register unsigned *b = &(bitmask[0]);
+ /* Start with a word with no bits on */
+ *p = 0;
+ do {
+ if (*s) {
+ if (*s == '1') {
+ /* Turn-on this bit */
+ *p |= *b;
+ }
+ ++s;
+ }
+ } while (++b < &(bitmask[WORDSIZE]));
+ } while (++p < endp);
+
+ return(a);
+}
+
+/*
+ * Or element e into set a. a can be empty.
+ */
+void
+#ifdef __USE_PROTOS
+set_orel( unsigned e, set *a )
+#else
+set_orel( e, a )
+unsigned e;
+set *a;
+#endif
+{
+ CHK((*a));
+ if ( e == nil ) return;
+ if ( NumWords(e) > a->n ) set_ext(a, NumWords(e));
+ a->setword[DIVWORD(e)] |= bitmask[MODWORD(e)];
+}
+
+/*
+ * Or set b into set a. a can be empty. does nothing if b empty.
+ */
+void
+#ifdef __USE_PROTOS
+set_orin( set *a, set b )
+#else
+set_orin( a, b )
+set *a;
+set b;
+#endif
+{
+ /* Fast set union operation */
+ /* size(a) is max(a, b); */
+ unsigned int m;
+ register unsigned *p,
+ *q = b.setword,
+ *endq; /* MR20 */
+
+ CHK((*a)); CHK(b);
+ if ( b.n == 0 ) return;
+ endq = &(b.setword[b.n]); /* MR20 */
+ m = (a->n > b.n) ? a->n : b.n;
+ set_ext(a, m);
+ p = a->setword;
+ do {
+ *p++ |= *q++;
+ } while ( q < endq );
+}
+
+/*
+ * And set b into set a. a can be empty. does nothing if b empty.
+ */
+void
+#ifdef __USE_PROTOS
+set_andin( set *a, set b )
+#else
+set_andin( a, b )
+set *a;
+set b;
+#endif
+{
+ /* Fast set intersection operation */
+ /* size(a) is max(a, b); */
+ unsigned int m;
+ register unsigned *p,
+ *q = b.setword,
+ *endq = &(b.setword[b.n]);
+
+ CHK((*a)); CHK(b);
+ if ( b.n == 0 ) return;
+ m = (a->n > b.n) ? a->n : b.n;
+ set_ext(a, m);
+ p = a->setword;
+ do {
+ *p++ &= *q++;
+ } while ( q < endq );
+}
+
+void
+#ifdef __USE_PROTOS
+set_rm( unsigned e, set a )
+#else
+set_rm( e, a )
+unsigned e;
+set a;
+#endif
+{
+ /* Does not effect size of set */
+ CHK(a);
+ if ( (e == nil) || (NumWords(e) > a.n) ) return;
+ a.setword[DIVWORD(e)] ^= (a.setword[DIVWORD(e)]&bitmask[MODWORD(e)]);
+}
+
+void
+#ifdef __USE_PROTOS
+set_clr( set a )
+#else
+set_clr( a )
+set a;
+#endif
+{
+ /* Does not effect size of set */
+ register unsigned *p = a.setword;
+ register unsigned *endp;
+
+ CHK(a);
+ if ( a.n == 0 ) return;
+ endp = &(a.setword[a.n]);
+ do {
+ *p++ = 0;
+ } while ( p < endp );
+}
+
+set
+#ifdef __USE_PROTOS
+set_dup( set a )
+#else
+set_dup( a )
+set a;
+#endif
+{
+ set b;
+ register unsigned *p,
+ *q = a.setword,
+ *endq; /* MR20 */
+
+ CHK(a);
+ b = empty;
+ if ( a.n == 0 ) return( empty );
+ endq = &(a.setword[a.n]); /* MR20 */
+ set_ext(&b, a.n);
+ p = b.setword;
+ do {
+ *p++ = *q++;
+ } while ( q < endq );
+
+ return(b);
+}
+
+/*
+ * Return a nil terminated list of unsigned ints that represents all
+ * "on" bits in the bit set.
+ *
+ * e.g. {011011} --> {1, 2, 4, 5, nil}
+ *
+ * _set_pdq and set_pdq are useful when an operation is required on each element
+ * of a set. Normally, the sequence is:
+ *
+ * while ( set_deg(a) > 0 ) {
+ * e = set_int(a);
+ * set_rm(e, a);
+ * ...process e...
+ * }
+ * Now,
+ *
+ * t = e = set_pdq(a);
+ * while ( *e != nil ) {
+ * ...process *e...
+ * e++;
+ * }
+ * free( t );
+ *
+ * We have saved many set calls and have not destroyed set a.
+ */
+void
+#ifdef __USE_PROTOS
+_set_pdq( set a, register unsigned *q )
+#else
+_set_pdq( a, q )
+set a;
+register unsigned *q;
+#endif
+{
+ register unsigned *p = a.setword,
+ *endp = &(a.setword[a.n]);
+ register unsigned e=0;
+
+ CHK(a);
+ /* are there any space (possibility of elements)? */
+ if ( a.n == 0 ) return;
+ do {
+ register unsigned t = *p;
+ register unsigned *b = &(bitmask[0]);
+ do {
+ if ( t & *b ) *q++ = e;
+ ++e;
+ } while (++b < &(bitmask[WORDSIZE]));
+ } while (++p < endp);
+ *q = nil;
+}
+
+/*
+ * Same as _set_pdq except allocate memory. set_pdq is the natural function
+ * to use.
+ */
+unsigned *
+#ifdef __USE_PROTOS
+set_pdq( set a )
+#else
+set_pdq( a )
+set a;
+#endif
+{
+ unsigned *q;
+ int max_deg;
+
+ CHK(a);
+ max_deg = WORDSIZE*a.n;
+ /* assume a.n!=0 & no elements is rare, but still ok */
+ if ( a.n == 0 ) return(NULL);
+ q = (unsigned *) malloc((max_deg+1)*BytesPerWord);
+ if ( q == NULL ) return( NULL );
+ _set_pdq(a, q);
+ return( q );
+}
+
+/* a function that produces a hash number for the set
+ */
+unsigned int
+#ifdef __USE_PROTOS
+set_hash( set a, register unsigned int mod )
+#else
+set_hash( a, mod )
+set a;
+register unsigned int mod;
+#endif
+{
+ /* Fast hash of set a (assumes all bits used) */
+ register unsigned *p = &(a.setword[0]);
+ register unsigned *endp = &(a.setword[a.n]);
+ register unsigned i = 0;
+
+ CHK(a);
+ while (p<endp){
+ i += (*p);
+ ++p;
+ }
+
+ return(i % mod);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.h
new file mode 100644
index 00000000..366088e9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/set/set.h
@@ -0,0 +1,121 @@
+#ifndef __GATE_SET_H
+#define __GATE_SET_H
+
+/* set.h
+
+ The following is a general-purpose set library originally developed
+ by Hank Dietz and enhanced by Terence Parr to allow dynamic sets.
+
+ Sets are now structs containing the #words in the set and
+ a pointer to the actual set words.
+
+ 1987 by Hank Dietz
+
+ Modified by:
+ Terence Parr
+ Purdue University
+ October 1989
+
+ Added ANSI prototyping Dec. 1992 -- TJP
+*/
+
+#include "pcctscfg.h"
+
+#ifdef NOT_USED /* SEE config.h */
+/* Define usable bits per unsigned int word */
+#ifdef PC
+#define WORDSIZE 16
+#define LogWordSize 4
+#else
+#define WORDSIZE 32
+#define LogWordSize 5
+#endif
+#define BytesPerWord sizeof(unsigned)
+#endif
+
+#define SETSIZE(a) ((a).n<<LogWordSize) /* Maximum items per set */
+#define MODWORD(x) ((x) & (WORDSIZE-1)) /* x % WORDSIZE */
+#define DIVWORD(x) ((x) >> LogWordSize) /* x / WORDSIZE */
+#define nil (~((unsigned) 0)) /* An impossible set member all bits on (big!) */
+
+typedef struct _set {
+ unsigned int n; /* Number of words in set */
+ unsigned *setword;
+ } set;
+
+#define set_init {0, NULL}
+#define set_null(a) ((a).setword==NULL)
+
+#define NumBytes(x) (((x)>>3)+1) /* Num bytes to hold x */
+#define NumWords(x) ((((unsigned)(x))>>LogWordSize)+1) /* Num words to hold x */
+
+
+/* M a c r o s */
+
+/* make arg1 a set big enough to hold max elem # of arg2 */
+#define set_new(a,_max) \
+if (((a).setword=(unsigned *)calloc(NumWords(_max),BytesPerWord))==NULL) \
+ fprintf(stderr, "set_new: Cannot allocate set with max of %d\n", _max); \
+ (a).n = NumWords(_max);
+
+#define set_free(a) \
+ {if ( (a).setword != NULL ) free((char *)((a).setword)); \
+ (a) = empty;}
+
+#ifdef __USE_PROTOS
+extern void set_size( unsigned );
+extern unsigned int set_deg( set );
+extern set set_or( set, set );
+extern set set_and( set, set );
+extern set set_dif( set, set );
+extern set set_of( unsigned );
+extern void set_ext( set *, unsigned int );
+extern set set_not( set );
+extern int set_equ( set, set );
+extern int set_sub( set, set );
+extern unsigned set_int( set );
+extern int set_el( unsigned, set );
+extern int set_nil( set );
+extern char * set_str( set );
+extern set set_val( register char * );
+extern void set_orel( unsigned, set * );
+extern void set_orin( set *, set );
+extern void set_andin( set *, set );
+extern void set_rm( unsigned, set );
+extern void set_clr( set );
+extern set set_dup( set );
+extern void set_PDQ( set, register unsigned * );
+extern unsigned *set_pdq( set );
+extern void _set_pdq( set a, register unsigned *q );
+extern unsigned int set_hash( set, register unsigned int );
+#else
+extern void set_size();
+extern unsigned int set_deg();
+extern set set_or();
+extern set set_and();
+extern set set_dif();
+extern set set_of();
+extern void set_ext();
+extern set set_not();
+extern int set_equ();
+extern int set_sub();
+extern unsigned set_int();
+extern int set_el();
+extern int set_nil();
+extern char * set_str();
+extern set set_val();
+extern void set_orel();
+extern void set_orin();
+extern void set_andin();
+extern void set_rm();
+extern void set_clr();
+extern set set_dup();
+extern void set_PDQ();
+extern unsigned *set_pdq();
+extern void _set_pdq();
+extern unsigned int set_hash();
+#endif
+
+extern set empty;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/sym.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/sym.c
new file mode 100644
index 00000000..69eb2b47
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/sym.c
@@ -0,0 +1,402 @@
+/*
+ * Simple symbol table manager using coalesced chaining to resolve collisions
+ *
+ * Doubly-linked lists are used for fast removal of entries.
+ *
+ * 'sym.h' must have a definition for typedef "Sym". Sym must include at
+ * minimum the following fields:
+ *
+ * ...
+ * char *symbol;
+ * struct ... *next, *prev, **head, *scope;
+ * unsigned int hash;
+ * ...
+ *
+ * 'template.h' can be used as a template to create a 'sym.h'.
+ *
+ * 'head' is &(table[hash(itself)]).
+ * The hash table is not resizable at run-time.
+ * The scope field is used to link all symbols of a current scope together.
+ * Scope() sets the current scope (linked list) to add symbols to.
+ * Any number of scopes can be handled. The user passes the address of
+ * a pointer to a symbol table
+ * entry (INITIALIZED TO NULL first time).
+ *
+ * Available Functions:
+ *
+ * zzs_init(s1,s2) -- Create hash table with size s1, string table size s2.
+ * zzs_done() -- Free hash and string table created with zzs_init().
+ * zzs_add(key,rec)-- Add 'rec' with key 'key' to the symbol table.
+ * zzs_newadd(key) -- create entry; add using 'key' to the symbol table.
+ * zzs_get(key) -- Return pointer to last record entered under 'key'
+ * Else return NULL
+ * zzs_del(p) -- Unlink the entry associated with p. This does
+ * NOT free 'p' and DOES NOT remove it from a scope
+ * list. If it was a part of your intermediate code
+ * tree or another structure. It will still be there.
+ * It is only removed from further consideration
+ * by the symbol table.
+ * zzs_keydel(s) -- Unlink the entry associated with key s.
+ * Calls zzs_del(p) to unlink.
+ * zzs_scope(sc) -- Specifies that everything added to the symbol
+ * table with zzs_add() is added to the list (scope)
+ * 'sc'. 'sc' is of 'Sym **sc' type and must be
+ * initialized to NULL before trying to add anything
+ * to it (passing it to zzs_scope()). Scopes can be
+ * switched at any time and merely links a set of
+ * symbol table entries. If a NULL pointer is
+ * passed, the current scope is returned.
+ * zzs_rmscope(sc) -- Remove (zzs_del()) all elements of scope 'sc'
+ * from the symbol table. The entries are NOT
+ * free()'d. A pointer to the first
+ * element in the "scope" is returned. The user
+ * can then manipulate the list as he/she chooses
+ * (such as freeing them all). NOTE that this
+ * function sets your scope pointer to NULL,
+ * but returns a pointer to the list for you to use.
+ * zzs_stat() -- Print out the symbol table and some relevant stats.
+ * zzs_new(key) -- Create a new record with calloc() of type Sym.
+ * Add 'key' to the string table and make the new
+ * records 'symbol' pointer point to it.
+ * zzs_strdup(s) -- Add s to the string table and return a pointer
+ * to it. Very fast allocation routine
+ * and does not require strlen() nor calloc().
+ *
+ * Example:
+ *
+ * #include <stdio.h>
+ * #include "sym.h"
+ *
+ * main()
+ * {
+ * Sym *scope1=NULL, *scope2=NULL, *a, *p;
+ *
+ * zzs_init(101, 100);
+ *
+ * a = zzs_new("Apple"); zzs_add(a->symbol, a); -- No scope
+ * zzs_scope( &scope1 ); -- enter scope 1
+ * a = zzs_new("Plum"); zzs_add(a->symbol, a);
+ * zzs_scope( &scope2 ); -- enter scope 2
+ * a = zzs_new("Truck"); zzs_add(a->symbol, a);
+ *
+ * p = zzs_get("Plum");
+ * if ( p == NULL ) fprintf(stderr, "Hmmm...Can't find 'Plum'\n");
+ *
+ * p = zzs_rmscope(&scope1)
+ * for (; p!=NULL; p=p->scope) {printf("Scope1: %s\n", p->symbol);}
+ * p = zzs_rmscope(&scope2)
+ * for (; p!=NULL; p=p->scope) {printf("Scope2: %s\n", p->symbol);}
+ * }
+ *
+ * Terence Parr
+ * Purdue University
+ * February 1990
+ *
+ * CHANGES
+ *
+ * Terence Parr
+ * May 1991
+ * Renamed functions to be consistent with ANTLR
+ * Made HASH macro
+ * Added zzs_keydel()
+ * Added zzs_newadd()
+ * Fixed up zzs_stat()
+ *
+ * July 1991
+ * Made symbol table entry save its hash code for fast comparison
+ * during searching etc...
+ */
+
+#include <stdio.h>
+#if defined(__STDC__) || defined(__USE_PROTOS)
+#include <string.h>
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include "sym.h"
+
+#define StrSame 0
+
+static Sym **CurScope = NULL;
+static unsigned size = 0;
+static Sym **table=NULL;
+static char *strings;
+static char *strp;
+static int strsize = 0;
+
+#ifdef __USE_PROTOS
+void zzs_init(int sz,int strs)
+#else
+void zzs_init(sz, strs)
+int sz, strs;
+#endif
+{
+ if ( sz <= 0 || strs <= 0 ) return;
+ table = (Sym **) calloc(sz, sizeof(Sym *));
+ if ( table == NULL )
+ {
+ fprintf(stderr, "Cannot allocate table of size %d\n", sz);
+ exit(1);
+ }
+ strings = (char *) calloc(strs, sizeof(char));
+ if ( strings == NULL )
+ {
+ fprintf(stderr, "Cannot allocate string table of size %d\n", strs);
+ exit(1);
+ }
+ size = sz;
+ strsize = strs;
+ strp = strings;
+}
+
+#ifdef __USE_PROTOS
+void zzs_done(void)
+#else
+void zzs_done()
+#endif
+{
+ if ( table != NULL ) free( table );
+ if ( strings != NULL ) free( strings );
+}
+
+#ifdef __USE_PROTOS
+void zzs_add(char *key,Sym rec)
+#else
+void zzs_add(key, rec)
+char *key;
+register Sym *rec;
+#endif
+{
+ register unsigned int h=0;
+ register char *p=key;
+
+ HASH(p, h);
+ rec->hash = h; /* save hash code for fast comp later */
+ h %= size;
+
+ if ( CurScope != NULL ) {rec->scope = *CurScope; *CurScope = rec;}
+ rec->next = table[h]; /* Add to doubly-linked list */
+ rec->prev = NULL;
+ if ( rec->next != NULL ) (rec->next)->prev = rec;
+ table[h] = rec;
+ rec->head = &(table[h]);
+}
+
+#ifdef __USE_PROTOS
+Sym * zzs_get(char *key)
+#else
+Sym * zzs_get(key)
+char *key;
+#endif
+{
+ register unsigned int h=0;
+ register char *p=key;
+ register Sym *q;
+
+ HASH(p, h);
+
+ for (q = table[h%size]; q != NULL; q = q->next)
+ {
+ if ( q->hash == h ) /* do we even have a chance of matching? */
+ if ( strcmp(key, q->symbol) == StrSame ) return( q );
+ }
+ return( NULL );
+}
+
+/*
+ * Unlink p from the symbol table. Hopefully, it's actually in the
+ * symbol table.
+ *
+ * If p is not part of a bucket chain of the symbol table, bad things
+ * will happen.
+ *
+ * Will do nothing if all list pointers are NULL
+ */
+#ifdef __USE_PROTOS
+void zzs_del(Sym *p)
+#else
+void zzs_del(p)
+register Sym *p;
+#endif
+{
+ if ( p == NULL ) {fprintf(stderr, "zzs_del(NULL)\n"); exit(1);}
+ if ( p->prev == NULL ) /* Head of list */
+ {
+ register Sym **t = p->head;
+
+ if ( t == NULL ) return; /* not part of symbol table */
+ (*t) = p->next;
+ if ( (*t) != NULL ) (*t)->prev = NULL;
+ }
+ else
+ {
+ (p->prev)->next = p->next;
+ if ( p->next != NULL ) (p->next)->prev = p->prev;
+ }
+ p->next = p->prev = NULL; /* not part of symbol table anymore */
+ p->head = NULL;
+}
+
+#ifdef __USE_PROTOS
+void zzs_keydel(char *key)
+#else
+void zzs_keydel(key)
+char *key;
+#endif
+{
+ Sym *p = zzs_get(key);
+
+ if ( p != NULL ) zzs_del( p );
+}
+
+/* S c o p e S t u f f */
+
+/* Set current scope to 'scope'; return current scope if 'scope' == NULL */
+
+#ifdef __USE_PROTOS
+Sym ** zzs_scope(Sym **scope)
+#else
+Sym ** zzs_scope(scope)
+Sym **scope;
+#endif
+{
+ if ( scope == NULL ) return( CurScope );
+ CurScope = scope;
+ return( scope );
+}
+
+/* Remove a scope described by 'scope'. Return pointer to 1st element in scope */
+
+#ifdef __USE_PROTOS
+Sym * zzs_rmscope(Sym **scope)
+#else
+Sym * zzs_rmscope(scope)
+register Sym **scope;
+#endif
+{
+ register Sym *p;
+ Sym *start;
+
+ if ( scope == NULL ) return(NULL);
+ start = p = *scope;
+ for (; p != NULL; p=p->scope) { zzs_del( p ); }
+ *scope = NULL;
+ return( start );
+}
+
+#ifdef __USE_PROTOS
+void zzs_stat(void)
+#else
+void zzs_stat()
+#endif
+{
+ static unsigned short count[20];
+ unsigned int i,n=0,low=0, hi=0;
+ register Sym **p;
+ float avg=0.0;
+
+ for (i=0; i<20; i++) count[i] = 0;
+ for (p=table; p<&(table[size]); p++)
+ {
+ register Sym *q = *p;
+ unsigned int len;
+
+ if ( q != NULL && low==0 ) low = p-table;
+ len = 0;
+ if ( q != NULL ) printf("[%d]", p-table);
+ while ( q != NULL )
+ {
+ len++;
+ n++;
+ printf(" %s", q->symbol);
+ q = q->next;
+ if ( q == NULL ) printf("\n");
+ }
+ if ( len>=20 ) printf("zzs_stat: count table too small\n");
+ else count[len]++;
+ if ( *p != NULL ) hi = p-table;
+ }
+
+ printf("Storing %d recs used %d hash positions out of %d\n",
+ n, size-count[0], size);
+ printf("%f %% utilization\n",
+ ((float)(size-count[0]))/((float)size));
+ for (i=0; i<20; i++)
+ {
+ if ( count[i] != 0 )
+ {
+ avg += (((float)(i*count[i]))/((float)n)) * i;
+ printf("Buckets of len %d == %d (%f %% of recs)\n",
+ i, count[i], 100.0*((float)(i*count[i]))/((float)n));
+ }
+ }
+ printf("Avg bucket length %f\n", avg);
+ printf("Range of hash function: %d..%d\n", low, hi);
+}
+
+/*
+ * Given a string, this function allocates and returns a pointer to a
+ * symbol table record whose "symbol" pointer is reset to a position
+ * in the string table.
+ */
+
+#ifdef __USE_PROTOS
+Sym * zzs_new(char *text)
+#else
+Sym * zzs_new(text)
+char *text;
+#endif
+{
+ Sym *p;
+
+ if ( (p = (Sym *) calloc(1,sizeof(Sym))) == 0 )
+ {
+ fprintf(stderr,"Out of memory\n");
+ exit(1);
+ }
+ p->symbol = zzs_strdup(text);
+
+ return p;
+}
+
+/* create a new symbol table entry and add it to the symbol table */
+
+#ifdef __USE_PROTOS
+Sym * zzs_newadd(char *text)
+#else
+Sym * zzs_newadd(text)
+char *text;
+#endif
+{
+ Sym *p = zzs_new(text);
+ if ( p != NULL ) zzs_add(text, p);
+ return p;
+}
+
+/* Add a string to the string table and return a pointer to it.
+ * Bump the pointer into the string table to next avail position.
+ */
+
+#ifdef __USE_PROTOS
+char * zzs_strdup(char *s)
+#else
+char * zzs_strdup(s)
+register char *s;
+#endif
+{
+ register char *start=strp;
+
+ while ( *s != '\0' )
+ {
+ if ( strp >= &(strings[strsize-2]) )
+ {
+ fprintf(stderr, "sym: string table overflow (%d chars)\n", strsize);
+ exit(-1);
+ }
+ *strp++ = *s++;
+ }
+ *strp++ = '\0';
+
+ return( start );
+}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/template.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/template.h
new file mode 100644
index 00000000..49ce0660
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/Pccts/support/sym/template.h
@@ -0,0 +1,41 @@
+/* T e m p l a t e F o r S y m b o l T a b l e M a n a g e r */
+
+/* define some hash function */
+#ifndef HASH
+#define HASH(p, h) while ( *p != '\0' ) h = (h<<1) + *p++;
+#endif
+
+/* minimum symbol table record */
+typedef struct _sym {
+ char *symbol;
+ struct _sym *next, *prev, **head, *scope;
+ unsigned int hash;
+ } Sym, *SymPtr;
+
+#ifdef __USE_PROTOS
+void zzs_init(int, int);
+void zzs_done(void);
+void zzs_add(char *, Sym *);
+Sym *zzs_get(char *);
+void zzs_del(Sym *);
+void zzs_keydel(char *);
+Sym **zzs_scope(Sym **);
+Sym *zzs_rmscope(Sym **);
+void zzs_stat(void);
+Sym *zzs_new(char *);
+Sym *zzs_newadd(char *);
+char *zzs_strdup(char *);
+#else
+void zzs_init();
+void zzs_done();
+void zzs_add();
+Sym *zzs_get();
+void zzs_del();
+void zzs_keydel();
+Sym **zzs_scope();
+Sym *zzs_rmscope();
+void zzs_stat();
+Sym *zzs_new();
+Sym *zzs_newadd();
+char *zzs_strdup();
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
new file mode 100644
index 00000000..2bdd5cb4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
@@ -0,0 +1,941 @@
+/** @file
+
+ VfrCompiler main class and main function.
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "VfrCompiler.h"
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+
+PACKAGE_DATA gCBuffer;
+PACKAGE_DATA gRBuffer;
+CVfrStringDB gCVfrStringDB;
+
+VOID
+CVfrCompiler::DebugError (
+ IN CHAR8 *FileName,
+ IN UINT32 LineNumber,
+ IN UINT32 MessageCode,
+ IN CONST CHAR8 *Text,
+ IN CONST CHAR8 *MsgFmt,
+ ...
+ )
+{
+ va_list List;
+ va_start (List, MsgFmt);
+ PrintMessage ((CHAR8 *) "ERROR", FileName, LineNumber, MessageCode, (CHAR8 *) Text, (CHAR8 *) MsgFmt, List);
+ va_end (List);
+}
+
+VOID
+CVfrCompiler::SET_RUN_STATUS (
+ IN COMPILER_RUN_STATUS Status
+ )
+{
+ mRunStatus = Status;
+}
+
+BOOLEAN
+CVfrCompiler::IS_RUN_STATUS (
+ IN COMPILER_RUN_STATUS Status
+ )
+{
+ return mRunStatus == Status;
+}
+
+VOID
+CVfrCompiler::OptionInitialization (
+ IN INT32 Argc,
+ IN CHAR8 **Argv
+ )
+{
+ INT32 Index;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ SetUtilityName ((CHAR8*) PROGRAM_NAME);
+
+ mOptions.VfrFileName = NULL;
+ mOptions.RecordListFile = NULL;
+ mOptions.CreateRecordListFile = FALSE;
+ mOptions.CreateIfrPkgFile = FALSE;
+ mOptions.PkgOutputFileName = NULL;
+ mOptions.COutputFileName = NULL;
+ mOptions.OutputDirectory = NULL;
+ mOptions.PreprocessorOutputFileName = NULL;
+ mOptions.VfrBaseFileName = NULL;
+ mOptions.IncludePaths = NULL;
+ mOptions.SkipCPreprocessor = TRUE;
+ mOptions.CPreprocessorOptions = NULL;
+ mOptions.HasOverrideClassGuid = FALSE;
+ mOptions.WarningAsError = FALSE;
+ mOptions.AutoDefault = FALSE;
+ mOptions.CheckDefault = FALSE;
+ memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID));
+
+ if (Argc == 1) {
+ Usage ();
+ SET_RUN_STATUS (STATUS_DEAD);
+ return;
+ }
+
+ for (Index = 1; (Index < Argc) && (Argv[Index][0] == '-'); Index++) {
+ if ((stricmp(Argv[Index], "-h") == 0) || (stricmp(Argv[Index], "--help") == 0)) {
+ Usage ();
+ SET_RUN_STATUS (STATUS_DEAD);
+ return;
+ } else if (stricmp(Argv[Index], "--version") == 0) {
+ Version ();
+ SET_RUN_STATUS (STATUS_DEAD);
+ return;
+ } else if (stricmp(Argv[Index], "-l") == 0) {
+ mOptions.CreateRecordListFile = TRUE;
+ gCIfrRecordInfoDB.TurnOn ();
+ } else if (stricmp(Argv[Index], "-i") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ DebugError (NULL, 0, 1001, "Missing option", "-i missing path argument");
+ goto Fail;
+ }
+
+ AppendIncludePath(Argv[Index]);
+ } else if (stricmp(Argv[Index], "-o") == 0 || stricmp(Argv[Index], "--output-directory") == 0 || stricmp(Argv[Index], "-od") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ DebugError (NULL, 0, 1001, "Missing option", "-o missing output directory name");
+ goto Fail;
+ }
+
+ mOptions.OutputDirectory = (CHAR8 *) malloc (strlen (Argv[Index]) + strlen ("\\") + 1);
+ if (mOptions.OutputDirectory == NULL) {
+ DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
+ goto Fail;
+ }
+ strcpy (mOptions.OutputDirectory, Argv[Index]);
+
+ CHAR8 lastChar = mOptions.OutputDirectory[strlen(mOptions.OutputDirectory) - 1];
+ if ((lastChar != '/') && (lastChar != '\\')) {
+ if (strchr(mOptions.OutputDirectory, '/') != NULL) {
+ strcat (mOptions.OutputDirectory, "/");
+ } else {
+ strcat (mOptions.OutputDirectory, "\\");
+ }
+ }
+ DebugMsg (NULL, 0, 9, (CHAR8 *) "Output Directory", (CHAR8 *) "%s", mOptions.OutputDirectory);
+ } else if (stricmp(Argv[Index], "-b") == 0 || stricmp(Argv[Index], "--create-ifr-package") == 0 || stricmp(Argv[Index], "-ibin") == 0) {
+ mOptions.CreateIfrPkgFile = TRUE;
+ } else if (stricmp(Argv[Index], "-n") == 0 || stricmp(Argv[Index], "--no-pre-processing") == 0 || stricmp(Argv[Index], "-nopp") == 0) {
+ mOptions.SkipCPreprocessor = TRUE;
+ } else if (stricmp(Argv[Index], "-f") == 0 || stricmp(Argv[Index], "--pre-processing-flag") == 0 || stricmp(Argv[Index], "-ppflag") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ DebugError (NULL, 0, 1001, "Missing option", "-od - missing C-preprocessor argument");
+ goto Fail;
+ }
+
+ AppendCPreprocessorOptions (Argv[Index]);
+ } else if (stricmp(Argv[Index], "-s") == 0|| stricmp(Argv[Index], "--string-db") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ DebugError (NULL, 0, 1001, "Missing option", "-s missing input string file name");
+ goto Fail;
+ }
+ gCVfrStringDB.SetStringFileName(Argv[Index]);
+ DebugMsg (NULL, 0, 9, (CHAR8 *) "Input string file path", (CHAR8 *) "%s", Argv[Index]);
+ } else if ((stricmp (Argv[Index], "-g") == 0) || (stricmp (Argv[Index], "--guid") == 0)) {
+ Index++;
+ Status = StringToGuid (Argv[Index], &mOptions.OverrideClassGuid);
+ if (EFI_ERROR (Status)) {
+ DebugError (NULL, 0, 1000, "Invalid format:", "%s", Argv[Index]);
+ goto Fail;
+ }
+ mOptions.HasOverrideClassGuid = TRUE;
+ } else if (stricmp(Argv[Index], "-w") == 0 || stricmp(Argv[Index], "--warning-as-error") == 0) {
+ mOptions.WarningAsError = TRUE;
+ } else if (stricmp(Argv[Index], "-a") == 0 ||stricmp(Argv[Index], "--autodefault") == 0) {
+ mOptions.AutoDefault = TRUE;
+ } else if (stricmp(Argv[Index], "-d") == 0 ||stricmp(Argv[Index], "--checkdefault") == 0) {
+ mOptions.CheckDefault = TRUE;
+ } else {
+ DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]);
+ goto Fail;
+ }
+ }
+
+ if (Index != Argc - 1) {
+ DebugError (NULL, 0, 1001, "Missing option", "VFR file name is not specified.");
+ goto Fail;
+ } else {
+ mOptions.VfrFileName = (CHAR8 *) malloc (strlen (Argv[Index]) + 1);
+ if (mOptions.VfrFileName == NULL) {
+ DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
+ goto Fail;
+ }
+ strcpy (mOptions.VfrFileName, Argv[Index]);
+
+ if (mOptions.OutputDirectory == NULL) {
+ mOptions.OutputDirectory = (CHAR8 *) malloc (1);
+ if (mOptions.OutputDirectory == NULL) {
+ DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
+ goto Fail;
+ }
+ mOptions.OutputDirectory[0] = '\0';
+ }
+ }
+
+ if (SetBaseFileName() != 0) {
+ goto Fail;
+ }
+ if (SetPkgOutputFileName () != 0) {
+ goto Fail;
+ }
+ if (SetCOutputFileName() != 0) {
+ goto Fail;
+ }
+ if (SetPreprocessorOutputFileName () != 0) {
+ goto Fail;
+ }
+ if (SetRecordListFileName () != 0) {
+ goto Fail;
+ }
+ return;
+
+Fail:
+ SET_RUN_STATUS (STATUS_DEAD);
+
+ mOptions.CreateRecordListFile = FALSE;
+ mOptions.CreateIfrPkgFile = FALSE;
+
+ if (mOptions.VfrFileName != NULL) {
+ free (mOptions.VfrFileName);
+ mOptions.VfrFileName = NULL;
+ }
+ if (mOptions.VfrBaseFileName != NULL) {
+ free (mOptions.VfrBaseFileName);
+ mOptions.VfrBaseFileName = NULL;
+ }
+ if (mOptions.OutputDirectory != NULL) {
+ free (mOptions.OutputDirectory);
+ mOptions.OutputDirectory = NULL;
+ }
+ if (mOptions.PkgOutputFileName != NULL) {
+ free (mOptions.PkgOutputFileName);
+ mOptions.PkgOutputFileName = NULL;
+ }
+ if (mOptions.COutputFileName != NULL) {
+ free (mOptions.COutputFileName);
+ mOptions.COutputFileName = NULL;
+ }
+ if (mOptions.PreprocessorOutputFileName != NULL) {
+ free (mOptions.PreprocessorOutputFileName);
+ mOptions.PreprocessorOutputFileName = NULL;
+ }
+ if (mOptions.RecordListFile != NULL) {
+ free (mOptions.RecordListFile);
+ mOptions.RecordListFile = NULL;
+ }
+ if (mOptions.IncludePaths != NULL) {
+ delete mOptions.IncludePaths;
+ mOptions.IncludePaths = NULL;
+ }
+ if (mOptions.CPreprocessorOptions != NULL) {
+ delete mOptions.CPreprocessorOptions;
+ mOptions.CPreprocessorOptions = NULL;
+ }
+}
+
+VOID
+CVfrCompiler::AppendIncludePath (
+ IN CHAR8 *PathStr
+ )
+{
+ UINT32 Len = 0;
+ CHAR8 *IncludePaths = NULL;
+
+ Len = strlen (" -I ") + strlen (PathStr) + 1;
+ if (mOptions.IncludePaths != NULL) {
+ Len += strlen (mOptions.IncludePaths);
+ }
+ IncludePaths = new CHAR8[Len];
+ if (IncludePaths == NULL) {
+ DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
+ return;
+ }
+ IncludePaths[0] = '\0';
+ if (mOptions.IncludePaths != NULL) {
+ strcat (IncludePaths, mOptions.IncludePaths);
+ }
+ strcat (IncludePaths, " -I ");
+ strcat (IncludePaths, PathStr);
+ if (mOptions.IncludePaths != NULL) {
+ delete[] mOptions.IncludePaths;
+ }
+ mOptions.IncludePaths = IncludePaths;
+}
+
+VOID
+CVfrCompiler::AppendCPreprocessorOptions (
+ IN CHAR8 *Options
+ )
+{
+ UINT32 Len = 0;
+ CHAR8 *Opt = NULL;
+
+ Len = strlen (Options) + strlen (" ") + 1;
+ if (mOptions.CPreprocessorOptions != NULL) {
+ Len += strlen (mOptions.CPreprocessorOptions);
+ }
+ Opt = new CHAR8[Len];
+ if (Opt == NULL) {
+ DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
+ return;
+ }
+ Opt[0] = 0;
+ if (mOptions.CPreprocessorOptions != NULL) {
+ strcat (Opt, mOptions.CPreprocessorOptions);
+ }
+ strcat (Opt, " ");
+ strcat (Opt, Options);
+ if (mOptions.CPreprocessorOptions != NULL) {
+ delete[] mOptions.CPreprocessorOptions;
+ }
+ mOptions.CPreprocessorOptions = Opt;
+}
+
+INT8
+CVfrCompiler::SetBaseFileName (
+ VOID
+ )
+{
+ CHAR8 *pFileName, *pPath, *pExt;
+
+ if (mOptions.VfrFileName == NULL) {
+ return -1;
+ }
+
+ pFileName = mOptions.VfrFileName;
+ while (
+ ((pPath = strchr (pFileName, '\\')) != NULL) ||
+ ((pPath = strchr (pFileName, '/')) != NULL)
+ )
+ {
+ pFileName = pPath + 1;
+ }
+
+ if (pFileName == NULL) {
+ return -1;
+ }
+
+ if ((pExt = strchr (pFileName, '.')) == NULL) {
+ return -1;
+ }
+
+ *pExt = '\0';
+
+ mOptions.VfrBaseFileName = (CHAR8 *) malloc (strlen (pFileName) + 1);
+ if (mOptions.VfrBaseFileName == NULL) {
+ *pExt = '.';
+ return -1;
+ }
+
+ strcpy (mOptions.VfrBaseFileName, pFileName);
+ *pExt = '.';
+
+ return 0;
+}
+
+INT8
+CVfrCompiler::SetPkgOutputFileName (
+ VOID
+ )
+{
+ INTN Length;
+
+ if (mOptions.VfrBaseFileName == NULL) {
+ return -1;
+ }
+
+ Length = strlen (mOptions.OutputDirectory) +
+ strlen (mOptions.VfrBaseFileName) +
+ strlen (VFR_PACKAGE_FILENAME_EXTENSION) +
+ 1;
+
+ mOptions.PkgOutputFileName = (CHAR8 *) malloc (Length);
+ if (mOptions.PkgOutputFileName == NULL) {
+ return -1;
+ }
+
+ strcpy (mOptions.PkgOutputFileName, mOptions.OutputDirectory);
+ strcat (mOptions.PkgOutputFileName, mOptions.VfrBaseFileName);
+ strcat (mOptions.PkgOutputFileName, VFR_PACKAGE_FILENAME_EXTENSION);
+
+ return 0;
+}
+
+INT8
+CVfrCompiler::SetCOutputFileName (
+ VOID
+ )
+{
+ INTN Length;
+
+ if (mOptions.VfrBaseFileName == NULL) {
+ return -1;
+ }
+
+ Length = strlen (mOptions.OutputDirectory) +
+ strlen (mOptions.VfrBaseFileName) +
+ strlen (".c") +
+ 1;
+
+ mOptions.COutputFileName = (CHAR8 *) malloc (Length);
+ if (mOptions.COutputFileName == NULL) {
+ return -1;
+ }
+
+ strcpy (mOptions.COutputFileName, mOptions.OutputDirectory);
+ strcat (mOptions.COutputFileName, mOptions.VfrBaseFileName);
+ strcat (mOptions.COutputFileName, ".c");
+
+ return 0;
+}
+
+INT8
+CVfrCompiler::SetPreprocessorOutputFileName (
+ VOID
+ )
+{
+ INTN Length;
+
+ if (mOptions.VfrBaseFileName == NULL) {
+ return -1;
+ }
+
+ Length = strlen (mOptions.OutputDirectory) +
+ strlen (mOptions.VfrBaseFileName) +
+ strlen (VFR_PREPROCESS_FILENAME_EXTENSION) +
+ 1;
+
+ mOptions.PreprocessorOutputFileName = (CHAR8 *) malloc (Length);
+ if (mOptions.PreprocessorOutputFileName == NULL) {
+ return -1;
+ }
+
+ strcpy (mOptions.PreprocessorOutputFileName, mOptions.OutputDirectory);
+ strcat (mOptions.PreprocessorOutputFileName, mOptions.VfrBaseFileName);
+ strcat (mOptions.PreprocessorOutputFileName, VFR_PREPROCESS_FILENAME_EXTENSION);
+
+ return 0;
+}
+
+INT8
+CVfrCompiler::SetRecordListFileName (
+ VOID
+ )
+{
+ INTN Length;
+
+ if (mOptions.VfrBaseFileName == NULL) {
+ return -1;
+ }
+
+ Length = strlen (mOptions.OutputDirectory) +
+ strlen (mOptions.VfrBaseFileName) +
+ strlen (VFR_RECORDLIST_FILENAME_EXTENSION) +
+ 1;
+
+ mOptions.RecordListFile = (CHAR8 *) malloc (Length);
+ if (mOptions.RecordListFile == NULL) {
+ return -1;
+ }
+
+ strcpy (mOptions.RecordListFile, mOptions.OutputDirectory);
+ strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName);
+ strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION);
+
+ return 0;
+}
+
+CVfrCompiler::CVfrCompiler (
+ IN INT32 Argc,
+ IN CHAR8 **Argv
+ )
+{
+ mPreProcessCmd = (CHAR8 *) PREPROCESSOR_COMMAND;
+ mPreProcessOpt = (CHAR8 *) PREPROCESSOR_OPTIONS;
+
+ SET_RUN_STATUS (STATUS_STARTED);
+
+ OptionInitialization(Argc, Argv);
+
+ if ((IS_RUN_STATUS(STATUS_FAILED)) || (IS_RUN_STATUS(STATUS_DEAD))) {
+ return;
+ }
+
+ SET_RUN_STATUS(STATUS_INITIALIZED);
+}
+
+CVfrCompiler::~CVfrCompiler (
+ VOID
+ )
+{
+ if (mOptions.VfrFileName != NULL) {
+ free (mOptions.VfrFileName);
+ mOptions.VfrFileName = NULL;
+ }
+
+ if (mOptions.VfrBaseFileName != NULL) {
+ free (mOptions.VfrBaseFileName);
+ mOptions.VfrBaseFileName = NULL;
+ }
+
+ if (mOptions.OutputDirectory != NULL) {
+ free (mOptions.OutputDirectory);
+ mOptions.OutputDirectory = NULL;
+ }
+
+ if (mOptions.PkgOutputFileName != NULL) {
+ free (mOptions.PkgOutputFileName);
+ mOptions.PkgOutputFileName = NULL;
+ }
+
+ if (mOptions.COutputFileName != NULL) {
+ free (mOptions.COutputFileName);
+ mOptions.COutputFileName = NULL;
+ }
+
+ if (mOptions.PreprocessorOutputFileName != NULL) {
+ free (mOptions.PreprocessorOutputFileName);
+ mOptions.PreprocessorOutputFileName = NULL;
+ }
+
+ if (mOptions.RecordListFile != NULL) {
+ free (mOptions.RecordListFile);
+ mOptions.RecordListFile = NULL;
+ }
+
+ if (mOptions.IncludePaths != NULL) {
+ delete[] mOptions.IncludePaths;
+ mOptions.IncludePaths = NULL;
+ }
+
+ if (mOptions.CPreprocessorOptions != NULL) {
+ delete[] mOptions.CPreprocessorOptions;
+ mOptions.CPreprocessorOptions = NULL;
+ }
+
+ SET_RUN_STATUS(STATUS_DEAD);
+}
+
+VOID
+CVfrCompiler::Usage (
+ VOID
+ )
+{
+ UINT32 Index;
+ CONST CHAR8 *Help[] = {
+ " ",
+ "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION,
+ "Copyright (c) 2004-2016 Intel Corporation. All rights reserved.",
+ " ",
+ "Usage: VfrCompile [options] VfrFile",
+ " ",
+ "Options:",
+ " -h, --help prints this help",
+ " --version prints version info",
+ " -l create an output IFR listing file",
+ " -o DIR, --output-directory DIR",
+ " deposit all output files to directory OutputDir",
+ " default is current directory",
+ " -b, --create-ifr-package",
+ " create an IFR HII pack file",
+ " -n, --no-pre-processing",
+ " do not preprocessing input file",
+ " -s, --string-db",
+ " input uni string package file",
+ " -g, --guid",
+ " override class guid input",
+ " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ " -w --warning-as-error",
+ " treat warning as an error",
+ " -a --autodefaut generate default value for question opcode if some default is missing",
+ " -d --checkdefault check the default information in a question opcode",
+ NULL
+ };
+ for (Index = 0; Help[Index] != NULL; Index++) {
+ fprintf (stdout, "%s\n", Help[Index]);
+ }
+}
+
+VOID
+CVfrCompiler::Version (
+ VOID
+ )
+{
+ UINT32 Index;
+ CONST CHAR8 *Help[] = {
+ "VfrCompile version " VFR_COMPILER_VERSION "Build " __BUILD_VERSION,
+ NULL
+ };
+ for (Index = 0; Help[Index] != NULL; Index++) {
+ fprintf (stdout, "%s\n", Help[Index]);
+ }
+}
+
+VOID
+CVfrCompiler::PreProcess (
+ VOID
+ )
+{
+ FILE *pVfrFile = NULL;
+ UINT32 CmdLen = 0;
+ CHAR8 *PreProcessCmd = NULL;
+
+ if (!IS_RUN_STATUS(STATUS_INITIALIZED)) {
+ goto Fail;
+ }
+
+ if (mOptions.SkipCPreprocessor == TRUE) {
+ goto Out;
+ }
+
+ if ((pVfrFile = fopen (LongFilePath (mOptions.VfrFileName), "r")) == NULL) {
+ DebugError (NULL, 0, 0001, "Error opening the input VFR file", "%s", mOptions.VfrFileName);
+ goto Fail;
+ }
+ fclose (pVfrFile);
+
+ CmdLen = strlen (mPreProcessCmd) + strlen (mPreProcessOpt) +
+ strlen (mOptions.VfrFileName) + strlen (mOptions.PreprocessorOutputFileName);
+ if (mOptions.CPreprocessorOptions != NULL) {
+ CmdLen += strlen (mOptions.CPreprocessorOptions);
+ }
+ if (mOptions.IncludePaths != NULL) {
+ CmdLen += strlen (mOptions.IncludePaths);
+ }
+
+ PreProcessCmd = new CHAR8[CmdLen + 10];
+ if (PreProcessCmd == NULL) {
+ DebugError (NULL, 0, 4001, "Resource: memory can't be allocated", NULL);
+ goto Fail;
+ }
+ strcpy (PreProcessCmd, mPreProcessCmd), strcat (PreProcessCmd, " ");
+ strcat (PreProcessCmd, mPreProcessOpt), strcat (PreProcessCmd, " ");
+ if (mOptions.IncludePaths != NULL) {
+ strcat (PreProcessCmd, mOptions.IncludePaths), strcat (PreProcessCmd, " ");
+ }
+ if (mOptions.CPreprocessorOptions != NULL) {
+ strcat (PreProcessCmd, mOptions.CPreprocessorOptions), strcat (PreProcessCmd, " ");
+ }
+ strcat (PreProcessCmd, mOptions.VfrFileName), strcat (PreProcessCmd, " > ");
+ strcat (PreProcessCmd, mOptions.PreprocessorOutputFileName);
+
+ if (system (PreProcessCmd) != 0) {
+ DebugError (NULL, 0, 0003, "Error parsing file", "failed to spawn C preprocessor on VFR file %s\n", PreProcessCmd);
+ goto Fail;
+ }
+
+ delete[] PreProcessCmd;
+
+Out:
+ SET_RUN_STATUS (STATUS_PREPROCESSED);
+ return;
+
+Fail:
+ if (!IS_RUN_STATUS(STATUS_DEAD)) {
+ SET_RUN_STATUS (STATUS_FAILED);
+ }
+ delete[] PreProcessCmd;
+}
+
+extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *);
+
+VOID
+CVfrCompiler::Compile (
+ VOID
+ )
+{
+ FILE *pInFile = NULL;
+ CHAR8 *InFileName = NULL;
+ INPUT_INFO_TO_SYNTAX InputInfo;
+
+ if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {
+ goto Fail;
+ }
+
+ InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;
+
+ gCVfrErrorHandle.SetInputFile (InFileName);
+ gCVfrErrorHandle.SetWarningAsError(mOptions.WarningAsError);
+
+ if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) {
+ DebugError (NULL, 0, 0001, "Error opening the input file", "%s", InFileName);
+ goto Fail;
+ }
+
+ if (mOptions.HasOverrideClassGuid) {
+ InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid;
+ } else {
+ InputInfo.OverrideClassGuid = NULL;
+ }
+
+ if (VfrParserStart (pInFile, &InputInfo) != 0) {
+ goto Fail;
+ }
+
+ fclose (pInFile);
+ pInFile = NULL;
+
+ if (gCFormPkg.HavePendingUnassigned () == TRUE) {
+ gCFormPkg.PendingAssignPrintAll ();
+ goto Fail;
+ }
+
+ SET_RUN_STATUS (STATUS_COMPILEED);
+ return;
+
+Fail:
+ if (!IS_RUN_STATUS(STATUS_DEAD)) {
+ DebugError (NULL, 0, 0003, "Error parsing", "compile error in file %s", InFileName);
+ SET_RUN_STATUS (STATUS_FAILED);
+ }
+ if (pInFile != NULL) {
+ fclose (pInFile);
+ }
+}
+
+VOID
+CVfrCompiler::AdjustBin (
+ VOID
+ )
+{
+ EFI_VFR_RETURN_CODE Status;
+
+ if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
+ return;
+ }
+
+ if (gNeedAdjustOpcode) {
+ //
+ // When parsing the Vfr, has created some opcodes, now need to update the record info.
+ //
+ gCIfrRecordInfoDB.IfrUpdateRecordInfoForDynamicOpcode (FALSE);
+ }
+
+ //
+ // Check whether need to check default info for question or auto add default for question.
+ //
+ if (mOptions.AutoDefault || mOptions.CheckDefault) {
+ gCIfrRecordInfoDB.IfrCheckAddDefaultRecord (mOptions.AutoDefault, mOptions.CheckDefault);
+ }
+
+ //
+ // Check Binary Code consistent between Form and IfrRecord
+ //
+
+ //
+ // Get Package Data and IfrRecord Data
+ //
+ gCFormPkg.BuildPkg (gCBuffer);
+ gCIfrRecordInfoDB.IfrRecordOutput (gRBuffer);
+
+ //
+ // Compare Form and Record data
+ //
+ if (gCBuffer.Buffer != NULL && gRBuffer.Buffer != NULL) {
+ UINT32 Index;
+ if (gCBuffer.Size != gRBuffer.Size) {
+ DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. FormBinary Size 0x%X is not same to RecordBuffer Size 0x%X", mOptions.VfrFileName, gCBuffer.Size, gRBuffer.Size);
+ }
+ for (Index = 0; Index < gCBuffer.Size; Index ++) {
+ if (gCBuffer.Buffer[Index] != gRBuffer.Buffer[Index]) {
+ break;
+ }
+ }
+ if (Index != gCBuffer.Size) {
+ DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s. the 0x%X byte is different between Form and Record", mOptions.VfrFileName, Index);
+ }
+ DebugMsg (NULL, 0, 9, (CHAR8 *) "IFR Buffer", (CHAR8 *) "Form Buffer same to Record Buffer and Size is 0x%X", Index);
+ } else if (gCBuffer.Buffer == NULL && gRBuffer.Buffer == NULL) {
+ //ok
+ } else {
+ DebugError (NULL, 0, 0001, "Error parsing vfr file", " %s.Buffer not allocated.", mOptions.VfrFileName);
+ }
+
+ return;
+}
+
+VOID
+CVfrCompiler::GenBinary (
+ VOID
+ )
+{
+ FILE *pFile = NULL;
+
+ if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
+ goto Fail;
+ }
+
+ if (mOptions.CreateIfrPkgFile == TRUE) {
+ if ((pFile = fopen (LongFilePath (mOptions.PkgOutputFileName), "wb")) == NULL) {
+ DebugError (NULL, 0, 0001, "Error opening file", "%s", mOptions.PkgOutputFileName);
+ goto Fail;
+ }
+ if (gCFormPkg.BuildPkg (pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {
+ fclose (pFile);
+ goto Fail;
+ }
+ fclose (pFile);
+ }
+
+ SET_RUN_STATUS (STATUS_GENBINARY);
+
+ return;
+
+Fail:
+ if (!IS_RUN_STATUS(STATUS_DEAD)) {
+ SET_RUN_STATUS (STATUS_FAILED);
+ }
+}
+
+static const char *gSourceFileHeader[] = {
+ "//",
+ "// DO NOT EDIT -- auto-generated file",
+ "//",
+ "// This file is generated by the vfrcompiler utility",
+ "//",
+ NULL
+};
+
+VOID
+CVfrCompiler::GenCFile (
+ VOID
+ )
+{
+ FILE *pFile;
+ UINT32 Index;
+
+ if (!IS_RUN_STATUS(STATUS_GENBINARY)) {
+ goto Fail;
+ }
+
+ if (!mOptions.CreateIfrPkgFile) {
+ if ((pFile = fopen (LongFilePath (mOptions.COutputFileName), "w")) == NULL) {
+ DebugError (NULL, 0, 0001, "Error opening output C file", "%s", mOptions.COutputFileName);
+ goto Fail;
+ }
+
+ for (Index = 0; gSourceFileHeader[Index] != NULL; Index++) {
+ fprintf (pFile, "%s\n", gSourceFileHeader[Index]);
+ }
+
+ if (gCFormPkg.GenCFile (mOptions.VfrBaseFileName, pFile, &gRBuffer) != VFR_RETURN_SUCCESS) {
+ fclose (pFile);
+ goto Fail;
+ }
+ fclose (pFile);
+ }
+
+ SET_RUN_STATUS (STATUS_FINISHED);
+ return;
+
+Fail:
+ if (!IS_RUN_STATUS(STATUS_DEAD)) {
+ SET_RUN_STATUS (STATUS_FAILED);
+ }
+}
+
+VOID
+CVfrCompiler::GenRecordListFile (
+ VOID
+ )
+{
+ CHAR8 *InFileName = NULL;
+ FILE *pInFile = NULL;
+ FILE *pOutFile = NULL;
+ CHAR8 LineBuf[MAX_VFR_LINE_LEN];
+ UINT32 LineNo;
+
+ InFileName = (mOptions.SkipCPreprocessor == TRUE) ? mOptions.VfrFileName : mOptions.PreprocessorOutputFileName;
+
+ if (mOptions.CreateRecordListFile == TRUE && InFileName != NULL && mOptions.RecordListFile != NULL) {
+ if ((InFileName[0] == '\0') || (mOptions.RecordListFile[0] == '\0')) {
+ return;
+ }
+
+ if ((pInFile = fopen (LongFilePath (InFileName), "r")) == NULL) {
+ DebugError (NULL, 0, 0001, "Error opening the input VFR preprocessor output file", "%s", InFileName);
+ return;
+ }
+
+ if ((pOutFile = fopen (LongFilePath (mOptions.RecordListFile), "w")) == NULL) {
+ DebugError (NULL, 0, 0001, "Error opening the record list file", "%s", mOptions.RecordListFile);
+ goto Err1;
+ }
+
+ fprintf (pOutFile, "//\n// VFR compiler version " VFR_COMPILER_VERSION __BUILD_VERSION "\n//\n");
+ LineNo = 0;
+ while (!feof (pInFile)) {
+ if (fgets (LineBuf, MAX_VFR_LINE_LEN, pInFile) != NULL) {
+ fprintf (pOutFile, "%s", LineBuf);
+ LineNo++;
+ gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, LineNo);
+ }
+ }
+
+ fprintf (pOutFile, "\n//\n// All Opcode Record List \n//\n");
+ gCIfrRecordInfoDB.IfrRecordOutput (pOutFile, 0);
+ gCVfrVarDataTypeDB.Dump(pOutFile);
+
+ fclose (pOutFile);
+ fclose (pInFile);
+ }
+
+ return;
+
+Err1:
+ fclose (pInFile);
+}
+
+int
+main (
+ IN int Argc,
+ IN char **Argv
+ )
+{
+ COMPILER_RUN_STATUS Status;
+
+ SetPrintLevel(WARNING_LOG_LEVEL);
+ CVfrCompiler Compiler(Argc, Argv);
+
+ Compiler.PreProcess();
+ Compiler.Compile();
+ Compiler.AdjustBin();
+ Compiler.GenBinary();
+ Compiler.GenCFile();
+ Compiler.GenRecordListFile ();
+
+ Status = Compiler.RunStatus ();
+ if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) {
+ return 2;
+ }
+
+ if (gCBuffer.Buffer != NULL) {
+ delete[] gCBuffer.Buffer;
+ }
+
+ if (gRBuffer.Buffer != NULL) {
+ delete[] gRBuffer.Buffer;
+ }
+
+ return GetUtilityStatus ();
+}
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.h
new file mode 100644
index 00000000..ce10a58b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrCompiler.h
@@ -0,0 +1,108 @@
+/** @file
+
+ VfrCompiler internal definitions.
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _VFRCOMPILER_H_
+#define _VFRCOMPILER_H_
+
+#include "Common/UefiBaseTypes.h"
+#include "EfiVfr.h"
+#include "VfrFormPkg.h"
+#include "VfrUtilityLib.h"
+#include "ParseInf.h"
+
+#define PROGRAM_NAME "VfrCompile"
+#define VFR_COMPILER_VERSION " 2.01 (UEFI 2.4) "
+//
+// This is how we invoke the C preprocessor on the VFR source file
+// to resolve #defines, #includes, etc. To make C source files
+// shareable between VFR and drivers, define VFRCOMPILE so that
+// #ifdefs can be used in shared .h files.
+//
+#define PREPROCESSOR_COMMAND "cl "
+#define PREPROCESSOR_OPTIONS "/nologo /E /TC /DVFRCOMPILE "
+
+//
+// Specify the filename extensions for the files we generate.
+//
+#define VFR_PREPROCESS_FILENAME_EXTENSION ".i"
+#define VFR_PACKAGE_FILENAME_EXTENSION ".hpk"
+#define VFR_RECORDLIST_FILENAME_EXTENSION ".lst"
+
+typedef struct {
+ CHAR8 *VfrFileName;
+ CHAR8 *RecordListFile;
+ CHAR8 *PkgOutputFileName;
+ CHAR8 *COutputFileName;
+ bool CreateRecordListFile;
+ bool CreateIfrPkgFile;
+ CHAR8 *OutputDirectory;
+ CHAR8 *PreprocessorOutputFileName;
+ CHAR8 *VfrBaseFileName; // name of input VFR file with no path or extension
+ CHAR8 *IncludePaths;
+ bool SkipCPreprocessor;
+ CHAR8 *CPreprocessorOptions;
+ BOOLEAN HasOverrideClassGuid;
+ EFI_GUID OverrideClassGuid;
+ BOOLEAN WarningAsError;
+ BOOLEAN AutoDefault;
+ BOOLEAN CheckDefault;
+} OPTIONS;
+
+typedef enum {
+ STATUS_STARTED = 0,
+ STATUS_INITIALIZED,
+ STATUS_PREPROCESSED,
+ STATUS_COMPILEED,
+ STATUS_GENBINARY,
+ STATUS_FINISHED,
+ STATUS_FAILED,
+ STATUS_DEAD,
+} COMPILER_RUN_STATUS;
+
+class CVfrCompiler {
+private:
+ COMPILER_RUN_STATUS mRunStatus;
+ OPTIONS mOptions;
+ CHAR8 *mPreProcessCmd;
+ CHAR8 *mPreProcessOpt;
+
+ VOID OptionInitialization (IN INT32 , IN CHAR8 **);
+ VOID AppendIncludePath (IN CHAR8 *);
+ VOID AppendCPreprocessorOptions (IN CHAR8 *);
+ INT8 SetBaseFileName (VOID);
+ INT8 SetPkgOutputFileName (VOID);
+ INT8 SetCOutputFileName(VOID);
+ INT8 SetPreprocessorOutputFileName (VOID);
+ INT8 SetRecordListFileName (VOID);
+
+ VOID SET_RUN_STATUS (IN COMPILER_RUN_STATUS);
+ BOOLEAN IS_RUN_STATUS (IN COMPILER_RUN_STATUS);
+
+public:
+ COMPILER_RUN_STATUS RunStatus (VOID) {
+ return mRunStatus;
+ }
+
+public:
+ CVfrCompiler (IN INT32 , IN CHAR8 **);
+ ~CVfrCompiler ();
+
+ VOID Usage (VOID);
+ VOID Version (VOID);
+
+ VOID PreProcess (VOID);
+ VOID Compile (VOID);
+ VOID AdjustBin (VOID);
+ VOID GenBinary (VOID);
+ VOID GenCFile (VOID);
+ VOID GenRecordListFile (VOID);
+ VOID DebugError (IN CHAR8*, IN UINT32, IN UINT32, IN CONST CHAR8*, IN CONST CHAR8*, ...);
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.cpp
new file mode 100644
index 00000000..46055604
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.cpp
@@ -0,0 +1,297 @@
+/** @file
+
+ VfrCompiler error handler.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "stdio.h"
+#include "string.h"
+#include "stdlib.h"
+#include "VfrError.h"
+#include "EfiUtilityMsgs.h"
+
+static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = {
+ { VFR_RETURN_SUCCESS, NULL },
+ { VFR_RETURN_ERROR_SKIPED, NULL },
+ { VFR_RETURN_FATAL_ERROR, ": fatal error!!" },
+
+ { VFR_RETURN_MISMATCHED, ": unexpected token" },
+ { VFR_RETURN_INVALID_PARAMETER, ": invalid parameter" },
+ { VFR_RETURN_OUT_FOR_RESOURCES, ": system out of memory" },
+ { VFR_RETURN_UNSUPPORTED, ": unsupported" },
+ { VFR_RETURN_REDEFINED, ": already defined" },
+ { VFR_RETURN_FORMID_REDEFINED, ": form id already defined" },
+ { VFR_RETURN_QUESTIONID_REDEFINED, ": question id already defined" },
+ { VFR_RETURN_VARSTOREID_REDEFINED, ": varstore id already defined" },
+ { VFR_RETURN_UNDEFINED, ": undefined" },
+ { VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, ": some variable has not defined by a question"},
+ { VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR, ": Data Structure is defined by more than one varstores, it can't be referred as varstore, only varstore name could be used."},
+ { VFR_RETURN_GET_EFIVARSTORE_ERROR, ": get efi varstore error"},
+ { VFR_RETURN_EFIVARSTORE_USE_ERROR, ": can not use the efi varstore like this" },
+ { VFR_RETURN_EFIVARSTORE_SIZE_ERROR, ": unsupport efi varstore size should be <= 8 bytes" },
+ { VFR_RETURN_GET_NVVARSTORE_ERROR, ": get name value varstore error" },
+ { VFR_RETURN_QVAR_REUSE, ": variable reused by more than one question" },
+ { VFR_RETURN_FLAGS_UNSUPPORTED, ": flags unsupported" },
+ { VFR_RETURN_ERROR_ARRARY_NUM, ": array number error, the valid value is in (0 ~ MAX_INDEX-1) for UEFI vfr and in (1 ~ MAX_INDEX) for Framework Vfr" },
+ { VFR_RETURN_DATA_STRING_ERROR, ": data field string error or not support"},
+ { VFR_RETURN_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},
+ { VFR_RETURN_CONSTANT_ONLY, ": only constant is allowed in the expression"},
+ { VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR, ": Varstore name is defined by more than one varstores, it can't be referred as varstore, only varstore structure name could be used."},
+ { VFR_RETURN_BIT_WIDTH_ERROR, ": bit width must be <= sizeof (type) * 8 and the max width can not > 32" },
+ { VFR_RETURN_STRING_TO_UINT_OVERFLOW, ": String to UINT* Overflow"},
+ { VFR_RETURN_CODEUNDEFINED, ": undefined Error Code" }
+};
+
+static SVFR_WARNING_HANDLE VFR_WARNING_HANDLE_TABLE [] = {
+ { VFR_WARNING_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},
+ { VFR_WARNING_ACTION_WITH_TEXT_TWO, ": Action opcode should not have TextTwo part"},
+ { VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE, ": Not recommend to use obsoleted framework opcode"},
+ { VFR_WARNING_CODEUNDEFINED, ": undefined Warning Code" }
+};
+
+CVfrErrorHandle::CVfrErrorHandle (
+ VOID
+ )
+{
+ mInputFileName = NULL;
+ mScopeRecordListHead = NULL;
+ mScopeRecordListTail = NULL;
+ mVfrErrorHandleTable = VFR_ERROR_HANDLE_TABLE;
+ mVfrWarningHandleTable = VFR_WARNING_HANDLE_TABLE;
+ mWarningAsError = FALSE;
+}
+
+CVfrErrorHandle::~CVfrErrorHandle (
+ VOID
+ )
+{
+ SVfrFileScopeRecord *pNode = NULL;
+
+ if (mInputFileName != NULL) {
+ delete[] mInputFileName;
+ }
+
+ while (mScopeRecordListHead != NULL) {
+ pNode = mScopeRecordListHead;
+ mScopeRecordListHead = mScopeRecordListHead->mNext;
+ delete pNode;
+ }
+
+ mScopeRecordListHead = NULL;
+ mScopeRecordListTail = NULL;
+ mVfrErrorHandleTable = NULL;
+ mVfrWarningHandleTable = NULL;
+}
+
+VOID
+CVfrErrorHandle::SetWarningAsError (
+ IN BOOLEAN WarningAsError
+ )
+{
+ mWarningAsError = WarningAsError;
+}
+
+VOID
+CVfrErrorHandle::SetInputFile (
+ IN CHAR8 *InputFile
+ )
+{
+ if (InputFile != NULL) {
+ mInputFileName = new CHAR8[strlen(InputFile) + 1];
+ strcpy (mInputFileName, InputFile);
+ }
+}
+
+SVfrFileScopeRecord::SVfrFileScopeRecord (
+ IN CHAR8 *Record,
+ IN UINT32 LineNum
+ )
+{
+ UINT32 Index;
+ CHAR8 *FileName = NULL;
+ CHAR8 *Str = NULL;
+
+ mWholeScopeLine = LineNum;
+ mNext = NULL;
+
+ Str = strchr (Record, ' ');
+ mScopeLineStart = atoi (++Str);
+
+ Str = strchr (Str, '\"');
+ FileName = ++Str;
+
+ while((Str = strstr (FileName, "\\\\")) != NULL) {
+ FileName = Str + 2;
+ }
+ if ((mFileName = new CHAR8[strlen(FileName)]) != NULL) {
+ for (Index = 0; FileName[Index] != '\"'; Index++) {
+ mFileName[Index] = FileName[Index];
+ }
+ mFileName[Index] = '\0';
+ }
+
+ return;
+}
+
+SVfrFileScopeRecord::~SVfrFileScopeRecord (
+ VOID
+ )
+{
+ if (mFileName != NULL) {
+ delete[] mFileName;
+ }
+}
+
+VOID
+CVfrErrorHandle::ParseFileScopeRecord (
+ IN CHAR8 *Record,
+ IN UINT32 WholeScopeLine
+ )
+{
+ SVfrFileScopeRecord *pNode = NULL;
+
+ if (Record == NULL) {
+ return;
+ }
+
+ if ((pNode = new SVfrFileScopeRecord(Record, WholeScopeLine)) == NULL) {
+ return;
+ }
+
+ if (mScopeRecordListHead == NULL) {
+ mScopeRecordListTail = mScopeRecordListHead = pNode;
+ } else {
+ mScopeRecordListTail->mNext = pNode;
+ mScopeRecordListTail = pNode;
+ }
+}
+
+VOID
+CVfrErrorHandle::GetFileNameLineNum (
+ IN UINT32 LineNum,
+ OUT CHAR8 **FileName,
+ OUT UINT32 *FileLine
+ )
+{
+ SVfrFileScopeRecord *pNode = NULL;
+
+ if ((FileName == NULL) || (FileLine == NULL)) {
+ return;
+ }
+
+ *FileName = NULL;
+ *FileLine = 0xFFFFFFFF;
+
+ //
+ // Some errors occur before scope record list been built.
+ //
+ if (mScopeRecordListHead == NULL) {
+ *FileLine = LineNum;
+ *FileName = mInputFileName;
+ return ;
+ }
+
+ for (pNode = mScopeRecordListHead; pNode->mNext != NULL; pNode = pNode->mNext) {
+ if ((LineNum > pNode->mWholeScopeLine) && (pNode->mNext->mWholeScopeLine > LineNum)) {
+ *FileName = pNode->mFileName;
+ *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;
+ return ;
+ }
+ }
+
+ *FileName = pNode->mFileName;
+ *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;
+}
+
+VOID
+CVfrErrorHandle::PrintMsg (
+ IN UINT32 LineNum,
+ IN CHAR8 *TokName,
+ IN CONST CHAR8 *MsgType,
+ IN CONST CHAR8 *ErrorMsg
+ )
+{
+ CHAR8 *FileName = NULL;
+ UINT32 FileLine;
+
+ if (strncmp ("Warning", MsgType, strlen ("Warning")) == 0) {
+ VerboseMsg ((CHAR8 *) ErrorMsg);
+ return;
+ }
+ GetFileNameLineNum (LineNum, &FileName, &FileLine);
+ Error (FileName, FileLine, 0x3000, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) ErrorMsg);
+}
+
+UINT8
+CVfrErrorHandle::HandleError (
+ IN EFI_VFR_RETURN_CODE ErrorCode,
+ IN UINT32 LineNum,
+ IN CHAR8 *TokName
+ )
+{
+ UINT32 Index;
+ CHAR8 *FileName = NULL;
+ UINT32 FileLine;
+ CONST CHAR8 *ErrorMsg = NULL;
+
+ if (mVfrErrorHandleTable == NULL) {
+ return 1;
+ }
+
+ for (Index = 0; mVfrErrorHandleTable[Index].mErrorCode != VFR_RETURN_CODEUNDEFINED; Index++) {
+ if (ErrorCode == mVfrErrorHandleTable[Index].mErrorCode) {
+ ErrorMsg = mVfrErrorHandleTable[Index].mErrorMsg;
+ break;
+ }
+ }
+
+ if (ErrorMsg != NULL) {
+ GetFileNameLineNum (LineNum, &FileName, &FileLine);
+ Error (FileName, FileLine, 0x3000, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) ErrorMsg);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+UINT8
+CVfrErrorHandle::HandleWarning (
+ IN EFI_VFR_WARNING_CODE WarningCode,
+ IN UINT32 LineNum,
+ IN CHAR8 *TokName
+ )
+{
+ UINT32 Index;
+ CHAR8 *FileName = NULL;
+ UINT32 FileLine;
+ CONST CHAR8 *WarningMsg = NULL;
+
+ if (mVfrWarningHandleTable == NULL) {
+ return 1;
+ }
+
+ GetFileNameLineNum (LineNum, &FileName, &FileLine);
+
+ if (mWarningAsError) {
+ Error (FileName, FileLine, 0x2220, (CHAR8 *) "warning treated as error", NULL);
+ }
+
+ for (Index = 0; mVfrWarningHandleTable[Index].mWarningCode != VFR_WARNING_CODEUNDEFINED; Index++) {
+ if (WarningCode == mVfrWarningHandleTable[Index].mWarningCode) {
+ WarningMsg = mVfrWarningHandleTable[Index].mWarningMsg;
+ break;
+ }
+ }
+
+ if (WarningMsg != NULL) {
+ Warning (FileName, FileLine, 0, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) WarningMsg);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+CVfrErrorHandle gCVfrErrorHandle;
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.h
new file mode 100644
index 00000000..04a26d93
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrError.h
@@ -0,0 +1,107 @@
+/** @file
+
+ VfrCompiler Error definition
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _VFRERROR_H_
+#define _VFRERROR_H_
+
+#include "Common/UefiBaseTypes.h"
+
+typedef enum {
+ VFR_RETURN_SUCCESS = 0,
+ VFR_RETURN_ERROR_SKIPED,
+ VFR_RETURN_FATAL_ERROR,
+ VFR_RETURN_MISMATCHED,
+ VFR_RETURN_INVALID_PARAMETER,
+ VFR_RETURN_OUT_FOR_RESOURCES,
+ VFR_RETURN_UNSUPPORTED,
+ VFR_RETURN_REDEFINED,
+ VFR_RETURN_FORMID_REDEFINED,
+ VFR_RETURN_QUESTIONID_REDEFINED,
+ VFR_RETURN_VARSTOREID_REDEFINED,
+ VFR_RETURN_UNDEFINED,
+ VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION,
+ VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR,
+ VFR_RETURN_GET_EFIVARSTORE_ERROR,
+ VFR_RETURN_EFIVARSTORE_USE_ERROR,
+ VFR_RETURN_EFIVARSTORE_SIZE_ERROR,
+ VFR_RETURN_GET_NVVARSTORE_ERROR,
+ VFR_RETURN_QVAR_REUSE,
+ VFR_RETURN_FLAGS_UNSUPPORTED,
+ VFR_RETURN_ERROR_ARRARY_NUM,
+ VFR_RETURN_DATA_STRING_ERROR,
+ VFR_RETURN_DEFAULT_VALUE_REDEFINED,
+ VFR_RETURN_CONSTANT_ONLY,
+ VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR,
+ VFR_RETURN_BIT_WIDTH_ERROR,
+ VFR_RETURN_STRING_TO_UINT_OVERFLOW,
+ VFR_RETURN_CODEUNDEFINED
+} EFI_VFR_RETURN_CODE;
+
+typedef enum {
+ VFR_WARNING_DEFAULT_VALUE_REDEFINED = 0,
+ VFR_WARNING_ACTION_WITH_TEXT_TWO,
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ VFR_WARNING_CODEUNDEFINED
+} EFI_VFR_WARNING_CODE;
+
+typedef struct _SVFR_ERROR_HANDLE {
+ EFI_VFR_RETURN_CODE mErrorCode;
+ CONST CHAR8 *mErrorMsg;
+} SVFR_ERROR_HANDLE;
+
+typedef struct _SVFR_WARNING_HANDLE {
+ EFI_VFR_WARNING_CODE mWarningCode;
+ CONST CHAR8 *mWarningMsg;
+} SVFR_WARNING_HANDLE;
+
+struct SVfrFileScopeRecord {
+ CHAR8 *mFileName;
+ UINT32 mWholeScopeLine;
+ UINT32 mScopeLineStart;
+ SVfrFileScopeRecord *mNext;
+
+ SVfrFileScopeRecord (IN CHAR8 *, IN UINT32);
+ ~SVfrFileScopeRecord();
+
+private:
+ SVfrFileScopeRecord (IN CONST SVfrFileScopeRecord&); // Prevent copy-construction
+ SVfrFileScopeRecord& operator= (IN CONST SVfrFileScopeRecord&); // Prevent assignment
+};
+
+class CVfrErrorHandle {
+private:
+ CHAR8 *mInputFileName;
+ SVFR_ERROR_HANDLE *mVfrErrorHandleTable;
+ SVFR_WARNING_HANDLE *mVfrWarningHandleTable;
+ SVfrFileScopeRecord *mScopeRecordListHead;
+ SVfrFileScopeRecord *mScopeRecordListTail;
+ BOOLEAN mWarningAsError;
+
+public:
+ CVfrErrorHandle (VOID);
+ ~CVfrErrorHandle (VOID);
+
+ VOID SetWarningAsError (IN BOOLEAN);
+ VOID SetInputFile (IN CHAR8 *);
+ VOID ParseFileScopeRecord (IN CHAR8 *, IN UINT32);
+ VOID GetFileNameLineNum (IN UINT32, OUT CHAR8 **, OUT UINT32 *);
+ UINT8 HandleError (IN EFI_VFR_RETURN_CODE, IN UINT32 LineNum = 0, IN CHAR8 *TokName = NULL);
+ UINT8 HandleWarning (IN EFI_VFR_WARNING_CODE, IN UINT32 LineNum = 0, IN CHAR8 *TokName = NULL);
+ VOID PrintMsg (IN UINT32 LineNum = 0, IN CHAR8 *TokName = NULL, IN CONST CHAR8 *MsgType = "Error", IN CONST CHAR8 *ErrorMsg = "");
+
+private:
+ CVfrErrorHandle (IN CONST CVfrErrorHandle&); // Prevent copy-construction
+ CVfrErrorHandle& operator= (IN CONST CVfrErrorHandle&); // Prevent assignment
+};
+
+#define CHECK_ERROR_RETURN(f, v) do { EFI_VFR_RETURN_CODE r; if ((r = (f)) != (v)) { return r; } } while (0)
+
+extern CVfrErrorHandle gCVfrErrorHandle;
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
new file mode 100644
index 00000000..e80426f6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
@@ -0,0 +1,2457 @@
+/** @file
+
+ The definition of CFormPkg's member function
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "stdio.h"
+#include "assert.h"
+#include "VfrFormPkg.h"
+
+/*
+ * The definition of CFormPkg's member function
+ */
+
+SPendingAssign::SPendingAssign (
+ IN CHAR8 *Key,
+ IN VOID *Addr,
+ IN UINT32 Len,
+ IN UINT32 LineNo,
+ IN CONST CHAR8 *Msg
+ )
+{
+ mKey = NULL;
+ mAddr = Addr;
+ mLen = Len;
+ mFlag = PENDING;
+ mLineNo = LineNo;
+ mMsg = NULL;
+ mNext = NULL;
+ if (Key != NULL) {
+ mKey = new CHAR8[strlen (Key) + 1];
+ if (mKey != NULL) {
+ strcpy (mKey, Key);
+ }
+ }
+
+ if (Msg != NULL) {
+ mMsg = new CHAR8[strlen (Msg) + 1];
+ if (mMsg != NULL) {
+ strcpy (mMsg, Msg);
+ }
+ }
+}
+
+SPendingAssign::~SPendingAssign (
+ VOID
+ )
+{
+ if (mKey != NULL) {
+ delete[] mKey;
+ }
+ mAddr = NULL;
+ mLen = 0;
+ mLineNo = 0;
+ if (mMsg != NULL) {
+ delete[] mMsg;
+ }
+ mNext = NULL;
+}
+
+VOID
+SPendingAssign::SetAddrAndLen (
+ IN VOID *Addr,
+ IN UINT32 LineNo
+ )
+{
+ mAddr = Addr;
+ mLineNo = LineNo;
+}
+
+VOID
+SPendingAssign::AssignValue (
+ IN VOID *Addr,
+ IN UINT32 Len
+ )
+{
+ memmove (mAddr, Addr, (mLen < Len ? mLen : Len));
+ mFlag = ASSIGNED;
+}
+
+CHAR8 *
+SPendingAssign::GetKey (
+ VOID
+ )
+{
+ return mKey;
+}
+
+CFormPkg::CFormPkg (
+ IN UINT32 BufferSize
+ )
+{
+ CHAR8 *BufferStart;
+ CHAR8 *BufferEnd;
+ SBufferNode *Node;
+
+ mPkgLength = 0;
+ mBufferSize = 0;
+ mBufferNodeQueueHead = NULL;
+ mBufferNodeQueueTail = NULL;
+ mCurrBufferNode = NULL;
+ mReadBufferNode = NULL;
+ mReadBufferOffset = 0;
+ PendingAssignList = NULL;
+
+ Node = new SBufferNode;
+ if (Node == NULL) {
+ return ;
+ }
+ BufferStart = new CHAR8[BufferSize];
+ if (BufferStart == NULL) {
+ delete Node;
+ return;
+ }
+ BufferEnd = BufferStart + BufferSize;
+
+ memset (BufferStart, 0, BufferSize);
+ Node->mBufferStart = BufferStart;
+ Node->mBufferEnd = BufferEnd;
+ Node->mBufferFree = BufferStart;
+ Node->mNext = NULL;
+
+ mBufferSize = BufferSize;
+ mBufferNodeQueueHead = Node;
+ mBufferNodeQueueTail = Node;
+ mCurrBufferNode = Node;
+}
+
+CFormPkg::~CFormPkg ()
+{
+ SBufferNode *pBNode;
+ SPendingAssign *pPNode;
+
+ while (mBufferNodeQueueHead != NULL) {
+ pBNode = mBufferNodeQueueHead;
+ mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;
+ if (pBNode->mBufferStart != NULL) {
+ delete[] pBNode->mBufferStart;
+ delete pBNode;
+ }
+ }
+ mBufferNodeQueueTail = NULL;
+ mCurrBufferNode = NULL;
+
+ while (PendingAssignList != NULL) {
+ pPNode = PendingAssignList;
+ PendingAssignList = PendingAssignList->mNext;
+ delete pPNode;
+ }
+ PendingAssignList = NULL;
+}
+
+SBufferNode *
+CFormPkg::CreateNewNode (
+ VOID
+ )
+{
+ SBufferNode *Node;
+
+ Node = new SBufferNode;
+ if (Node == NULL) {
+ return NULL;
+ }
+
+ Node->mBufferStart = new CHAR8[mBufferSize];
+ if (Node->mBufferStart == NULL) {
+ delete Node;
+ return NULL;
+ } else {
+ memset (Node->mBufferStart, 0, mBufferSize);
+ Node->mBufferEnd = Node->mBufferStart + mBufferSize;
+ Node->mBufferFree = Node->mBufferStart;
+ Node->mNext = NULL;
+ }
+
+ return Node;
+}
+
+CHAR8 *
+CFormPkg::IfrBinBufferGet (
+ IN UINT32 Len
+ )
+{
+ CHAR8 *BinBuffer = NULL;
+ SBufferNode *Node = NULL;
+
+ if ((Len == 0) || (Len > mBufferSize)) {
+ return NULL;
+ }
+
+ if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
+ BinBuffer = mCurrBufferNode->mBufferFree;
+ mCurrBufferNode->mBufferFree += Len;
+ } else {
+ Node = CreateNewNode ();
+ if (Node == NULL) {
+ return NULL;
+ }
+
+ if (mBufferNodeQueueTail == NULL) {
+ mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
+ } else {
+ mBufferNodeQueueTail->mNext = Node;
+ mBufferNodeQueueTail = Node;
+ }
+ mCurrBufferNode = Node;
+
+ //
+ // Now try again.
+ //
+ BinBuffer = mCurrBufferNode->mBufferFree;
+ mCurrBufferNode->mBufferFree += Len;
+ }
+
+ mPkgLength += Len;
+
+ return BinBuffer;
+}
+
+inline
+UINT32
+CFormPkg::GetPkgLength (
+ VOID
+ )
+{
+ return mPkgLength;
+}
+
+VOID
+CFormPkg::Open (
+ VOID
+ )
+{
+ mReadBufferNode = mBufferNodeQueueHead;
+ mReadBufferOffset = 0;
+}
+
+VOID
+CFormPkg::Close (
+ VOID
+ )
+{
+ mReadBufferNode = NULL;
+ mReadBufferOffset = 0;
+}
+
+UINT32
+CFormPkg::Read (
+ IN CHAR8 *Buffer,
+ IN UINT32 Size
+ )
+{
+ UINT32 Index;
+
+ if ((Size == 0) || (Buffer == NULL)) {
+ return 0;
+ }
+
+ if (mReadBufferNode == NULL) {
+ return 0;
+ }
+
+ for (Index = 0; Index < Size; Index++) {
+ if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
+ Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
+ } else {
+ if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
+ return Index;
+ } else {
+ mReadBufferOffset = 0;
+ Index --;
+ }
+ }
+ }
+
+ return Size;
+}
+
+EFI_VFR_RETURN_CODE
+CFormPkg::BuildPkgHdr (
+ OUT EFI_HII_PACKAGE_HEADER **PkgHdr
+ )
+{
+ if (PkgHdr == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;
+ (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CFormPkg::BuildPkg (
+ OUT PACKAGE_DATA &TBuffer
+ )
+{
+
+ CHAR8 *Temp;
+ UINT32 Size;
+ CHAR8 Buffer[1024];
+
+ if (TBuffer.Buffer != NULL) {
+ delete TBuffer.Buffer;
+ }
+
+ TBuffer.Size = mPkgLength;
+ TBuffer.Buffer = NULL;
+ if (TBuffer.Size != 0) {
+ TBuffer.Buffer = new CHAR8[TBuffer.Size];
+ } else {
+ return VFR_RETURN_SUCCESS;
+ }
+
+ Temp = TBuffer.Buffer;
+ Open ();
+ while ((Size = Read (Buffer, 1024)) != 0) {
+ memcpy (Temp, Buffer, Size);
+ Temp += Size;
+ }
+ Close ();
+ return VFR_RETURN_SUCCESS;
+}
+
+
+EFI_VFR_RETURN_CODE
+CFormPkg::BuildPkg (
+ IN FILE *Output,
+ IN PACKAGE_DATA *PkgData
+ )
+{
+ EFI_VFR_RETURN_CODE Ret;
+ CHAR8 Buffer[1024];
+ UINT32 Size;
+ EFI_HII_PACKAGE_HEADER *PkgHdr;
+
+ if (Output == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+ fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
+ delete PkgHdr;
+
+ if (PkgData == NULL) {
+ Open ();
+ while ((Size = Read (Buffer, 1024)) != 0) {
+ fwrite (Buffer, Size, 1, Output);
+ }
+ Close ();
+ } else {
+ fwrite (PkgData->Buffer, PkgData->Size, 1, Output);
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CFormPkg::_WRITE_PKG_LINE (
+ IN FILE *pFile,
+ IN UINT32 LineBytes,
+ IN CONST CHAR8 *LineHeader,
+ IN CHAR8 *BlkBuf,
+ IN UINT32 BlkSize
+ )
+{
+ UINT32 Index;
+
+ if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
+ return;
+ }
+
+ for (Index = 0; Index < BlkSize; Index++) {
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
+ }
+}
+
+VOID
+CFormPkg::_WRITE_PKG_END (
+ IN FILE *pFile,
+ IN UINT32 LineBytes,
+ IN CONST CHAR8 *LineHeader,
+ IN CHAR8 *BlkBuf,
+ IN UINT32 BlkSize
+ )
+{
+ UINT32 Index;
+
+ if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
+ return;
+ }
+
+ for (Index = 0; Index < BlkSize - 1; Index++) {
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
+ }
+
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
+}
+
+#define BYTES_PRE_LINE 0x10
+UINT32 gAdjustOpcodeOffset = 0;
+BOOLEAN gNeedAdjustOpcode = FALSE;
+UINT32 gAdjustOpcodeLen = 0;
+
+EFI_VFR_RETURN_CODE
+CFormPkg::GenCFile (
+ IN CHAR8 *BaseName,
+ IN FILE *pFile,
+ IN PACKAGE_DATA *PkgData
+ )
+{
+ EFI_VFR_RETURN_CODE Ret;
+ CHAR8 Buffer[BYTES_PRE_LINE * 8];
+ EFI_HII_PACKAGE_HEADER *PkgHdr;
+ UINT32 PkgLength = 0;
+ UINT32 ReadSize = 0;
+
+ if ((BaseName == NULL) || (pFile == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);
+
+ if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+
+ fprintf (pFile, " // ARRAY LENGTH\n");
+ PkgLength = PkgHdr->Length + sizeof (UINT32);
+ _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));
+
+ fprintf (pFile, "\n\n // PACKAGE HEADER\n");
+ _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
+ PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);
+
+ fprintf (pFile, "\n\n // PACKAGE DATA\n");
+
+ if (PkgData == NULL) {
+ Open ();
+ while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
+ PkgLength += ReadSize;
+ if (PkgLength < PkgHdr->Length) {
+ _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
+ } else {
+ _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
+ }
+ }
+ Close ();
+ } else {
+ if (PkgData->Size % BYTES_PRE_LINE != 0) {
+ PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);
+ _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);
+ _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);
+ } else {
+ PkgLength = PkgData->Size - BYTES_PRE_LINE;
+ _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);
+ _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);
+ }
+ }
+
+ delete PkgHdr;
+ fprintf (pFile, "\n};\n");
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CFormPkg::AssignPending (
+ IN CHAR8 *Key,
+ IN VOID *ValAddr,
+ IN UINT32 ValLen,
+ IN UINT32 LineNo,
+ IN CONST CHAR8 *Msg
+ )
+{
+ SPendingAssign *pNew;
+
+ pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);
+ if (pNew == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNew->mNext = PendingAssignList;
+ PendingAssignList = pNew;
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CFormPkg::DoPendingAssign (
+ IN CHAR8 *Key,
+ IN VOID *ValAddr,
+ IN UINT32 ValLen
+ )
+{
+ SPendingAssign *pNode;
+
+ if ((Key == NULL) || (ValAddr == NULL)) {
+ return;
+ }
+
+ for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mKey, Key) == 0) {
+ pNode->AssignValue (ValAddr, ValLen);
+ }
+ }
+}
+
+bool
+CFormPkg::HavePendingUnassigned (
+ VOID
+ )
+{
+ SPendingAssign *pNode;
+
+ for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mFlag == PENDING) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID
+CFormPkg::PendingAssignPrintAll (
+ VOID
+ )
+{
+ SPendingAssign *pNode;
+
+ for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mFlag == PENDING) {
+ gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);
+ }
+ }
+}
+
+SBufferNode *
+CFormPkg::GetBinBufferNodeForAddr (
+ IN CHAR8 *BinBuffAddr
+ )
+{
+ SBufferNode *TmpNode;
+
+ TmpNode = mBufferNodeQueueHead;
+
+ while (TmpNode != NULL) {
+ if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {
+ return TmpNode;
+ }
+
+ TmpNode = TmpNode->mNext;
+ }
+
+ return NULL;
+}
+
+SBufferNode *
+CFormPkg::GetNodeBefore(
+ IN SBufferNode *CurrentNode
+ )
+{
+ SBufferNode *FirstNode = mBufferNodeQueueHead;
+ SBufferNode *LastNode = mBufferNodeQueueHead;
+
+ while (FirstNode != NULL) {
+ if (FirstNode == CurrentNode) {
+ break;
+ }
+
+ LastNode = FirstNode;
+ FirstNode = FirstNode->mNext;
+ }
+
+ if (FirstNode == NULL) {
+ LastNode = NULL;
+ }
+
+ return LastNode;
+}
+
+EFI_VFR_RETURN_CODE
+CFormPkg::InsertNodeBefore(
+ IN SBufferNode *CurrentNode,
+ IN SBufferNode *NewNode
+ )
+{
+ SBufferNode *LastNode = GetNodeBefore (CurrentNode);
+
+ if (LastNode == NULL) {
+ return VFR_RETURN_MISMATCHED;
+ }
+
+ NewNode->mNext = LastNode->mNext;
+ LastNode->mNext = NewNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+CHAR8 *
+CFormPkg::GetBufAddrBaseOnOffset (
+ IN UINT32 Offset
+ )
+{
+ SBufferNode *TmpNode;
+ UINT32 TotalBufLen;
+ UINT32 CurrentBufLen;
+
+ TotalBufLen = 0;
+
+ for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {
+ CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;
+ if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {
+ return TmpNode->mBufferStart + (Offset - TotalBufLen);
+ }
+
+ TotalBufLen += CurrentBufLen;
+ }
+
+ return NULL;
+}
+
+EFI_VFR_RETURN_CODE
+CFormPkg::AdjustDynamicInsertOpcode (
+ IN CHAR8 *InserPositionAddr,
+ IN CHAR8 *InsertOpcodeAddr,
+ IN BOOLEAN CreateOpcodeAfterParsingVfr
+ )
+{
+ SBufferNode *InserPositionNode;
+ SBufferNode *InsertOpcodeNode;
+ SBufferNode *NewRestoreNodeBegin;
+ SBufferNode *NewRestoreNodeEnd;
+ SBufferNode *NewLastEndNode;
+ SBufferNode *TmpNode;
+ UINT32 NeedRestoreCodeLen;
+
+ NewRestoreNodeEnd = NULL;
+
+ InserPositionNode = GetBinBufferNodeForAddr(InserPositionAddr);
+ InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);
+ assert (InserPositionNode != NULL);
+ assert (InsertOpcodeNode != NULL);
+
+ if (InserPositionNode == InsertOpcodeNode) {
+ //
+ // Create New Node to save the restore opcode.
+ //
+ NeedRestoreCodeLen = InsertOpcodeAddr - InserPositionAddr;
+ gAdjustOpcodeLen = NeedRestoreCodeLen;
+ NewRestoreNodeBegin = CreateNewNode ();
+ if (NewRestoreNodeBegin == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);
+ NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
+
+ //
+ // Override the restore buffer data.
+ //
+ memmove (InserPositionAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
+ InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;
+ memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);
+ } else {
+ //
+ // Create New Node to save the restore opcode.
+ //
+ NeedRestoreCodeLen = InserPositionNode->mBufferFree - InserPositionAddr;
+ gAdjustOpcodeLen = NeedRestoreCodeLen;
+ NewRestoreNodeBegin = CreateNewNode ();
+ if (NewRestoreNodeBegin == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);
+ NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
+ //
+ // Override the restore buffer data.
+ //
+ InserPositionNode->mBufferFree -= NeedRestoreCodeLen;
+ //
+ // Link the restore data to new node.
+ //
+ NewRestoreNodeBegin->mNext = InserPositionNode->mNext;
+
+ //
+ // Count the Adjust opcode len.
+ //
+ TmpNode = InserPositionNode->mNext;
+ while (TmpNode != InsertOpcodeNode) {
+ gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;
+ TmpNode = TmpNode->mNext;
+ }
+
+ //
+ // Create New Node to save the last node of restore opcode.
+ //
+ NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
+ gAdjustOpcodeLen += NeedRestoreCodeLen;
+ if (NeedRestoreCodeLen > 0) {
+ NewRestoreNodeEnd = CreateNewNode ();
+ if (NewRestoreNodeEnd == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);
+ NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;
+ //
+ // Override the restore buffer data.
+ //
+ memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
+ InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
+
+ //
+ // Insert the last restore data node.
+ //
+ TmpNode = GetNodeBefore (InsertOpcodeNode);
+ assert (TmpNode != NULL);
+
+ if (TmpNode == InserPositionNode) {
+ NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;
+ } else {
+ TmpNode->mNext = NewRestoreNodeEnd;
+ }
+ //
+ // Connect the dynamic opcode node to the node after InserPositionNode.
+ //
+ InserPositionNode->mNext = InsertOpcodeNode;
+ }
+ }
+
+ if (CreateOpcodeAfterParsingVfr) {
+ //
+ // Th new opcodes were created after Parsing Vfr file,
+ // so the content in mBufferNodeQueueTail must be the new created opcodes.
+ // So connet the NewRestoreNodeBegin to the tail and update the tail node.
+ //
+ mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
+ if (NewRestoreNodeEnd != NULL) {
+ mBufferNodeQueueTail = NewRestoreNodeEnd;
+ } else {
+ mBufferNodeQueueTail = NewRestoreNodeBegin;
+ }
+ } else {
+ if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {
+ //
+ // End form set opcode all in the mBufferNodeQueueTail node.
+ //
+ NewLastEndNode = CreateNewNode ();
+ if (NewLastEndNode == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ NewLastEndNode->mBufferStart[0] = 0x29;
+ NewLastEndNode->mBufferStart[1] = 0x02;
+ NewLastEndNode->mBufferFree += 2;
+
+ mBufferNodeQueueTail->mBufferFree -= 2;
+
+ mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
+ if (NewRestoreNodeEnd != NULL) {
+ NewRestoreNodeEnd->mNext = NewLastEndNode;
+ } else {
+ NewRestoreNodeBegin->mNext = NewLastEndNode;
+ }
+
+ mBufferNodeQueueTail = NewLastEndNode;
+ } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {
+ TmpNode = GetNodeBefore(mBufferNodeQueueTail);
+ assert (TmpNode != NULL);
+
+ TmpNode->mNext = NewRestoreNodeBegin;
+ if (NewRestoreNodeEnd != NULL) {
+ NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;
+ } else {
+ NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;
+ }
+ }
+ }
+ mCurrBufferNode = mBufferNodeQueueTail;
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CFormPkg::DeclarePendingQuestion (
+ IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,
+ IN CVfrDataStorage &lCVfrDataStorage,
+ IN CVfrQuestionDB &lCVfrQuestionDB,
+ IN EFI_GUID *LocalFormSetGuid,
+ IN UINT32 LineNo,
+ OUT CHAR8 **InsertOpcodeAddr
+ )
+{
+ SPendingAssign *pNode;
+ CHAR8 *VarStr;
+ UINT32 ArrayIdx;
+ CHAR8 FName[MAX_NAME_LEN];
+ CHAR8 *SName;
+ CHAR8 *NewStr;
+ UINT32 ShrinkSize = 0;
+ EFI_VFR_RETURN_CODE ReturnCode;
+ EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
+ UINT8 LFlags;
+ UINT32 MaxValue;
+ CIfrGuid *GuidObj = NULL;
+
+ //
+ // Declare all questions as Numeric in DisableIf True
+ //
+ // DisableIf
+ CIfrDisableIf DIObj;
+ DIObj.SetLineNo (LineNo);
+ *InsertOpcodeAddr = DIObj.GetObjBinAddr<CHAR8>();
+
+ //TrueOpcode
+ CIfrTrue TObj (LineNo);
+
+ // Declare Numeric qeustion for each undefined question.
+ for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mFlag == PENDING) {
+ EFI_VARSTORE_INFO Info;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ //
+ // Register this question, assume it is normal question, not date or time question
+ //
+ VarStr = pNode->mKey;
+ ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);
+ if (ReturnCode != VFR_RETURN_SUCCESS) {
+ gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
+ return ReturnCode;
+ }
+
+#ifdef VFREXP_DEBUG
+ printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);
+#endif
+ //
+ // Get Question Info, framework vfr VarName == StructName
+ //
+ ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);
+ if (ReturnCode != VFR_RETURN_SUCCESS) {
+ gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");
+ return ReturnCode;
+ }
+ //
+ // Get VarStoreType
+ //
+ ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);
+ if (ReturnCode != VFR_RETURN_SUCCESS) {
+ gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
+ return ReturnCode;
+ }
+ VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);
+
+ if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {
+ ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);
+ } else {
+ if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
+ ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
+ } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {
+ VarStr = pNode->mKey;
+ //convert VarStr with store name to VarStr with structure name
+ ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);
+ if (ReturnCode == VFR_RETURN_SUCCESS) {
+ NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];
+ NewStr[0] = '\0';
+ strcpy (NewStr, SName);
+ strcat (NewStr, VarStr + strlen (FName));
+ ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize, Info.mIsBitVar);
+ delete[] NewStr;
+ }
+ } else {
+ ReturnCode = VFR_RETURN_UNSUPPORTED;
+ }
+ }
+ if (ReturnCode != VFR_RETURN_SUCCESS) {
+ gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
+ return ReturnCode;
+ }
+ //
+ // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.
+ //
+ if (Info.mIsBitVar) {
+ GuidObj = new CIfrGuid(0);
+ GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
+ GuidObj->SetLineNo(LineNo);
+ }
+
+ CIfrNumeric CNObj;
+ CNObj.SetLineNo (LineNo);
+ CNObj.SetPrompt (0x0);
+ CNObj.SetHelp (0x0);
+ CNObj.SetQuestionId (QId);
+ CNObj.SetVarStoreInfo (&Info);
+
+ //
+ // Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.
+ //
+ if (Info.mIsBitVar) {
+ MaxValue = (1 << Info.mVarTotalSize) -1;
+ CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);
+ ShrinkSize = 12;
+ LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & Info.mVarTotalSize);
+ CNObj.SetFlagsForBitField (0, LFlags);
+ } else {
+ //
+ // Numeric doesn't support BOOLEAN data type.
+ // BOOLEAN type has the same data size to UINT8.
+ //
+ if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
+ Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
+ }
+ CNObj.SetFlags (0, Info.mVarType);
+ //
+ // Use maximum value not to limit the valid value for the undefined question.
+ //
+ switch (Info.mVarType) {
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);
+ ShrinkSize = 0;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);
+ ShrinkSize = 12;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);
+ ShrinkSize = 18;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);
+ ShrinkSize = 21;
+ break;
+ default:
+ break;
+ }
+ }
+ CNObj.ShrinkBinSize (ShrinkSize);
+
+ //
+ // For undefined Efi VarStore type question
+ // Append the extended guided opcode to contain VarName
+ //
+ if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
+ CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
+ CVNObj.SetLineNo (LineNo);
+ }
+
+ //
+ // End for Numeric
+ //
+ CIfrEnd CEObj;
+ CEObj.SetLineNo (LineNo);
+ //
+ // End for Guided opcode
+ //
+ if (GuidObj != NULL) {
+ CIfrEnd CEObjGuid;
+ CEObjGuid.SetLineNo (LineNo);
+ GuidObj->SetScope(1);
+ delete GuidObj;
+ GuidObj = NULL;
+ }
+ }
+ }
+
+ //
+ // End for DisableIf
+ //
+ CIfrEnd SEObj;
+ SEObj.SetLineNo (LineNo);
+
+ return VFR_RETURN_SUCCESS;
+}
+
+CFormPkg gCFormPkg;
+
+SIfrRecord::SIfrRecord (
+ VOID
+ )
+{
+ mIfrBinBuf = NULL;
+ mBinBufLen = 0;
+ mLineNo = 0xFFFFFFFF;
+ mOffset = 0xFFFFFFFF;
+ mNext = NULL;
+}
+
+SIfrRecord::~SIfrRecord (
+ VOID
+ )
+{
+ if (mIfrBinBuf != NULL) {
+ //delete mIfrBinBuf;
+ mIfrBinBuf = NULL;
+ }
+ mLineNo = 0xFFFFFFFF;
+ mOffset = 0xFFFFFFFF;
+ mBinBufLen = 0;
+ mNext = NULL;
+}
+
+CIfrRecordInfoDB::CIfrRecordInfoDB (
+ VOID
+ )
+{
+ mSwitch = TRUE;
+ mRecordCount = EFI_IFR_RECORDINFO_IDX_START;
+ mIfrRecordListHead = NULL;
+ mIfrRecordListTail = NULL;
+ mAllDefaultTypeCount = 0;
+ for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {
+ mAllDefaultIdArray[i] = 0xffff;
+ }
+}
+
+CIfrRecordInfoDB::~CIfrRecordInfoDB (
+ VOID
+ )
+{
+ SIfrRecord *pNode;
+
+ while (mIfrRecordListHead != NULL) {
+ pNode = mIfrRecordListHead;
+ mIfrRecordListHead = mIfrRecordListHead->mNext;
+ delete pNode;
+ }
+}
+
+SIfrRecord *
+CIfrRecordInfoDB::GetRecordInfoFromIdx (
+ IN UINT32 RecordIdx
+ )
+{
+ UINT32 Idx;
+ SIfrRecord *pNode = NULL;
+
+ if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
+ return NULL;
+ }
+
+ for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
+ (Idx != RecordIdx) && (pNode != NULL);
+ Idx++, pNode = pNode->mNext)
+ ;
+
+ return pNode;
+}
+
+UINT32
+CIfrRecordInfoDB::IfrRecordRegister (
+ IN UINT32 LineNo,
+ IN CHAR8 *IfrBinBuf,
+ IN UINT8 BinBufLen,
+ IN UINT32 Offset
+ )
+{
+ SIfrRecord *pNew;
+
+ if (mSwitch == FALSE) {
+ return EFI_IFR_RECORDINFO_IDX_INVALUD;
+ }
+
+ if ((pNew = new SIfrRecord) == NULL) {
+ return EFI_IFR_RECORDINFO_IDX_INVALUD;
+ }
+
+ if (mIfrRecordListHead == NULL) {
+ mIfrRecordListHead = pNew;
+ mIfrRecordListTail = pNew;
+ } else {
+ mIfrRecordListTail->mNext = pNew;
+ mIfrRecordListTail = pNew;
+ }
+ mRecordCount++;
+
+ return mRecordCount;
+}
+
+VOID
+CIfrRecordInfoDB::IfrRecordInfoUpdate (
+ IN UINT32 RecordIdx,
+ IN UINT32 LineNo,
+ IN CHAR8 *BinBuf,
+ IN UINT8 BinBufLen,
+ IN UINT32 Offset
+ )
+{
+ SIfrRecord *pNode;
+ SIfrRecord *Prev;
+
+ if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
+ return;
+ }
+
+ if (LineNo == 0) {
+ //
+ // Line number is not specified explicitly, try to use line number of previous opcode
+ //
+ Prev = GetRecordInfoFromIdx (RecordIdx - 1);
+ if (Prev != NULL) {
+ LineNo = Prev->mLineNo;
+ }
+ }
+
+ pNode->mLineNo = LineNo;
+ pNode->mOffset = Offset;
+ pNode->mBinBufLen = BinBufLen;
+ pNode->mIfrBinBuf = BinBuf;
+
+}
+
+VOID
+CIfrRecordInfoDB::IfrRecordOutput (
+ OUT PACKAGE_DATA &TBuffer
+ )
+{
+ CHAR8 *Temp;
+ SIfrRecord *pNode;
+
+ if (TBuffer.Buffer != NULL) {
+ delete[] TBuffer.Buffer;
+ }
+
+ TBuffer.Size = 0;
+ TBuffer.Buffer = NULL;
+
+
+ if (mSwitch == FALSE) {
+ return;
+ }
+
+ for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
+ TBuffer.Size += pNode->mBinBufLen;
+ }
+
+ if (TBuffer.Size != 0) {
+ TBuffer.Buffer = new CHAR8[TBuffer.Size];
+ } else {
+ return;
+ }
+
+ Temp = TBuffer.Buffer;
+
+ for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mIfrBinBuf != NULL) {
+ memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
+ Temp += pNode->mBinBufLen;
+ }
+ }
+
+ return;
+}
+
+VOID
+CIfrRecordInfoDB::IfrRecordOutput (
+ IN FILE *File,
+ IN UINT32 LineNo
+ )
+{
+ SIfrRecord *pNode;
+ UINT8 Index;
+ UINT32 TotalSize;
+
+ if (mSwitch == FALSE) {
+ return;
+ }
+
+ if (File == NULL) {
+ return;
+ }
+
+ TotalSize = 0;
+
+ for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mLineNo == LineNo || LineNo == 0) {
+ fprintf (File, ">%08X: ", pNode->mOffset);
+ TotalSize += pNode->mBinBufLen;
+ if (pNode->mIfrBinBuf != NULL) {
+ for (Index = 0; Index < pNode->mBinBufLen; Index++) {
+ fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
+ }
+ }
+ fprintf (File, "\n");
+ }
+ }
+
+ if (LineNo == 0) {
+ fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
+ }
+}
+
+//
+// for framework vfr file
+// adjust opcode sequence for uefi IFR format
+// adjust inconsistent and varstore into the right position.
+//
+BOOLEAN
+CIfrRecordInfoDB::CheckQuestionOpCode (
+ IN UINT8 OpCode
+ )
+{
+ switch (OpCode) {
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_NUMERIC_OP:
+ case EFI_IFR_PASSWORD_OP:
+ case EFI_IFR_ONE_OF_OP:
+ case EFI_IFR_ACTION_OP:
+ case EFI_IFR_STRING_OP:
+ case EFI_IFR_DATE_OP:
+ case EFI_IFR_TIME_OP:
+ case EFI_IFR_ORDERED_LIST_OP:
+ case EFI_IFR_REF_OP:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+BOOLEAN
+CIfrRecordInfoDB::CheckIdOpCode (
+ IN UINT8 OpCode
+ )
+{
+ switch (OpCode) {
+ case EFI_IFR_EQ_ID_VAL_OP:
+ case EFI_IFR_EQ_ID_ID_OP:
+ case EFI_IFR_EQ_ID_VAL_LIST_OP:
+ case EFI_IFR_QUESTION_REF1_OP:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+EFI_QUESTION_ID
+CIfrRecordInfoDB::GetOpcodeQuestionId (
+ IN EFI_IFR_OP_HEADER *OpHead
+ )
+{
+ EFI_IFR_QUESTION_HEADER *QuestionHead;
+
+ QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
+
+ return QuestionHead->QuestionId;
+}
+
+SIfrRecord *
+CIfrRecordInfoDB::GetRecordInfoFromOffset (
+ IN UINT32 Offset
+ )
+{
+ SIfrRecord *pNode = NULL;
+
+ for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mOffset == Offset) {
+ return pNode;
+ }
+ }
+
+ return pNode;
+}
+
+/**
+ Add just the op code position.
+
+ Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
+ so pDynamicOpcodeNodes is before mIfrRecordListTail.
+
+ From
+
+ |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
+
+ To
+
+ |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
+
+ Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
+ so new records are appennded to the end of OriginalIfrRecordListTail.
+
+ From
+
+ |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
+
+ To
+
+ |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
+
+
+ @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
+
+**/
+BOOLEAN
+CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
+ IN BOOLEAN CreateOpcodeAfterParsingVfr
+ )
+{
+ UINT32 OpcodeOffset;
+ SIfrRecord *pNode, *pPreNode;
+ SIfrRecord *pAdjustNode, *pNodeBeforeAdjust;
+ SIfrRecord *pNodeBeforeDynamic;
+
+ pPreNode = NULL;
+ pAdjustNode = NULL;
+ pNodeBeforeDynamic = NULL;
+ OpcodeOffset = 0;
+
+ //
+ // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
+ // and the node before pDynamicOpcodeNode.
+ //
+ for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {
+ if (OpcodeOffset == gAdjustOpcodeOffset) {
+ pAdjustNode = pNode;
+ pNodeBeforeAdjust = pPreNode;
+ } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {
+ pNodeBeforeDynamic = pPreNode;
+ }
+ if (pNode->mNext != NULL) {
+ pPreNode = pNode;
+ }
+ OpcodeOffset += pNode->mBinBufLen;
+ }
+
+ //
+ // Check the nodes whether exist.
+ //
+ if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Adjust the node. pPreNode save the Node before mIfrRecordListTail
+ //
+ pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;
+ if (CreateOpcodeAfterParsingVfr) {
+ //
+ // mIfrRecordListTail is the end of pDynamicNode (Case2).
+ //
+ mIfrRecordListTail->mNext = pAdjustNode;
+ mIfrRecordListTail = pNodeBeforeDynamic;
+ mIfrRecordListTail->mNext = NULL;
+ } else {
+ //
+ //pPreNode is the end of pDynamicNode(Case1).
+ //
+ pPreNode->mNext = pAdjustNode;
+ pNodeBeforeDynamic->mNext = mIfrRecordListTail;
+ }
+
+ return TRUE;
+}
+
+/**
+ Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
+
+ @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
+
+**/
+VOID
+CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
+ IN BOOLEAN CreateOpcodeAfterParsingVfr
+ )
+{
+ SIfrRecord *pRecord;
+
+ //
+ // Base on the original offset info to update the record list.
+ //
+ if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {
+ gCVfrErrorHandle.PrintMsg (0, (CHAR8 *)"Error", (CHAR8 *)"Can not find the adjust offset in the record.");
+ }
+
+ //
+ // Base on the opcode binary length to recalculate the offset for each opcode.
+ //
+ IfrAdjustOffsetForRecord();
+
+ //
+ // Base on the offset to find the binary address.
+ //
+ pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);
+ while (pRecord != NULL) {
+ pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);
+ pRecord = pRecord->mNext;
+ }
+}
+
+
+VOID
+CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
+ VOID
+ )
+{
+ UINT32 OpcodeOffset;
+ SIfrRecord *pNode;
+
+ OpcodeOffset = 0;
+ for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
+ pNode->mOffset = OpcodeOffset;
+ OpcodeOffset += pNode->mBinBufLen;
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CIfrRecordInfoDB::IfrRecordAdjust (
+ VOID
+ )
+{
+ SIfrRecord *pNode, *preNode;
+ SIfrRecord *uNode, *tNode;
+ EFI_IFR_OP_HEADER *OpHead, *tOpHead;
+ EFI_QUESTION_ID QuestionId;
+ UINT32 StackCount;
+ UINT32 QuestionScope;
+ CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };
+ EFI_VFR_RETURN_CODE Status;
+
+ //
+ // Init local variable
+ //
+ Status = VFR_RETURN_SUCCESS;
+ pNode = mIfrRecordListHead;
+ preNode = pNode;
+ QuestionScope = 0;
+ while (pNode != NULL) {
+ OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
+
+ //
+ // make sure the inconsistent opcode in question scope
+ //
+ if (QuestionScope > 0) {
+ QuestionScope += OpHead->Scope;
+ if (OpHead->OpCode == EFI_IFR_END_OP) {
+ QuestionScope --;
+ }
+ }
+
+ if (CheckQuestionOpCode (OpHead->OpCode)) {
+ QuestionScope = 1;
+ }
+ //
+ // for the inconsistent opcode not in question scope, adjust it
+ //
+ if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
+ //
+ // for inconsistent opcode not in question scope
+ //
+
+ //
+ // Count inconsistent opcode Scope
+ //
+ StackCount = OpHead->Scope;
+ QuestionId = EFI_QUESTION_ID_INVALID;
+ tNode = pNode;
+ while (tNode != NULL && StackCount > 0) {
+ tNode = tNode->mNext;
+ tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
+ //
+ // Calculate Scope Number
+ //
+ StackCount += tOpHead->Scope;
+ if (tOpHead->OpCode == EFI_IFR_END_OP) {
+ StackCount --;
+ }
+ //
+ // by IdEqual opcode to get QuestionId
+ //
+ if (QuestionId == EFI_QUESTION_ID_INVALID &&
+ CheckIdOpCode (tOpHead->OpCode)) {
+ QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
+ }
+ }
+ if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
+ //
+ // report error; not found
+ //
+ sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
+ gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
+ Status = VFR_RETURN_MISMATCHED;
+ break;
+ }
+ //
+ // extract inconsistent opcode list
+ // pNode is Inconsistent opcode, tNode is End Opcode
+ //
+
+ //
+ // insert inconsistent opcode list into the right question scope by questionid
+ //
+ for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
+ tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
+ if (CheckQuestionOpCode (tOpHead->OpCode) &&
+ (QuestionId == GetOpcodeQuestionId (tOpHead))) {
+ break;
+ }
+ }
+ //
+ // insert inconsistent opcode list and check LATE_CHECK flag
+ //
+ if (uNode != NULL) {
+ if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
+ //
+ // if LATE_CHECK flag is set, change inconsistent to nosumbit
+ //
+ OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
+ }
+
+ //
+ // skip the default storage for Date and Time
+ //
+ if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
+ uNode = uNode->mNext;
+ }
+
+ preNode->mNext = tNode->mNext;
+ tNode->mNext = uNode->mNext;
+ uNode->mNext = pNode;
+ //
+ // reset pNode to head list, scan the whole list again.
+ //
+ pNode = mIfrRecordListHead;
+ preNode = pNode;
+ QuestionScope = 0;
+ continue;
+ } else {
+ //
+ // not found matched question id, report error
+ //
+ sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
+ gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
+ Status = VFR_RETURN_MISMATCHED;
+ break;
+ }
+ } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
+ OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
+ //
+ // for new added group of varstore opcode
+ //
+ tNode = pNode;
+ while (tNode->mNext != NULL) {
+ tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
+ if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
+ tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
+ break;
+ }
+ tNode = tNode->mNext;
+ }
+
+ if (tNode->mNext == NULL) {
+ //
+ // invalid IfrCode, IfrCode end by EndOpCode
+ //
+ gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
+ Status = VFR_RETURN_MISMATCHED;
+ break;
+ }
+
+ if (tOpHead->OpCode != EFI_IFR_END_OP) {
+ //
+ // not new added varstore, which are not needed to be adjust.
+ //
+ preNode = tNode;
+ pNode = tNode->mNext;
+ continue;
+ } else {
+ //
+ // move new added varstore opcode to the position befor form opcode
+ // varstore opcode between pNode and tNode
+ //
+
+ //
+ // search form opcode from begin
+ //
+ for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
+ tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
+ if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
+ break;
+ }
+ }
+ //
+ // Insert varstore opcode beform form opcode if form opcode is found
+ //
+ if (uNode->mNext != NULL) {
+ preNode->mNext = tNode->mNext;
+ tNode->mNext = uNode->mNext;
+ uNode->mNext = pNode;
+ //
+ // reset pNode to head list, scan the whole list again.
+ //
+ pNode = mIfrRecordListHead;
+ preNode = pNode;
+ QuestionScope = 0;
+ continue;
+ } else {
+ //
+ // not found form, continue scan IfrRecord list
+ //
+ preNode = tNode;
+ pNode = tNode->mNext;
+ continue;
+ }
+ }
+ }
+ //
+ // next node
+ //
+ preNode = pNode;
+ pNode = pNode->mNext;
+ }
+
+ //
+ // Update Ifr Opcode Offset
+ //
+ if (Status == VFR_RETURN_SUCCESS) {
+ IfrAdjustOffsetForRecord ();
+ }
+ return Status;
+}
+
+/**
+ When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
+ given by expression, should save the default info for the Buffer VarStore.
+
+ @param DefaultId The default id.
+ @param pQuestionNode Point to the question opcode node.
+ @param Value The default value.
+**/
+VOID
+CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
+ IN UINT16 DefaultId,
+ IN SIfrRecord *pQuestionNode,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ CHAR8 *VarStoreName = NULL;
+ EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
+ EFI_GUID *VarGuid = NULL;
+ EFI_VARSTORE_INFO VarInfo;
+ EFI_IFR_QUESTION_HEADER *QuestionHead;
+ EFI_IFR_OP_HEADER *pQuestionOpHead;
+
+ pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
+ QuestionHead = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);
+
+ //
+ // Get the Var Store name and type.
+ //
+ gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);
+ VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);
+ VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);
+
+ //
+ // Only for Buffer storage need to save the default info in the storage.
+ // Other type storage, just return.
+ //
+ if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {
+ return;
+ } else {
+ VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;
+ VarInfo.mVarStoreId = QuestionHead->VarStoreId;
+ }
+
+ //
+ // Get the buffer storage info about this question.
+ //
+ gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);
+
+ //
+ // Add action.
+ //
+ gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
+ DefaultId,
+ VarInfo,
+ VarStoreName,
+ VarGuid,
+ VarInfo.mVarType,
+ Value
+ );
+}
+
+/**
+ Record the number and default id of all defaultstore opcode.
+
+**/
+VOID
+CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
+ VOID
+ )
+{
+ SIfrRecord *pNode;
+ EFI_IFR_OP_HEADER *pOpHead;
+ EFI_IFR_DEFAULTSTORE *DefaultStore;
+
+ pNode = mIfrRecordListHead;
+ mAllDefaultTypeCount = 0;
+
+ while (pNode != NULL) {
+ pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
+
+ if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){
+ DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;
+ mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;
+ }
+ pNode = pNode->mNext;
+ }
+}
+
+/**
+ Create new default opcode record.
+
+ @param Size The new default opcode size.
+ @param DefaultId The new default id.
+ @param Type The new default type.
+ @param LineNo The line number of the new record.
+ @param Value The new default value.
+
+**/
+VOID
+CIfrRecordInfoDB::IfrCreateDefaultRecord(
+ IN UINT8 Size,
+ IN UINT16 DefaultId,
+ IN UINT8 Type,
+ IN UINT32 LineNo,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ CIfrDefault *DObj;
+ CIfrDefault2 *DObj2;
+
+ DObj = NULL;
+ DObj2 = NULL;
+
+ if (Type == EFI_IFR_TYPE_OTHER) {
+ DObj2 = new CIfrDefault2 (Size);
+ DObj2->SetDefaultId(DefaultId);
+ DObj2->SetType(Type);
+ DObj2->SetLineNo(LineNo);
+ DObj2->SetScope (1);
+ delete DObj2;
+ } else {
+ DObj = new CIfrDefault (Size);
+ DObj->SetDefaultId(DefaultId);
+ DObj->SetType(Type);
+ DObj->SetLineNo(LineNo);
+ DObj->SetValue (Value);
+ delete DObj;
+ }
+}
+
+/**
+ Create new default opcode for question base on the QuestionDefaultInfo.
+
+ @param pQuestionNode Point to the question opcode Node.
+ @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
+
+**/
+VOID
+CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
+ IN SIfrRecord *pQuestionNode,
+ IN QuestionDefaultRecord *QuestionDefaultInfo
+ )
+{
+ EFI_IFR_OP_HEADER *pOpHead;
+ EFI_IFR_DEFAULT *Default;
+ SIfrRecord *pSNode;
+ SIfrRecord *pENode;
+ SIfrRecord *pDefaultNode;
+ CIfrObj *Obj;
+ CHAR8 *ObjBinBuf;
+ UINT8 ScopeCount;
+ UINT8 OpcodeNumber;
+ UINT8 OpcodeCount;
+ UINT8 DefaultSize;
+ EFI_IFR_ONE_OF_OPTION *DefaultOptionOpcode;
+ EFI_IFR_TYPE_VALUE CheckBoxDefaultValue;
+
+ CheckBoxDefaultValue.b = 1;
+ pOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
+ ScopeCount = 0;
+ OpcodeCount = 0;
+ Obj = NULL;
+
+ //
+ // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
+ //
+ gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;
+ //
+ // Case 1:
+ // For oneof, the default with smallest default id is given by the option flag.
+ // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
+ //
+ if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
+ DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;
+ DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
+ DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);
+ //
+ // Save the new created default in the buffer storage.
+ //
+ IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);
+ }
+ }
+ return;
+ }
+
+ //
+ // Case2:
+ // For checkbox, the default with smallest default id is given by the question flag.
+ // And create the missing defaults with true value.
+ //
+ if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
+ DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);
+ //
+ // Save the new created default.
+ //
+ IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);
+ }
+ }
+ return;
+ }
+
+ //
+ // Case3:
+ // The default with smallest default id is given by the default opcode.
+ // So create the missing defaults base on the value in the default opcode.
+ //
+
+ //
+ // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
+ //
+ pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;
+ Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;
+ //
+ // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
+ //
+ gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;
+
+ if (Default->Type == EFI_IFR_TYPE_OTHER) {
+ //
+ // EFI_IFR_DEFAULT_2 opcode.
+ //
+ // Point to the first expression opcode.
+ //
+ pSNode = pDefaultNode->mNext;
+ pENode = NULL;
+ ScopeCount++;
+ //
+ // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
+ //
+ while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {
+ pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
+ if (pOpHead->Scope == 1) {
+ ScopeCount++;
+ }
+ if (pOpHead->OpCode == EFI_IFR_END_OP) {
+ ScopeCount--;
+ }
+ pENode = pSNode;
+ pSNode = pSNode->mNext;
+ OpcodeCount++;
+ }
+
+ assert (pSNode);
+ assert (pENode);
+
+ //
+ // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
+ //
+ gAdjustOpcodeOffset = pSNode->mOffset;
+ //
+ // Create new default opcode node for missing default.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ OpcodeNumber = OpcodeCount;
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);
+ //
+ // Point to the first expression opcode node.
+ //
+ pSNode = pDefaultNode->mNext;
+ //
+ // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
+ //
+ while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {
+ pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
+ Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);
+ assert (Obj != NULL);
+ Obj->SetLineNo (pSNode->mLineNo);
+ ObjBinBuf = Obj->GetObjBinAddr<CHAR8>();
+ memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);
+ delete Obj;
+ pSNode = pSNode->mNext;
+ }
+ }
+ }
+ } else {
+ //
+ // EFI_IFR_DEFAULT opcode.
+ //
+ // Create new default opcode node for missing default.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);
+ //
+ // Save the new created default in the buffer storage..
+ //
+ IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);
+ }
+ }
+ }
+}
+
+/**
+ Parse the default information in a question, get the QuestionDefaultInfo.
+
+ @param pQuestionNode Point to the question record Node.
+ @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
+**/
+VOID
+CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
+ IN SIfrRecord *pQuestionNode,
+ OUT QuestionDefaultRecord *QuestionDefaultInfo
+ )
+{
+ SIfrRecord *pSNode;
+ EFI_IFR_ONE_OF_OPTION *OneofOptionOpcode;
+ EFI_IFR_OP_HEADER *pSOpHead;
+ EFI_IFR_CHECKBOX *CheckBoxOpcode;
+ EFI_IFR_DEFAULT *DefaultOpcode;
+ BOOLEAN IsOneOfOpcode;
+ UINT16 SmallestDefaultId;
+ UINT8 ScopeCount;
+
+ SmallestDefaultId = 0xffff;
+ IsOneOfOpcode = FALSE;
+ ScopeCount = 0;
+ pSNode = pQuestionNode;
+
+ //
+ // Parse all the opcodes in the Question.
+ //
+ while (pSNode != NULL) {
+ pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
+ //
+ // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
+ // Scopes may be nested within other scopes.
+ // When finishing parsing a question, the scope count must be zero.
+ //
+ if (pSOpHead->Scope == 1) {
+ ScopeCount++;
+ }
+ if (pSOpHead->OpCode == EFI_IFR_END_OP) {
+ ScopeCount--;
+ }
+ //
+ // Check whether finishing parsing a question.
+ //
+ if (ScopeCount == 0) {
+ break;
+ }
+
+ //
+ // Record the default information in the question.
+ //
+ switch (pSOpHead->OpCode) {
+ case EFI_IFR_ONE_OF_OP:
+ IsOneOfOpcode = TRUE;
+ break;
+ case EFI_IFR_CHECKBOX_OP:
+ //
+ // The default info of check box may be given by flag.
+ // So need to check the flag of check box.
+ //
+ CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;
+ if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {
+ //
+ // Check whether need to update the smallest default id.
+ //
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
+ }
+ //
+ // Update the QuestionDefaultInfo.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ QuestionDefaultInfo->mDefaultNumber ++;
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
+ }
+ break;
+ }
+ }
+ }
+ if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {
+ //
+ // Check whether need to update the smallest default id.
+ //
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
+ }
+ //
+ // Update the QuestionDefaultInfo.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ QuestionDefaultInfo->mDefaultNumber ++;
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case EFI_IFR_ONE_OF_OPTION_OP:
+ if (!IsOneOfOpcode) {
+ //
+ // Only check the option in oneof.
+ //
+ break;
+ }
+ OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;
+ if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
+ //
+ // The option is used as the standard default.
+ // Check whether need to update the smallest default id and QuestionDefaultInfo.
+ //
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
+ QuestionDefaultInfo->mDefaultValueRecord = pSNode;
+ }
+ //
+ // Update the IsDefaultIdExist array in QuestionDefaultInfo.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ QuestionDefaultInfo->mDefaultNumber ++;
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
+ }
+ break;
+ }
+ }
+ }
+ if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {
+ //
+ // This option is used as the manufacture default.
+ // Check whether need to update the smallest default id and QuestionDefaultInfo.
+ //
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
+ QuestionDefaultInfo->mDefaultValueRecord = pSNode;
+ }
+ //
+ // Update the QuestionDefaultInfo.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
+ if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ QuestionDefaultInfo->mDefaultNumber ++;
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case EFI_IFR_DEFAULT_OP:
+ DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;
+ //
+ // Check whether need to update the smallest default id and QuestionDefaultInfo.
+ //
+ if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {
+ SmallestDefaultId = DefaultOpcode->DefaultId;
+ QuestionDefaultInfo->mDefaultValueRecord= pSNode;
+ QuestionDefaultInfo->mIsDefaultOpcode= TRUE;
+ }
+ //
+ // Update the QuestionDefaultInfo.
+ //
+ for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){
+ if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {
+ if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
+ QuestionDefaultInfo->mDefaultNumber ++;
+ QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ //
+ // Parse next opcode in this question.
+ //
+ pSNode = pSNode->mNext;
+ }
+}
+
+/**
+ Check or add default for question if need.
+
+ This function will check the default info for question.
+ If the question has default, but the default number < defaultstore opcode number.
+ will do following two action :
+
+ 1. if (AutoDefault) will add default for question to support all kinds of defaults.
+ 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
+
+ We assume that the two options can not be TRUE at same time.
+ If they are TRUE at same time, only do the action corresponding to AutoDefault option.
+
+ @param AutoDefault Add default for question if needed
+ @param CheckDefault Check the default info, if missing default, generates an error.
+
+**/
+VOID
+CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
+ BOOLEAN AutoDefault,
+ BOOLEAN CheckDefault
+ )
+{
+ SIfrRecord *pNode;
+ SIfrRecord *pTailNode;
+ SIfrRecord *pStartAdjustNode;
+ EFI_IFR_OP_HEADER *pOpHead;
+ QuestionDefaultRecord QuestionDefaultInfo;
+ UINT8 MissingDefaultCount;
+ CHAR8 Msg[MAX_STRING_LEN] = {0, };
+
+ pNode = mIfrRecordListHead;
+
+ //
+ // Record the number and default id of all defaultstore opcode.
+ //
+ IfrGetDefaultStoreInfo ();
+
+ while (pNode != NULL) {
+ pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
+ //
+ // Check whether is question opcode.
+ //
+ if (CheckQuestionOpCode (pOpHead->OpCode)) {
+ //
+ // Initialize some local variables here, because they vary with question.
+ // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
+ //
+ memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));
+ pTailNode = mIfrRecordListTail;
+ //
+ // Get the QuestionDefaultInfo for current question.
+ //
+ IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);
+
+ if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {
+ if (AutoDefault) {
+ //
+ // Create default for question which misses default.
+ //
+ IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);
+
+ //
+ // Adjust the buffer content.
+ // pStartAdjustNode->mIfrBinBuf points to the insert position.
+ // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
+ //
+ pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);
+ gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);
+
+ //
+ // Update the record info.
+ //
+ IfrUpdateRecordInfoForDynamicOpcode (TRUE);
+ } else if (CheckDefault) {
+ //
+ // Generate an error for question which misses default.
+ //
+ MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;
+ sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);
+ gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);
+ }
+ }
+ }
+ //
+ // parse next opcode.
+ //
+ pNode = pNode->mNext;
+ }
+}
+
+CIfrRecordInfoDB gCIfrRecordInfoDB;
+
+VOID
+CIfrObj::_EMIT_PENDING_OBJ (
+ VOID
+ )
+{
+ CHAR8 *ObjBinBuf = NULL;
+
+ //
+ // do nothing
+ //
+ if (!mDelayEmit || !gCreateOp) {
+ return;
+ }
+
+ mPkgOffset = gCFormPkg.GetPkgLength ();
+ //
+ // update data buffer to package data
+ //
+ ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
+ if (ObjBinBuf != NULL) {
+ memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);
+ }
+
+ //
+ // update bin buffer to package data buffer
+ //
+ if (mObjBinBuf != NULL) {
+ delete[] mObjBinBuf;
+ mObjBinBuf = ObjBinBuf;
+ }
+
+ mDelayEmit = FALSE;
+}
+
+/*
+ * The definition of CIfrObj's member function
+ */
+static struct {
+ UINT8 mSize;
+ UINT8 mScope;
+} gOpcodeSizesScopeTable[] = {
+ { 0, 0 }, // EFI_IFR_INVALID - 0x00
+ { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
+ { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
+ { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
+ { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
+ { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
+ { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
+ { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
+ { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
+ { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
+ { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
+ { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
+ { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
+ { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
+ { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
+ { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
+ { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
+ { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
+ { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
+ { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
+ { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
+ { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
+ { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
+ { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
+ { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
+ { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
+ { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
+ { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
+ { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
+ { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP
+ { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
+ { 0, 0 }, // 0x1F
+ { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
+ { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
+ { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22
+ { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
+ { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
+ { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
+ { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
+ { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
+ { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
+ { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
+ { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A
+ { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B
+ { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C
+ { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D
+ { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E
+ { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
+ { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
+ { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
+ { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
+ { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
+ { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
+ { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
+ { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
+ { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
+ { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
+ { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
+ { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
+ { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
+ { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
+ { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
+ { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
+ { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
+ { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
+ { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
+ { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
+ { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
+ { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
+ { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
+ { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
+ { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
+ { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
+ { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
+ { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
+ { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
+ { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
+ { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
+ { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
+ { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
+ { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
+ { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
+ { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
+ { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
+ { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
+ { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
+ { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
+ { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
+ { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
+ { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
+ { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
+ { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
+ { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
+ { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
+ { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
+ { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
+ { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
+ { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
+ { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
+ { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
+ { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64
+};
+
+#ifdef CIFROBJ_DEUBG
+static struct {
+ CHAR8 *mIfrName;
+} gIfrObjPrintDebugTable[] = {
+ "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
+ "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
+ "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
+ "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
+ "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
+ "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
+ "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
+ "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
+ "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
+ "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
+ "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
+ "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
+ "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
+ "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
+ "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
+ "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
+ "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
+};
+
+VOID
+CIFROBJ_DEBUG_PRINT (
+ IN UINT8 OpCode
+ )
+{
+ printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
+}
+#else
+
+#define CIFROBJ_DEBUG_PRINT(OpCode)
+
+#endif
+
+BOOLEAN gCreateOp = TRUE;
+
+CIfrObj::CIfrObj (
+ IN UINT8 OpCode,
+ OUT CHAR8 **IfrObj,
+ IN UINT8 ObjBinLen,
+ IN BOOLEAN DelayEmit
+ )
+{
+ mDelayEmit = DelayEmit;
+ mPkgOffset = gCFormPkg.GetPkgLength ();
+ mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
+ mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
+ mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
+ mLineNo = 0;
+
+ assert (mObjBinBuf != NULL);
+
+ if (IfrObj != NULL) {
+ *IfrObj = mObjBinBuf;
+ }
+
+ CIFROBJ_DEBUG_PRINT (OpCode);
+}
+
+CIfrObj::~CIfrObj (
+ VOID
+ )
+{
+ if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
+ _EMIT_PENDING_OBJ ();
+ }
+
+ gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
+}
+
+/*
+ * The definition of CIfrObj's member function
+ */
+UINT8 gScopeCount = 0;
+
+CIfrOpHeader::CIfrOpHeader (
+ IN UINT8 OpCode,
+ IN VOID *StartAddr,
+ IN UINT8 Length
+ ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
+{
+ mHeader->OpCode = OpCode;
+ mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
+ mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
+}
+
+CIfrOpHeader::CIfrOpHeader (
+ IN CIfrOpHeader &OpHdr
+ )
+{
+ mHeader = OpHdr.mHeader;
+}
+
+UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
new file mode 100644
index 00000000..d412de12
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
@@ -0,0 +1,2776 @@
+/** @file
+
+ The definition of CFormPkg's member function
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFIIFRCLASS_H_
+#define _EFIIFRCLASS_H_
+
+#include "string.h"
+#include "EfiVfr.h"
+#include "VfrError.h"
+#include "VfrUtilityLib.h"
+
+#define NO_QST_REFED "no question refered"
+
+struct PACKAGE_DATA {
+ CHAR8 *Buffer;
+ UINT32 Size;
+};
+
+/*
+ * The functions below are used for flags setting
+ */
+static inline BOOLEAN _FLAGS_ZERO (
+ IN UINT8 &Flags
+ )
+{
+ return Flags == 0;
+}
+
+static inline VOID _FLAG_CLEAR (
+ IN UINT8 &Flags,
+ IN UINT8 Mask
+ )
+{
+ Flags &= (~Mask);
+}
+
+static inline UINT8 _FLAG_TEST_AND_CLEAR (
+ IN UINT8 &Flags,
+ IN UINT8 Mask
+ )
+{
+ UINT8 Ret = Flags & Mask;
+ Flags &= (~Mask);
+ return Ret;
+}
+
+static inline UINT8 _IS_EQUAL (
+ IN UINT8 &Flags,
+ IN UINT8 Value
+ )
+{
+ return Flags == Value;
+}
+
+/*
+ * The definition of CIfrBin
+ */
+typedef enum {
+ PENDING,
+ ASSIGNED
+} ASSIGN_FLAG;
+
+struct SPendingAssign {
+ CHAR8 *mKey; // key ! unique
+ VOID *mAddr;
+ UINT32 mLen;
+ ASSIGN_FLAG mFlag;
+ UINT32 mLineNo;
+ CHAR8 *mMsg;
+ struct SPendingAssign *mNext;
+
+ SPendingAssign (IN CHAR8 *, IN VOID *, IN UINT32, IN UINT32, IN CONST CHAR8 *);
+ ~SPendingAssign ();
+
+ VOID SetAddrAndLen (IN VOID *, IN UINT32);
+ VOID AssignValue (IN VOID *, IN UINT32);
+ CHAR8 * GetKey (VOID);
+
+private:
+ SPendingAssign (IN CONST SPendingAssign&); // Prevent copy-construction
+ SPendingAssign& operator= (IN CONST SPendingAssign&); // Prevent assignment
+};
+
+struct SBufferNode {
+ CHAR8 *mBufferStart;
+ CHAR8 *mBufferEnd;
+ CHAR8 *mBufferFree;
+ struct SBufferNode *mNext;
+};
+
+typedef struct {
+ EFI_GUID *OverrideClassGuid;
+} INPUT_INFO_TO_SYNTAX;
+
+class CFormPkg {
+private:
+ UINT32 mBufferSize;
+ SBufferNode *mBufferNodeQueueHead;
+ SBufferNode *mBufferNodeQueueTail;
+ SBufferNode *mCurrBufferNode;
+
+ SBufferNode *mReadBufferNode;
+ UINT32 mReadBufferOffset;
+
+ UINT32 mPkgLength;
+
+ VOID _WRITE_PKG_LINE (IN FILE *, IN UINT32 , IN CONST CHAR8 *, IN CHAR8 *, IN UINT32);
+ VOID _WRITE_PKG_END (IN FILE *, IN UINT32 , IN CONST CHAR8 *, IN CHAR8 *, IN UINT32);
+ SBufferNode * GetBinBufferNodeForAddr (IN CHAR8 *);
+ SBufferNode * CreateNewNode ();
+ SBufferNode * GetNodeBefore (IN SBufferNode *);
+ EFI_VFR_RETURN_CODE InsertNodeBefore (IN SBufferNode *, IN SBufferNode *);
+
+private:
+ SPendingAssign *PendingAssignList;
+
+public:
+ CFormPkg (IN UINT32 BufferSize = 4096);
+ ~CFormPkg ();
+
+ CHAR8 * IfrBinBufferGet (IN UINT32);
+ inline UINT32 GetPkgLength (VOID);
+
+ VOID Open ();
+ UINT32 Read (IN CHAR8 *, IN UINT32);
+ VOID Close ();
+
+ EFI_VFR_RETURN_CODE BuildPkgHdr (OUT EFI_HII_PACKAGE_HEADER **);
+ EFI_VFR_RETURN_CODE BuildPkg (IN FILE *, IN PACKAGE_DATA *PkgData = NULL);
+ EFI_VFR_RETURN_CODE BuildPkg (OUT PACKAGE_DATA &);
+ EFI_VFR_RETURN_CODE GenCFile (IN CHAR8 *, IN FILE *, IN PACKAGE_DATA *PkgData = NULL);
+
+private:
+ CFormPkg (IN CONST CFormPkg&); // Prevent copy-construction
+ CFormPkg& operator= (IN CONST CFormPkg&); // Prevent assignment
+
+public:
+ EFI_VFR_RETURN_CODE AssignPending (IN CHAR8 *, IN VOID *, IN UINT32, IN UINT32, IN CONST CHAR8 *Msg = NULL);
+ VOID DoPendingAssign (IN CHAR8 *, IN VOID *, IN UINT32);
+ bool HavePendingUnassigned (VOID);
+ VOID PendingAssignPrintAll (VOID);
+ EFI_VFR_RETURN_CODE DeclarePendingQuestion (
+ IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,
+ IN CVfrDataStorage &lCVfrDataStorage,
+ IN CVfrQuestionDB &lCVfrQuestionDB,
+ IN EFI_GUID *LocalFormSetGuid,
+ IN UINT32 LineNo,
+ OUT CHAR8 **InsertOpcodeAddr
+ );
+ EFI_VFR_RETURN_CODE AdjustDynamicInsertOpcode (
+ IN CHAR8 *LastFormEndAddr,
+ IN CHAR8 *InsertOpcodeAddr,
+ IN BOOLEAN CreateOpcodeAfterParsingVfr
+ );
+ CHAR8 * GetBufAddrBaseOnOffset (
+ IN UINT32 Offset
+ );
+};
+
+extern CFormPkg gCFormPkg;
+extern CVfrStringDB gCVfrStringDB;
+extern UINT32 gAdjustOpcodeOffset;
+extern BOOLEAN gNeedAdjustOpcode;
+
+struct SIfrRecord {
+ UINT32 mLineNo;
+ CHAR8 *mIfrBinBuf;
+ UINT8 mBinBufLen;
+ UINT32 mOffset;
+ SIfrRecord *mNext;
+
+ SIfrRecord (VOID);
+ ~SIfrRecord (VOID);
+};
+
+
+#define EFI_IFR_RECORDINFO_IDX_INVALUD 0xFFFFFF
+#define EFI_IFR_RECORDINFO_IDX_START 0x0
+#define EFI_HII_MAX_SUPPORT_DEFAULT_TYPE 0x08
+
+struct QuestionDefaultRecord {
+ BOOLEAN mIsDefaultIdExist[EFI_HII_MAX_SUPPORT_DEFAULT_TYPE]; // Record the default id in mAllDefaultIdArray[EFI_HII_MAX_SUPPORT_DEFAULT_TYPE]
+ // whether exists in current question.
+
+ SIfrRecord *mDefaultValueRecord; // Point to the default value record in RecordList which has smallest default Id.
+ // (for checkbox it may be NULL, because the dedault value is always true when the flag is set.)
+
+ BOOLEAN mIsDefaultOpcode; // whether the default value with smallest default id is given by default opcode.
+ // (for oneof and checkbox default info may be given by flag.)
+
+ UINT16 mDefaultNumber; // The default number of this question.
+};
+
+class CIfrRecordInfoDB {
+private:
+ bool mSwitch;
+ UINT32 mRecordCount;
+ SIfrRecord *mIfrRecordListHead;
+ SIfrRecord *mIfrRecordListTail;
+ UINT8 mAllDefaultTypeCount;
+ UINT16 mAllDefaultIdArray[EFI_HII_MAX_SUPPORT_DEFAULT_TYPE];
+
+ SIfrRecord * GetRecordInfoFromIdx (IN UINT32);
+ BOOLEAN CheckQuestionOpCode (IN UINT8);
+ BOOLEAN CheckIdOpCode (IN UINT8);
+ EFI_QUESTION_ID GetOpcodeQuestionId (IN EFI_IFR_OP_HEADER *);
+public:
+ CIfrRecordInfoDB (VOID);
+ ~CIfrRecordInfoDB (VOID);
+
+ inline VOID TurnOn (VOID) {
+ mSwitch = TRUE;
+ }
+
+ inline VOID TurnOff (VOID) {
+ mSwitch = FALSE;
+ }
+
+ SIfrRecord * GetRecordInfoFromOffset (IN UINT32);
+ VOID IfrAdjustOffsetForRecord (VOID);
+ BOOLEAN IfrAdjustDynamicOpcodeInRecords (IN BOOLEAN);
+
+ UINT32 IfrRecordRegister (IN UINT32, IN CHAR8 *, IN UINT8, IN UINT32);
+ VOID IfrRecordInfoUpdate (IN UINT32, IN UINT32, IN CHAR8*, IN UINT8, IN UINT32);
+ VOID IfrRecordOutput (IN FILE *, IN UINT32 LineNo);
+ VOID IfrRecordOutput (OUT PACKAGE_DATA &);
+ EFI_VFR_RETURN_CODE IfrRecordAdjust (VOID);
+ VOID IfrUpdateRecordInfoForDynamicOpcode (IN BOOLEAN);
+ VOID IfrCheckAddDefaultRecord (IN BOOLEAN, IN BOOLEAN);
+ VOID IfrGetDefaultStoreInfo ();
+ VOID IfrCreateDefaultRecord (IN UINT8 Size,IN UINT16 DefaultId,IN UINT8 Type,IN UINT32 LineNo,IN EFI_IFR_TYPE_VALUE Value);
+ VOID IfrCreateDefaultForQuestion (IN SIfrRecord *, IN QuestionDefaultRecord *);
+ VOID IfrParseDefaulInfoInQuestion (IN SIfrRecord *, OUT QuestionDefaultRecord *);
+ VOID IfrAddDefaultToBufferConfig (IN UINT16, IN SIfrRecord *,IN EFI_IFR_TYPE_VALUE);
+
+private:
+ CIfrRecordInfoDB (IN CONST CIfrRecordInfoDB&); // Prevent copy-construction
+ CIfrRecordInfoDB& operator= (IN CONST CIfrRecordInfoDB&); // Prevent assignment
+};
+
+extern CIfrRecordInfoDB gCIfrRecordInfoDB;
+
+/*
+ * The definition of CIfrObj
+ */
+extern BOOLEAN gCreateOp;
+
+class CIfrObj {
+private:
+ BOOLEAN mDelayEmit;
+
+ CHAR8 *mObjBinBuf;
+ UINT8 mObjBinLen;
+ UINT32 mLineNo;
+ UINT32 mRecordIdx;
+ UINT32 mPkgOffset;
+
+public:
+ CIfrObj (IN UINT8 OpCode, OUT CHAR8 **IfrObj = NULL, IN UINT8 ObjBinLen = 0, IN BOOLEAN DelayEmit = FALSE);
+ virtual ~CIfrObj(VOID);
+
+ VOID _EMIT_PENDING_OBJ (VOID);
+
+ inline VOID SetLineNo (IN UINT32 LineNo) {
+ mLineNo = LineNo;
+ }
+
+ template<typename T>
+ inline T * GetObjBinAddr (VOID) {
+ return reinterpret_cast<T *>(mObjBinBuf);
+ }
+
+ inline UINT32 GetObjBinOffset (VOID) {
+ return mPkgOffset;
+ }
+
+ inline UINT8 GetObjBinLen (VOID) {
+ return mObjBinLen;
+ }
+
+ inline bool ExpendObjBin (IN UINT8 Size) {
+ if ((mDelayEmit == TRUE) && ((mObjBinLen + Size) > mObjBinLen)) {
+ mObjBinLen = mObjBinLen + Size;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+
+ inline bool ShrinkObjBin (IN UINT8 Size) {
+ if ((mDelayEmit == TRUE) && (mObjBinLen > Size)) {
+ mObjBinLen -= Size;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+};
+
+/*
+ * The definition of CIfrOpHeader
+ */
+class CIfrOpHeader {
+private:
+ EFI_IFR_OP_HEADER *mHeader;
+
+public:
+ CIfrOpHeader (IN UINT8 OpCode, IN VOID *StartAddr, IN UINT8 Length = 0);
+ CIfrOpHeader (IN CIfrOpHeader &);
+ CIfrOpHeader& operator=(IN CONST CIfrOpHeader &);
+
+ VOID IncLength (UINT8 Size) {
+ if ((mHeader->Length + Size) > mHeader->Length) {
+ mHeader->Length = mHeader->Length + Size;
+ }
+ }
+
+ VOID DecLength (UINT8 Size) {
+ if (mHeader->Length >= Size) {
+ mHeader->Length -= Size;
+ }
+ }
+
+ UINT8 GetLength () {
+ return mHeader->Length;
+ }
+
+ UINT8 GetScope () {
+ return mHeader->Scope;
+ }
+
+ VOID SetScope (IN UINT8 Scope) {
+ mHeader->Scope = Scope;
+ }
+
+ VOID UpdateHeader (IN EFI_IFR_OP_HEADER *Header) {
+ mHeader = Header;
+ }
+
+ UINT8 GetOpCode () {
+ return mHeader->OpCode;
+ }
+};
+
+extern UINT8 gScopeCount;
+
+/*
+ * The definition of CIfrStatementHeader
+ */
+class CIfrStatementHeader {
+private:
+ EFI_IFR_STATEMENT_HEADER *mHeader;
+
+public:
+ CIfrStatementHeader (
+ IN EFI_IFR_STATEMENT_HEADER *StartAddr
+ ) : mHeader ((EFI_IFR_STATEMENT_HEADER *)StartAddr) {
+ mHeader = StartAddr;
+ mHeader->Help = EFI_STRING_ID_INVALID;
+ mHeader->Prompt = EFI_STRING_ID_INVALID;
+ }
+
+ EFI_IFR_STATEMENT_HEADER *GetStatementHeader () {
+ return mHeader;
+ }
+
+ VOID SetPrompt (IN EFI_STRING_ID Prompt) {
+ mHeader->Prompt = Prompt;
+ }
+
+ VOID SetHelp (IN EFI_STRING_ID Help) {
+ mHeader->Help = Help;
+ }
+};
+
+/*
+ * The definition of CIfrQuestionHeader
+ */
+#define EFI_IFR_QUESTION_FLAG_DEFAULT 0
+
+class CIfrQuestionHeader : public CIfrStatementHeader {
+private:
+ EFI_IFR_QUESTION_HEADER *mHeader;
+
+ EFI_IFR_STATEMENT_HEADER * QH2SH (EFI_IFR_QUESTION_HEADER *Qheader) {
+ return &(Qheader)->Header;
+ }
+
+public:
+ EFI_QUESTION_ID QUESTION_ID (VOID) {
+ return mHeader->QuestionId;
+ }
+
+ EFI_VARSTORE_ID VARSTORE_ID (VOID) {
+ return mHeader->VarStoreId;
+ }
+
+ VOID VARSTORE_INFO (OUT EFI_VARSTORE_INFO *Info) {
+ if (Info != NULL) {
+ Info->mVarStoreId = mHeader->VarStoreId;
+ memmove (&Info->mVarStoreId, &mHeader->VarStoreInfo, sizeof (Info->mVarStoreId));
+ }
+ }
+
+ UINT8 FLAGS (VOID) {
+ return mHeader->Flags;
+ }
+
+public:
+ CIfrQuestionHeader (
+ IN EFI_IFR_QUESTION_HEADER *StartAddr,
+ IN UINT8 Flags = EFI_IFR_QUESTION_FLAG_DEFAULT
+ ) : CIfrStatementHeader (QH2SH(StartAddr)) {
+ mHeader = StartAddr;
+ mHeader->QuestionId = EFI_QUESTION_ID_INVALID;
+ mHeader->VarStoreId = EFI_VARSTORE_ID_INVALID;
+ mHeader->VarStoreInfo.VarName = EFI_STRING_ID_INVALID;
+ mHeader->VarStoreInfo.VarOffset = EFI_VAROFFSET_INVALID;
+ mHeader->Flags = Flags;
+ }
+
+ VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {
+ mHeader->QuestionId = QuestionId;
+ }
+
+ VOID SetVarStoreInfo (IN EFI_VARSTORE_INFO *Info) {
+ mHeader->VarStoreId = Info->mVarStoreId;
+ mHeader->VarStoreInfo.VarName = Info->mInfo.mVarName;
+ mHeader->VarStoreInfo.VarOffset = Info->mInfo.mVarOffset;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 Flags) {
+ if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_READ_ONLY)) {
+ mHeader->Flags |= EFI_IFR_FLAG_READ_ONLY;
+ }
+
+ _FLAG_CLEAR (Flags, 0x02);
+
+ if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_CALLBACK)) {
+ mHeader->Flags |= EFI_IFR_FLAG_CALLBACK;
+ }
+
+ //
+ // ignore NVAccessFlag
+ //
+ _FLAG_CLEAR (Flags, 0x08);
+
+ if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_RESET_REQUIRED)) {
+ mHeader->Flags |= EFI_IFR_FLAG_RESET_REQUIRED;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_RECONNECT_REQUIRED)) {
+ mHeader->Flags |= EFI_IFR_FLAG_RECONNECT_REQUIRED;
+ }
+
+ //
+ // Set LateCheck Flag to compatible for framework flag
+ // but it uses 0x20 as its flag, if in the future UEFI may take this flag
+ //
+ if (_FLAG_TEST_AND_CLEAR (Flags, 0x20)) {
+ mHeader->Flags |= 0x20;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (Flags, EFI_IFR_FLAG_OPTIONS_ONLY)) {
+ mHeader->Flags |= EFI_IFR_FLAG_OPTIONS_ONLY;
+ }
+
+ return _FLAGS_ZERO (Flags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+
+ VOID UpdateCIfrQuestionHeader (IN EFI_IFR_QUESTION_HEADER *Header) {
+ mHeader = Header;
+ }
+};
+
+/*
+ * The definition of CIfrMinMaxStepData
+ */
+class CIfrMinMaxStepData {
+private:
+ MINMAXSTEP_DATA *mMinMaxStepData;
+ BOOLEAN ValueIsSet;
+ BOOLEAN IsNumeric;
+
+public:
+ CIfrMinMaxStepData (MINMAXSTEP_DATA *DataAddr, BOOLEAN NumericOpcode=FALSE) : mMinMaxStepData (DataAddr) {
+ mMinMaxStepData->u64.MinValue = 0;
+ mMinMaxStepData->u64.MaxValue = 0;
+ mMinMaxStepData->u64.Step = 0;
+ ValueIsSet = FALSE;
+ IsNumeric = NumericOpcode;
+ }
+
+ VOID SetMinMaxStepData (IN UINT64 MinValue, IN UINT64 MaxValue, IN UINT64 Step) {
+ if (!ValueIsSet) {
+ mMinMaxStepData->u64.MinValue = MinValue;
+ mMinMaxStepData->u64.MaxValue = MaxValue;
+ ValueIsSet = TRUE;
+ } else {
+ if (MinValue < mMinMaxStepData->u64.MinValue) {
+ mMinMaxStepData->u64.MinValue = MinValue;
+ }
+ if (MaxValue > mMinMaxStepData->u64.MaxValue) {
+ mMinMaxStepData->u64.MaxValue = MaxValue;
+ }
+ }
+ mMinMaxStepData->u64.Step = Step;
+ }
+
+ VOID SetMinMaxStepData (IN UINT32 MinValue, IN UINT32 MaxValue, IN UINT32 Step) {
+ if (!ValueIsSet) {
+ mMinMaxStepData->u32.MinValue = MinValue;
+ mMinMaxStepData->u32.MaxValue = MaxValue;
+ ValueIsSet = TRUE;
+ } else {
+ if (MinValue < mMinMaxStepData->u32.MinValue) {
+ mMinMaxStepData->u32.MinValue = MinValue;
+ }
+ if (MaxValue > mMinMaxStepData->u32.MaxValue) {
+ mMinMaxStepData->u32.MaxValue = MaxValue;
+ }
+ }
+ mMinMaxStepData->u32.Step = Step;
+ }
+
+ VOID SetMinMaxStepData (IN UINT16 MinValue, IN UINT16 MaxValue, IN UINT16 Step) {
+ if (!ValueIsSet) {
+ mMinMaxStepData->u16.MinValue = MinValue;
+ mMinMaxStepData->u16.MaxValue = MaxValue;
+ ValueIsSet = TRUE;
+ } else {
+ if (MinValue < mMinMaxStepData->u16.MinValue) {
+ mMinMaxStepData->u16.MinValue = MinValue;
+ }
+ if (MaxValue > mMinMaxStepData->u16.MaxValue) {
+ mMinMaxStepData->u16.MaxValue = MaxValue;
+ }
+ }
+ mMinMaxStepData->u16.Step = Step;
+ }
+
+ VOID SetMinMaxStepData (IN UINT8 MinValue, IN UINT8 MaxValue, IN UINT8 Step) {
+ if (!ValueIsSet) {
+ mMinMaxStepData->u8.MinValue = MinValue;
+ mMinMaxStepData->u8.MaxValue = MaxValue;
+ ValueIsSet = TRUE;
+ } else {
+ if (MinValue < mMinMaxStepData->u8.MinValue) {
+ mMinMaxStepData->u8.MinValue = MinValue;
+ }
+ if (MaxValue > mMinMaxStepData->u8.MaxValue) {
+ mMinMaxStepData->u8.MaxValue = MaxValue;
+ }
+ }
+ mMinMaxStepData->u8.Step = Step;
+ }
+
+ UINT64 GetMinData (UINT8 VarType, BOOLEAN IsBitVar) {
+ UINT64 MinValue = 0;
+ if (IsBitVar) {
+ MinValue = mMinMaxStepData->u32.MinValue;
+ return MinValue;
+ }
+ switch (VarType) {
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ MinValue = mMinMaxStepData->u64.MinValue;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ MinValue = (UINT64) mMinMaxStepData->u32.MinValue;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ MinValue = (UINT64) mMinMaxStepData->u16.MinValue;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ MinValue = (UINT64) mMinMaxStepData->u8.MinValue;
+ break;
+ default:
+ break;
+ }
+ return MinValue;
+ }
+
+ UINT64 GetMaxData (UINT8 VarType, BOOLEAN IsBitVar) {
+ UINT64 MaxValue = 0;
+ if (IsBitVar) {
+ MaxValue = mMinMaxStepData->u32.MaxValue;
+ return MaxValue;
+ }
+ switch (VarType) {
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ MaxValue = mMinMaxStepData->u64.MaxValue;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ MaxValue = (UINT64) mMinMaxStepData->u32.MaxValue;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ MaxValue = (UINT64) mMinMaxStepData->u16.MaxValue;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ MaxValue = (UINT64) mMinMaxStepData->u8.MaxValue;
+ break;
+ default:
+ break;
+ }
+ return MaxValue;
+ }
+
+ UINT64 GetStepData (UINT8 VarType, BOOLEAN IsBitVar) {
+ UINT64 MaxValue = 0;
+ if (IsBitVar) {
+ MaxValue = mMinMaxStepData->u32.Step;
+ return MaxValue;
+ }
+ switch (VarType) {
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ MaxValue = mMinMaxStepData->u64.Step;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ MaxValue = (UINT64) mMinMaxStepData->u32.Step;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ MaxValue = (UINT64) mMinMaxStepData->u16.Step;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ MaxValue = (UINT64) mMinMaxStepData->u8.Step;
+ break;
+ default:
+ break;
+ }
+ return MaxValue;
+ }
+
+ BOOLEAN IsNumericOpcode () {
+ return IsNumeric;
+ }
+
+ VOID UpdateCIfrMinMaxStepData (IN MINMAXSTEP_DATA *MinMaxStepData) {
+ mMinMaxStepData = MinMaxStepData;
+ }
+};
+
+static CIfrQuestionHeader *gCurrentQuestion = NULL;
+static CIfrMinMaxStepData *gCurrentMinMaxData = NULL;
+static BOOLEAN gIsOrderedList = FALSE;
+static BOOLEAN gIsStringOp = FALSE;
+
+/*
+ * The definition of all of the UEFI IFR Objects
+ */
+class CIfrFormSet : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_FORM_SET *mFormSet;
+ EFI_GUID *mClassGuid;
+
+public:
+ CIfrFormSet (UINT8 Size) : CIfrObj (EFI_IFR_FORM_SET_OP, (CHAR8 **)NULL, Size),
+ CIfrOpHeader (EFI_IFR_FORM_SET_OP, &(GetObjBinAddr<EFI_IFR_FORM_SET>())->Header, Size), mFormSet(GetObjBinAddr<EFI_IFR_FORM_SET>()) {
+ mFormSet->Help = EFI_STRING_ID_INVALID;
+ mFormSet->FormSetTitle = EFI_STRING_ID_INVALID;
+ mFormSet->Flags = 0;
+ memset (&mFormSet->Guid, 0, sizeof (EFI_GUID));
+ mClassGuid = (EFI_GUID *) (mFormSet + 1);
+ }
+
+ VOID SetGuid (IN EFI_GUID *Guid) {
+ memmove (&mFormSet->Guid, Guid, sizeof (EFI_GUID));
+ }
+
+ VOID SetFormSetTitle (IN EFI_STRING_ID FormSetTitle) {
+ mFormSet->FormSetTitle = FormSetTitle;
+ }
+
+ VOID SetHelp (IN EFI_STRING_ID Help) {
+ mFormSet->Help = Help;
+ }
+
+ VOID SetClassGuid (IN EFI_GUID *Guid) {
+ memmove (&(mClassGuid[mFormSet->Flags++]), Guid, sizeof (EFI_GUID));
+ }
+
+ UINT8 GetFlags() {
+ return mFormSet->Flags;
+ }
+};
+
+class CIfrEnd : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrEnd () : CIfrObj (EFI_IFR_END_OP),
+ CIfrOpHeader (EFI_IFR_END_OP, &(GetObjBinAddr<EFI_IFR_END>())->Header) {}
+};
+
+class CIfrDefaultStore : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_DEFAULTSTORE *mDefaultStore;
+
+public:
+ CIfrDefaultStore () : CIfrObj (EFI_IFR_DEFAULTSTORE_OP),
+ CIfrOpHeader (EFI_IFR_DEFAULTSTORE_OP, &(GetObjBinAddr<EFI_IFR_DEFAULTSTORE>())->Header), mDefaultStore(GetObjBinAddr<EFI_IFR_DEFAULTSTORE>()) {
+ mDefaultStore->DefaultId = EFI_VARSTORE_ID_INVALID;
+ mDefaultStore->DefaultName = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetDefaultName (IN EFI_STRING_ID DefaultName) {
+ mDefaultStore->DefaultName = DefaultName;
+ }
+
+ VOID SetDefaultId (IN UINT16 DefaultId) {
+ mDefaultStore->DefaultId = DefaultId;
+ }
+};
+
+#define EFI_FORM_ID_MAX 0xFFFF
+#define EFI_FREE_FORM_ID_BITMAP_SIZE ((EFI_FORM_ID_MAX + 1) / EFI_BITS_PER_UINT32)
+
+class CIfrFormId {
+public:
+ STATIC UINT32 FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE];
+
+ STATIC BOOLEAN ChekFormIdFree (IN EFI_FORM_ID FormId) {
+ UINT32 Index = (FormId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (FormId % EFI_BITS_PER_UINT32);
+
+ return (FormIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
+ }
+
+ STATIC VOID MarkFormIdUsed (IN EFI_FORM_ID FormId) {
+ UINT32 Index = (FormId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (FormId % EFI_BITS_PER_UINT32);
+
+ FormIdBitMap[Index] |= (0x80000000 >> Offset);
+ }
+};
+
+class CIfrForm : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_FORM *mForm;
+
+public:
+ CIfrForm () : CIfrObj (EFI_IFR_FORM_OP),
+ CIfrOpHeader (EFI_IFR_FORM_OP, &(GetObjBinAddr<EFI_IFR_FORM>())->Header), mForm(GetObjBinAddr<EFI_IFR_FORM>()) {
+ mForm->FormId = 0;
+ mForm->FormTitle = EFI_STRING_ID_INVALID;
+ }
+
+ EFI_VFR_RETURN_CODE SetFormId (IN EFI_FORM_ID FormId) {
+ if (FormId == 0) {
+ //
+ // FormId can't be 0.
+ //
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+ if (CIfrFormId::ChekFormIdFree (FormId) == FALSE) {
+ return VFR_RETURN_FORMID_REDEFINED;
+ }
+ mForm->FormId = FormId;
+ CIfrFormId::MarkFormIdUsed (FormId);
+ return VFR_RETURN_SUCCESS;
+ }
+
+ VOID SetFormTitle (IN EFI_STRING_ID FormTitle) {
+ mForm->FormTitle = FormTitle;
+ }
+};
+
+class CIfrFormMap : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_FORM_MAP *mFormMap;
+ EFI_IFR_FORM_MAP_METHOD *mMethodMap;
+
+public:
+ CIfrFormMap () : CIfrObj (EFI_IFR_FORM_MAP_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_FORM_MAP), TRUE),
+ CIfrOpHeader (EFI_IFR_FORM_MAP_OP, &(GetObjBinAddr<EFI_IFR_FORM_MAP>())->Header), mFormMap(GetObjBinAddr<EFI_IFR_FORM_MAP>()) {
+ mFormMap->FormId = 0;
+ mMethodMap = (EFI_IFR_FORM_MAP_METHOD *) (mFormMap + 1);
+ }
+
+ EFI_VFR_RETURN_CODE SetFormId (IN EFI_FORM_ID FormId) {
+ if (FormId == 0) {
+ //
+ // FormId can't be 0.
+ //
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+ if (CIfrFormId::ChekFormIdFree (FormId) == FALSE) {
+ return VFR_RETURN_FORMID_REDEFINED;
+ }
+ mFormMap->FormId = FormId;
+ CIfrFormId::MarkFormIdUsed (FormId);
+ return VFR_RETURN_SUCCESS;
+ }
+
+ VOID SetFormMapMethod (IN EFI_STRING_ID MethodTitle, IN EFI_GUID *MethodGuid) {
+ if (ExpendObjBin (sizeof (EFI_IFR_FORM_MAP_METHOD))) {
+ IncLength (sizeof (EFI_IFR_FORM_MAP_METHOD));
+
+ mMethodMap->MethodTitle = MethodTitle;
+ memmove (&(mMethodMap->MethodIdentifier), MethodGuid, sizeof (EFI_GUID));
+ mMethodMap ++;
+ }
+ }
+};
+
+class CIfrVarStore : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_VARSTORE *mVarStore;
+
+public:
+ CIfrVarStore () : CIfrObj (EFI_IFR_VARSTORE_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_VARSTORE), TRUE),
+ CIfrOpHeader (EFI_IFR_VARSTORE_OP, &(GetObjBinAddr<EFI_IFR_VARSTORE>())->Header), mVarStore(GetObjBinAddr<EFI_IFR_VARSTORE>()) {
+ mVarStore->VarStoreId = EFI_VARSTORE_ID_INVALID;
+ mVarStore->Size = 0;
+ memset (&mVarStore->Guid, 0, sizeof (EFI_GUID));
+ mVarStore->Name[0] = '\0';
+ }
+
+ VOID SetGuid (IN EFI_GUID *Guid) {
+ memmove (&mVarStore->Guid, Guid, sizeof (EFI_GUID));
+ }
+
+ VOID SetVarStoreId (IN EFI_VARSTORE_ID VarStoreId) {
+ mVarStore->VarStoreId = VarStoreId;
+ }
+
+ VOID SetSize (IN UINT16 Size) {
+ mVarStore->Size = Size;
+ }
+
+ VOID SetName (IN CHAR8 *Name) {
+ UINT8 Len;
+
+ if (Name != NULL) {
+ Len = (UINT8) strlen (Name);
+ if (Len != 0) {
+ if (ExpendObjBin (Len) == TRUE) {
+ IncLength (Len);
+ strcpy ((CHAR8 *)(mVarStore->Name), Name);
+ }
+ }
+ }
+ }
+};
+
+class CIfrVarStoreEfi : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_VARSTORE_EFI *mVarStoreEfi;
+
+public:
+ CIfrVarStoreEfi () : CIfrObj (EFI_IFR_VARSTORE_EFI_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_VARSTORE_EFI), TRUE),
+ CIfrOpHeader (EFI_IFR_VARSTORE_EFI_OP, &(GetObjBinAddr<EFI_IFR_VARSTORE_EFI>())->Header), mVarStoreEfi(GetObjBinAddr<EFI_IFR_VARSTORE_EFI>()) {
+ mVarStoreEfi->VarStoreId = EFI_VAROFFSET_INVALID;
+ mVarStoreEfi->Size = 0;
+ memset (&mVarStoreEfi->Guid, 0, sizeof (EFI_GUID));
+ mVarStoreEfi->Name[0] = '\0';
+ }
+
+ VOID SetGuid (IN EFI_GUID *Guid) {
+ memmove (&mVarStoreEfi->Guid, Guid, sizeof (EFI_GUID));
+ }
+
+ VOID SetVarStoreId (IN UINT16 VarStoreId) {
+ mVarStoreEfi->VarStoreId = VarStoreId;
+ }
+
+ VOID SetAttributes (IN UINT32 Attributes) {
+ mVarStoreEfi->Attributes = Attributes;
+ }
+ VOID SetSize (IN UINT16 Size) {
+ mVarStoreEfi->Size = Size;
+ }
+
+ VOID SetName (IN CHAR8 *Name) {
+ UINT8 Len;
+
+ if (Name != NULL) {
+ Len = (UINT8) strlen (Name);
+ if (Len != 0) {
+ if (ExpendObjBin (Len) == TRUE) {
+ IncLength (Len);
+ strcpy ((CHAR8 *)(mVarStoreEfi->Name), Name);
+ }
+ }
+ }
+ }
+
+ VOID SetBinaryLength (IN UINT16 Size) {
+ UINT16 Len;
+
+ Len = sizeof (EFI_IFR_VARSTORE_EFI);
+ if (Size > Len) {
+ ExpendObjBin(Size - Len);
+ IncLength(Size - Len);
+ } else {
+ ShrinkObjBin(Len - Size);
+ DecLength(Len - Size);
+ }
+ }
+};
+
+class CIfrVarStoreNameValue : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_VARSTORE_NAME_VALUE *mVarStoreNameValue;
+
+public:
+ CIfrVarStoreNameValue () : CIfrObj (EFI_IFR_VARSTORE_NAME_VALUE_OP),
+ CIfrOpHeader (EFI_IFR_VARSTORE_NAME_VALUE_OP, &(GetObjBinAddr<EFI_IFR_VARSTORE_NAME_VALUE>())->Header), mVarStoreNameValue(GetObjBinAddr<EFI_IFR_VARSTORE_NAME_VALUE>()) {
+ mVarStoreNameValue->VarStoreId = EFI_VAROFFSET_INVALID;
+ memset (&mVarStoreNameValue->Guid, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetGuid (IN EFI_GUID *Guid) {
+ memmove (&mVarStoreNameValue->Guid, Guid, sizeof (EFI_GUID));
+ }
+
+ VOID SetVarStoreId (IN UINT16 VarStoreId) {
+ mVarStoreNameValue->VarStoreId = VarStoreId;
+ }
+};
+
+class CIfrImage : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_IMAGE *mImage;
+
+public:
+ CIfrImage () : CIfrObj (EFI_IFR_IMAGE_OP),
+ CIfrOpHeader (EFI_IFR_IMAGE_OP, &(GetObjBinAddr<EFI_IFR_IMAGE>())->Header), mImage(GetObjBinAddr<EFI_IFR_IMAGE>()) {
+ mImage->Id = EFI_IMAGE_ID_INVALID;
+ }
+
+ VOID SetImageId (IN EFI_IMAGE_ID ImageId) {
+ mImage->Id = ImageId;
+ }
+};
+
+class CIfrModal : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrModal () : CIfrObj (EFI_IFR_MODAL_TAG_OP),
+ CIfrOpHeader (EFI_IFR_MODAL_TAG_OP, &(GetObjBinAddr<EFI_IFR_MODAL_TAG>())->Header) {
+ }
+};
+
+
+class CIfrLocked : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrLocked () : CIfrObj (EFI_IFR_LOCKED_OP),
+ CIfrOpHeader (EFI_IFR_LOCKED_OP, &(GetObjBinAddr<EFI_IFR_LOCKED>())->Header) {}
+};
+
+class CIfrRule : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_RULE *mRule;
+
+public:
+ CIfrRule () : CIfrObj (EFI_IFR_RULE_OP),
+ CIfrOpHeader (EFI_IFR_RULE_OP, &(GetObjBinAddr<EFI_IFR_RULE>())->Header), mRule(GetObjBinAddr<EFI_IFR_RULE>()) {
+ mRule->RuleId = EFI_RULE_ID_INVALID;
+ }
+
+ VOID SetRuleId (IN UINT8 RuleId) {
+ mRule->RuleId = RuleId;
+ }
+};
+
+static EFI_IFR_TYPE_VALUE gZeroEfiIfrTypeValue = {0, };
+
+class CIfrDefault : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_DEFAULT *mDefault;
+
+public:
+ CIfrDefault (
+ IN UINT8 Size,
+ IN UINT16 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD,
+ IN UINT8 Type = EFI_IFR_TYPE_OTHER,
+ IN EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue
+ ) : CIfrObj (EFI_IFR_DEFAULT_OP, (CHAR8 **)NULL, Size),
+ CIfrOpHeader (EFI_IFR_DEFAULT_OP, &(GetObjBinAddr<EFI_IFR_DEFAULT>())->Header, Size), mDefault(GetObjBinAddr<EFI_IFR_DEFAULT>()) {
+ mDefault->Type = Type;
+ mDefault->DefaultId = DefaultId;
+ memmove (&(mDefault->Value), &Value, Size - OFFSET_OF (EFI_IFR_DEFAULT, Value));
+ }
+
+ VOID SetDefaultId (IN UINT16 DefaultId) {
+ mDefault->DefaultId = DefaultId;
+ }
+
+ VOID SetType (IN UINT8 Type) {
+ mDefault->Type = Type;
+ }
+
+ VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) {
+ memmove (&mDefault->Value, &Value, mDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));
+ }
+};
+
+class CIfrDefault2 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_DEFAULT_2 *mDefault;
+
+public:
+ CIfrDefault2 (
+ IN UINT16 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD,
+ IN UINT8 Type = EFI_IFR_TYPE_OTHER
+ ) : CIfrObj (EFI_IFR_DEFAULT_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_DEFAULT_2)),
+ CIfrOpHeader (EFI_IFR_DEFAULT_OP, &(GetObjBinAddr<EFI_IFR_DEFAULT_2>())->Header, sizeof (EFI_IFR_DEFAULT_2)), mDefault(GetObjBinAddr<EFI_IFR_DEFAULT_2>()) {
+ mDefault->Type = Type;
+ mDefault->DefaultId = DefaultId;
+ }
+
+ VOID SetDefaultId (IN UINT16 DefaultId) {
+ mDefault->DefaultId = DefaultId;
+ }
+
+ VOID SetType (IN UINT8 Type) {
+ mDefault->Type = Type;
+ }
+};
+
+class CIfrValue : public CIfrObj, public CIfrOpHeader{
+public:
+ CIfrValue () : CIfrObj (EFI_IFR_VALUE_OP),
+ CIfrOpHeader (EFI_IFR_VALUE_OP, &(GetObjBinAddr<EFI_IFR_VALUE>())->Header) {}
+
+};
+
+class CIfrRead : public CIfrObj, public CIfrOpHeader{
+public:
+ CIfrRead () : CIfrObj (EFI_IFR_READ_OP),
+ CIfrOpHeader (EFI_IFR_READ_OP, &(GetObjBinAddr<EFI_IFR_READ>())->Header) {}
+
+};
+
+class CIfrWrite : public CIfrObj, public CIfrOpHeader{
+public:
+ CIfrWrite () : CIfrObj (EFI_IFR_WRITE_OP),
+ CIfrOpHeader (EFI_IFR_WRITE_OP, &(GetObjBinAddr<EFI_IFR_WRITE>())->Header) {}
+
+};
+
+class CIfrGet : public CIfrObj, public CIfrOpHeader{
+private:
+ EFI_IFR_GET *mGet;
+
+public:
+ CIfrGet (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_GET_OP),
+ CIfrOpHeader (EFI_IFR_GET_OP, &(GetObjBinAddr<EFI_IFR_GET>())->Header), mGet(GetObjBinAddr<EFI_IFR_GET>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetVarInfo (IN EFI_VARSTORE_INFO *Info) {
+ mGet->VarStoreId = Info->mVarStoreId;
+ mGet->VarStoreInfo.VarName = Info->mInfo.mVarName;
+ mGet->VarStoreInfo.VarOffset = Info->mInfo.mVarOffset;
+ mGet->VarStoreType = Info->mVarType;
+ }
+};
+
+class CIfrSet : public CIfrObj, public CIfrOpHeader{
+private:
+ EFI_IFR_SET *mSet;
+
+public:
+ CIfrSet (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_SET_OP),
+ CIfrOpHeader (EFI_IFR_SET_OP, &(GetObjBinAddr<EFI_IFR_SET>())->Header), mSet(GetObjBinAddr<EFI_IFR_SET>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetVarInfo (IN EFI_VARSTORE_INFO *Info) {
+ mSet->VarStoreId = Info->mVarStoreId;
+ mSet->VarStoreInfo.VarName = Info->mInfo.mVarName;
+ mSet->VarStoreInfo.VarOffset = Info->mInfo.mVarOffset;
+ mSet->VarStoreType = Info->mVarType;
+ }
+};
+
+class CIfrSubtitle : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {
+private:
+ EFI_IFR_SUBTITLE *mSubtitle;
+
+public:
+ CIfrSubtitle () : CIfrObj (EFI_IFR_SUBTITLE_OP),
+ CIfrOpHeader (EFI_IFR_SUBTITLE_OP, &(GetObjBinAddr<EFI_IFR_SUBTITLE>())->Header),
+ CIfrStatementHeader (&(GetObjBinAddr<EFI_IFR_SUBTITLE>())->Statement), mSubtitle(GetObjBinAddr<EFI_IFR_SUBTITLE>()) {
+ mSubtitle->Flags = 0;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) {
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_FLAGS_HORIZONTAL)) {
+ mSubtitle->Flags |= EFI_IFR_FLAGS_HORIZONTAL;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+};
+
+class CIfrText : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {
+private:
+ EFI_IFR_TEXT *mText;
+
+public:
+ CIfrText () : CIfrObj (EFI_IFR_TEXT_OP),
+ CIfrOpHeader (EFI_IFR_TEXT_OP, &(GetObjBinAddr<EFI_IFR_TEXT>())->Header),
+ CIfrStatementHeader (&(GetObjBinAddr<EFI_IFR_TEXT>())->Statement), mText(GetObjBinAddr<EFI_IFR_TEXT>()) {
+ mText->TextTwo = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetTextTwo (IN EFI_STRING_ID StringId) {
+ mText->TextTwo = StringId;
+ }
+};
+
+class CIfrRef : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_REF *mRef;
+
+public:
+ CIfrRef () : CIfrObj (EFI_IFR_REF_OP),
+ CIfrOpHeader (EFI_IFR_REF_OP, &(GetObjBinAddr<EFI_IFR_REF>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_REF>())->Question), mRef(GetObjBinAddr<EFI_IFR_REF>()) {
+ mRef->FormId = 0;
+ }
+
+ VOID SetFormId (IN EFI_FORM_ID FormId) {
+ mRef->FormId = FormId;
+ }
+};
+
+class CIfrRef2 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_REF2 *mRef2;
+
+public:
+ CIfrRef2 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_REF2)),
+ CIfrOpHeader (EFI_IFR_REF_OP, &(GetObjBinAddr<EFI_IFR_REF2>())->Header, sizeof (EFI_IFR_REF2)),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_REF2>())->Question), mRef2(GetObjBinAddr<EFI_IFR_REF2>()) {
+ mRef2->FormId = 0;
+ mRef2->QuestionId = EFI_QUESTION_ID_INVALID;
+ }
+
+ VOID SetFormId (IN EFI_FORM_ID FormId) {
+ mRef2->FormId = FormId;
+ }
+
+ VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {
+ mRef2->QuestionId = QuestionId;
+ }
+};
+
+class CIfrRef3 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_REF3 *mRef3;
+
+public:
+ CIfrRef3 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)NULL, sizeof(EFI_IFR_REF3)),
+ CIfrOpHeader (EFI_IFR_REF_OP, &(GetObjBinAddr<EFI_IFR_REF3>())->Header, sizeof (EFI_IFR_REF3)),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_REF3>())->Question), mRef3(GetObjBinAddr<EFI_IFR_REF3>()) {
+ mRef3->FormId = 0;
+ mRef3->QuestionId = EFI_QUESTION_ID_INVALID;
+ memset (&mRef3->FormSetId, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetFormId (IN EFI_FORM_ID FormId) {
+ mRef3->FormId = FormId;
+ }
+
+ VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {
+ mRef3->QuestionId = QuestionId;
+ }
+
+ VOID SetFormSetId (IN EFI_GUID FormSetId) {
+ mRef3->FormSetId = FormSetId;
+ }
+};
+
+class CIfrRef4 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_REF4 *mRef4;
+
+public:
+ CIfrRef4 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)NULL, sizeof(EFI_IFR_REF4)),
+ CIfrOpHeader (EFI_IFR_REF_OP, &(GetObjBinAddr<EFI_IFR_REF4>())->Header, sizeof(EFI_IFR_REF4)),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_REF4>())->Question), mRef4(GetObjBinAddr<EFI_IFR_REF4>()) {
+ mRef4->FormId = 0;
+ mRef4->QuestionId = EFI_QUESTION_ID_INVALID;
+ memset (&mRef4->FormSetId, 0, sizeof (EFI_GUID));
+ mRef4->DevicePath = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetFormId (IN EFI_FORM_ID FormId) {
+ mRef4->FormId = FormId;
+ }
+
+ VOID SetQuestionId (IN EFI_QUESTION_ID QuestionId) {
+ mRef4->QuestionId = QuestionId;
+ }
+
+ VOID SetFormSetId (IN EFI_GUID FormSetId) {
+ mRef4->FormSetId = FormSetId;
+ }
+
+ VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {
+ mRef4->DevicePath = DevicePath;
+ }
+};
+
+class CIfrRef5 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+public:
+ CIfrRef5 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_REF5)),
+ CIfrOpHeader (EFI_IFR_REF_OP, &(GetObjBinAddr<EFI_IFR_REF5>())->Header, sizeof (EFI_IFR_REF5)),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_REF5>())->Question) {
+ }
+};
+
+class CIfrResetButton : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {
+private:
+ EFI_IFR_RESET_BUTTON *mResetButton;
+
+public:
+ CIfrResetButton () : CIfrObj (EFI_IFR_RESET_BUTTON_OP),
+ CIfrOpHeader (EFI_IFR_RESET_BUTTON_OP, &(GetObjBinAddr<EFI_IFR_RESET_BUTTON>())->Header),
+ CIfrStatementHeader (&(GetObjBinAddr<EFI_IFR_RESET_BUTTON>())->Statement), mResetButton(GetObjBinAddr<EFI_IFR_RESET_BUTTON>()) {
+ mResetButton->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
+ }
+
+ VOID SetDefaultId (IN UINT16 DefaultId) {
+ mResetButton->DefaultId = DefaultId;
+ }
+};
+
+class CIfrCheckBox : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_CHECKBOX *mCheckBox;
+
+public:
+ CIfrCheckBox () : CIfrObj (EFI_IFR_CHECKBOX_OP),
+ CIfrOpHeader (EFI_IFR_CHECKBOX_OP, &(GetObjBinAddr<EFI_IFR_CHECKBOX>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_CHECKBOX>())->Question), mCheckBox(GetObjBinAddr<EFI_IFR_CHECKBOX>()) {
+ mCheckBox->Flags = 0;
+ gCurrentQuestion = this;
+ }
+
+ ~CIfrCheckBox () {
+ gCurrentQuestion = NULL;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_CHECKBOX_DEFAULT)) {
+ mCheckBox->Flags |= EFI_IFR_CHECKBOX_DEFAULT;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_CHECKBOX_DEFAULT_MFG)) {
+ mCheckBox->Flags |= EFI_IFR_CHECKBOX_DEFAULT_MFG;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+
+ UINT8 GetFlags (VOID) {
+ return mCheckBox->Flags;
+ }
+};
+
+class CIfrAction : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_ACTION *mAction;
+
+public:
+ CIfrAction () : CIfrObj (EFI_IFR_ACTION_OP),
+ CIfrOpHeader (EFI_IFR_ACTION_OP, &(GetObjBinAddr<EFI_IFR_ACTION>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_ACTION>())->Question), mAction(GetObjBinAddr<EFI_IFR_ACTION>()) {
+ mAction->QuestionConfig = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetQuestionConfig (IN EFI_STRING_ID QuestionConfig) {
+ mAction->QuestionConfig = QuestionConfig;
+ }
+};
+
+class CIfrDate : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_DATE *mDate;
+
+public:
+ CIfrDate () : CIfrObj (EFI_IFR_DATE_OP),
+ CIfrOpHeader (EFI_IFR_DATE_OP, &(GetObjBinAddr<EFI_IFR_DATE>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_DATE>())->Question), mDate(GetObjBinAddr<EFI_IFR_DATE>()) {
+ mDate->Flags = 0;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_YEAR_SUPPRESS)) {
+ mDate->Flags |= EFI_QF_DATE_YEAR_SUPPRESS;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_MONTH_SUPPRESS)) {
+ mDate->Flags |= EFI_QF_DATE_MONTH_SUPPRESS;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_QF_DATE_DAY_SUPPRESS)) {
+ mDate->Flags |= EFI_QF_DATE_DAY_SUPPRESS;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_NORMAL)) {
+ mDate->Flags |= QF_DATE_STORAGE_NORMAL;
+ } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_TIME)) {
+ mDate->Flags |= QF_DATE_STORAGE_TIME;
+ } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_DATE_STORAGE_WAKEUP)) {
+ mDate->Flags |= QF_DATE_STORAGE_WAKEUP;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+};
+
+class CIfrNumeric : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader, public CIfrMinMaxStepData {
+private:
+ EFI_IFR_NUMERIC *mNumeric;
+
+public:
+ CIfrNumeric () : CIfrObj (EFI_IFR_NUMERIC_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_NUMERIC), TRUE),
+ CIfrOpHeader (EFI_IFR_NUMERIC_OP, &(GetObjBinAddr<EFI_IFR_NUMERIC>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_NUMERIC>())->Question),
+ CIfrMinMaxStepData (&(GetObjBinAddr<EFI_IFR_NUMERIC>())->data, TRUE), mNumeric(GetObjBinAddr<EFI_IFR_NUMERIC>()) {
+ mNumeric->Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC;
+ gCurrentQuestion = this;
+ gCurrentMinMaxData = this;
+ }
+
+ ~CIfrNumeric () {
+ gCurrentQuestion = NULL;
+ gCurrentMinMaxData = NULL;
+ }
+
+ VOID ShrinkBinSize (IN UINT16 Size) {
+ //
+ // Update the buffer size which is truly be used later.
+ //
+ ShrinkObjBin(Size);
+ DecLength(Size);
+
+ //
+ // Allocate buffer in gCFormPkg.
+ //
+ _EMIT_PENDING_OBJ();
+
+ //
+ // Update the buffer pointer used by other class.
+ //
+ mNumeric = GetObjBinAddr<EFI_IFR_NUMERIC>();
+ UpdateHeader (&mNumeric->Header);
+ UpdateCIfrQuestionHeader(&mNumeric->Question);
+ UpdateCIfrMinMaxStepData(&mNumeric->data);
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags, BOOLEAN DisplaySettingsSpecified = FALSE) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (DisplaySettingsSpecified == FALSE) {
+ mNumeric->Flags = LFlags | EFI_IFR_DISPLAY_UINT_DEC;
+ } else {
+ mNumeric->Flags = LFlags;
+ }
+ return VFR_RETURN_SUCCESS;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlagsForBitField (IN UINT8 HFlags, IN UINT8 LFlags, BOOLEAN DisplaySettingsSpecified = FALSE) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (DisplaySettingsSpecified == FALSE) {
+ mNumeric->Flags = LFlags | EDKII_IFR_DISPLAY_UINT_DEC_BIT;
+ } else {
+ mNumeric->Flags = LFlags;
+ }
+ return VFR_RETURN_SUCCESS;
+ }
+
+ UINT8 GetNumericFlags () {
+ return mNumeric->Flags;
+ }
+};
+
+class CIfrOneOf : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader, public CIfrMinMaxStepData {
+private:
+ EFI_IFR_ONE_OF *mOneOf;
+
+public:
+ CIfrOneOf () : CIfrObj (EFI_IFR_ONE_OF_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_ONE_OF), TRUE),
+ CIfrOpHeader (EFI_IFR_ONE_OF_OP, &(GetObjBinAddr<EFI_IFR_ONE_OF>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_ONE_OF>())->Question),
+ CIfrMinMaxStepData (&(GetObjBinAddr<EFI_IFR_ONE_OF>())->data), mOneOf(GetObjBinAddr<EFI_IFR_ONE_OF>()) {
+ mOneOf->Flags = 0;
+ gCurrentQuestion = this;
+ gCurrentMinMaxData = this;
+ }
+
+ ~CIfrOneOf () {
+ gCurrentQuestion = NULL;
+ gCurrentMinMaxData = NULL;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (LFlags & EFI_IFR_DISPLAY) {
+ mOneOf->Flags = LFlags;
+ } else {
+ mOneOf->Flags = LFlags | EFI_IFR_DISPLAY_UINT_DEC;
+ }
+ return VFR_RETURN_SUCCESS;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlagsForBitField (IN UINT8 HFlags, IN UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (LFlags & EFI_IFR_DISPLAY) {
+ mOneOf->Flags = LFlags;
+ } else {
+ mOneOf->Flags = LFlags | EDKII_IFR_DISPLAY_UINT_DEC_BIT;
+ }
+ return VFR_RETURN_SUCCESS;
+ }
+
+ VOID ShrinkBinSize (IN UINT16 Size) {
+ //
+ // Update the buffer size which is truly be used later.
+ //
+ ShrinkObjBin(Size);
+ DecLength(Size);
+
+ //
+ // Allocate buffer in gCFormPkg.
+ //
+ _EMIT_PENDING_OBJ();
+
+ //
+ // Update the buffer pointer used by other class.
+ //
+ mOneOf = GetObjBinAddr<EFI_IFR_ONE_OF>();
+ UpdateHeader (&mOneOf->Header);
+ UpdateCIfrQuestionHeader(&mOneOf->Question);
+ UpdateCIfrMinMaxStepData(&mOneOf->data);
+ }
+};
+
+class CIfrString : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_STRING *mString;
+
+public:
+ CIfrString () : CIfrObj (EFI_IFR_STRING_OP),
+ CIfrOpHeader (EFI_IFR_STRING_OP, &(GetObjBinAddr<EFI_IFR_STRING>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_STRING>())->Question), mString(GetObjBinAddr<EFI_IFR_STRING>()) {
+ mString->Flags = 0;
+ mString->MinSize = 0;
+ mString->MaxSize = 0;
+ gCurrentQuestion = this;
+ }
+
+ ~CIfrString () {
+ gCurrentQuestion = NULL;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_STRING_MULTI_LINE)) {
+ mString->Flags |= EFI_IFR_STRING_MULTI_LINE;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+
+ VOID SetMinSize (IN UINT8 Flags) {
+ mString->MinSize = Flags;
+ }
+
+ VOID SetMaxSize (IN UINT8 MaxSize) {
+ mString->MaxSize = MaxSize;
+ }
+};
+
+class CIfrPassword : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_PASSWORD *mPassword;
+
+public:
+ CIfrPassword () : CIfrObj (EFI_IFR_PASSWORD_OP),
+ CIfrOpHeader (EFI_IFR_PASSWORD_OP, &(GetObjBinAddr<EFI_IFR_PASSWORD>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_PASSWORD>())->Question), mPassword(GetObjBinAddr<EFI_IFR_PASSWORD>()) {
+ mPassword->MinSize = 0;
+ mPassword->MaxSize = 0;
+ gCurrentQuestion = this;
+ }
+
+ ~CIfrPassword () {
+ gCurrentQuestion = NULL;
+ }
+
+ VOID SetMinSize (IN UINT16 MinSize) {
+ mPassword->MinSize = MinSize;
+ }
+
+ VOID SetMaxSize (IN UINT16 MaxSize) {
+ mPassword->MaxSize = MaxSize;
+ }
+};
+
+class CIfrOrderedList : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_ORDERED_LIST *mOrderedList;
+
+public:
+ CIfrOrderedList () : CIfrObj (EFI_IFR_ORDERED_LIST_OP),
+ CIfrOpHeader (EFI_IFR_ORDERED_LIST_OP, &(GetObjBinAddr<EFI_IFR_ORDERED_LIST>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_ORDERED_LIST>())->Question), mOrderedList(GetObjBinAddr<EFI_IFR_ORDERED_LIST>()) {
+ mOrderedList->MaxContainers = 0;
+ mOrderedList->Flags = 0;
+ gCurrentQuestion = this;
+ }
+
+ ~CIfrOrderedList () {
+ gCurrentQuestion = NULL;
+ }
+
+ VOID SetMaxContainers (IN UINT8 MaxContainers) {
+ mOrderedList->MaxContainers = MaxContainers;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_UNIQUE_SET)) {
+ mOrderedList->Flags |= EFI_IFR_UNIQUE_SET;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_NO_EMPTY_SET)) {
+ mOrderedList->Flags |= EFI_IFR_NO_EMPTY_SET;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+};
+
+class CIfrTime : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_TIME *mTime;
+
+public:
+ CIfrTime () : CIfrObj (EFI_IFR_TIME_OP),
+ CIfrOpHeader (EFI_IFR_TIME_OP, &(GetObjBinAddr<EFI_IFR_TIME>())->Header),
+ CIfrQuestionHeader (&(GetObjBinAddr<EFI_IFR_TIME>())->Question), mTime(GetObjBinAddr<EFI_IFR_TIME>()) {
+ mTime->Flags = 0;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {
+ EFI_VFR_RETURN_CODE Ret;
+
+ Ret = CIfrQuestionHeader::SetFlags (HFlags);
+ if (Ret != VFR_RETURN_SUCCESS) {
+ return Ret;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_HOUR_SUPPRESS)) {
+ mTime->Flags |= QF_TIME_HOUR_SUPPRESS;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_MINUTE_SUPPRESS)) {
+ mTime->Flags |= QF_TIME_MINUTE_SUPPRESS;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_SECOND_SUPPRESS)) {
+ mTime->Flags |= QF_TIME_SECOND_SUPPRESS;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_NORMAL)) {
+ mTime->Flags |= QF_TIME_STORAGE_NORMAL;
+ } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_TIME)) {
+ mTime->Flags |= QF_TIME_STORAGE_TIME;
+ } else if (_FLAG_TEST_AND_CLEAR (LFlags, QF_TIME_STORAGE_WAKEUP)) {
+ mTime->Flags |= QF_TIME_STORAGE_WAKEUP;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+};
+
+class CIfrDisableIf : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrDisableIf () : CIfrObj (EFI_IFR_DISABLE_IF_OP),
+ CIfrOpHeader (EFI_IFR_DISABLE_IF_OP, &(GetObjBinAddr<EFI_IFR_DISABLE_IF>())->Header) {}
+};
+
+class CIfrSuppressIf : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrSuppressIf () : CIfrObj (EFI_IFR_SUPPRESS_IF_OP),
+ CIfrOpHeader (EFI_IFR_SUPPRESS_IF_OP, &(GetObjBinAddr<EFI_IFR_SUPPRESS_IF>())->Header) {}
+};
+
+class CIfrGrayOutIf : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrGrayOutIf () : CIfrObj (EFI_IFR_GRAY_OUT_IF_OP),
+ CIfrOpHeader (EFI_IFR_GRAY_OUT_IF_OP, &(GetObjBinAddr<EFI_IFR_GRAY_OUT_IF>())->Header) {}
+};
+
+class CIfrInconsistentIf : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_INCONSISTENT_IF *mInconsistentIf;
+
+public:
+ CIfrInconsistentIf () : CIfrObj (EFI_IFR_INCONSISTENT_IF_OP),
+ CIfrOpHeader (EFI_IFR_INCONSISTENT_IF_OP, &(GetObjBinAddr<EFI_IFR_INCONSISTENT_IF>())->Header), mInconsistentIf(GetObjBinAddr<EFI_IFR_INCONSISTENT_IF>()) {
+ mInconsistentIf->Error = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetError (IN EFI_STRING_ID Error) {
+ mInconsistentIf->Error = Error;
+ }
+};
+
+class CIfrWarningIf : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_WARNING_IF *mWarningIf;
+
+public:
+ CIfrWarningIf () : CIfrObj (EFI_IFR_WARNING_IF_OP),
+ CIfrOpHeader (EFI_IFR_WARNING_IF_OP, &(GetObjBinAddr<EFI_IFR_WARNING_IF>())->Header), mWarningIf(GetObjBinAddr<EFI_IFR_WARNING_IF>()) {
+ mWarningIf->Warning = EFI_STRING_ID_INVALID;
+ mWarningIf->TimeOut = 0;
+ }
+
+ VOID SetWarning (IN EFI_STRING_ID Warning) {
+ mWarningIf->Warning = Warning;
+ }
+
+ VOID SetTimeOut (IN UINT8 TimeOut) {
+ mWarningIf->TimeOut = TimeOut;
+ }
+};
+
+class CIfrNoSubmitIf : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_NO_SUBMIT_IF *mNoSubmitIf;
+
+public:
+ CIfrNoSubmitIf () : CIfrObj (EFI_IFR_NO_SUBMIT_IF_OP),
+ CIfrOpHeader (EFI_IFR_NO_SUBMIT_IF_OP, &(GetObjBinAddr<EFI_IFR_NO_SUBMIT_IF>())->Header), mNoSubmitIf(GetObjBinAddr<EFI_IFR_NO_SUBMIT_IF>()) {
+ mNoSubmitIf->Error = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetError (IN EFI_STRING_ID Error) {
+ mNoSubmitIf->Error = Error;
+ }
+};
+
+class CIfrRefresh : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_REFRESH *mRefresh;
+
+public:
+ CIfrRefresh () : CIfrObj (EFI_IFR_REFRESH_OP),
+ CIfrOpHeader (EFI_IFR_REFRESH_OP, &(GetObjBinAddr<EFI_IFR_REFRESH>())->Header), mRefresh(GetObjBinAddr<EFI_IFR_REFRESH>()) {
+ mRefresh->RefreshInterval = 0;
+ }
+
+ VOID SetRefreshInterval (IN UINT8 RefreshInterval) {
+ mRefresh->RefreshInterval = RefreshInterval;
+ }
+};
+
+class CIfrRefreshId : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_REFRESH_ID *mRefreshId;
+
+public:
+ CIfrRefreshId () : CIfrObj (EFI_IFR_REFRESH_ID_OP),
+ CIfrOpHeader (EFI_IFR_REFRESH_ID_OP, &(GetObjBinAddr<EFI_IFR_REFRESH_ID>())->Header), mRefreshId(GetObjBinAddr<EFI_IFR_REFRESH_ID>()) {
+ memset (&mRefreshId->RefreshEventGroupId, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetRefreshEventGroutId (IN EFI_GUID *RefreshEventGroupId) {
+ memmove (&mRefreshId->RefreshEventGroupId, RefreshEventGroupId, sizeof (EFI_GUID));
+ }
+};
+
+class CIfrVarStoreDevice : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_VARSTORE_DEVICE *mVarStoreDevice;
+
+public:
+ CIfrVarStoreDevice () : CIfrObj (EFI_IFR_VARSTORE_DEVICE_OP),
+ CIfrOpHeader (EFI_IFR_VARSTORE_DEVICE_OP, &(GetObjBinAddr<EFI_IFR_VARSTORE_DEVICE>())->Header), mVarStoreDevice(GetObjBinAddr<EFI_IFR_VARSTORE_DEVICE>()) {
+ mVarStoreDevice->DevicePath = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {
+ mVarStoreDevice->DevicePath = DevicePath;
+ }
+};
+
+class CIfrOneOfOption : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_ONE_OF_OPTION *mOneOfOption;
+
+public:
+ CIfrOneOfOption (UINT8 Size) : CIfrObj (EFI_IFR_ONE_OF_OPTION_OP, (CHAR8 **)NULL, Size),
+ CIfrOpHeader (EFI_IFR_ONE_OF_OPTION_OP, &(GetObjBinAddr<EFI_IFR_ONE_OF_OPTION>())->Header, Size), mOneOfOption(GetObjBinAddr<EFI_IFR_ONE_OF_OPTION>()) {
+ mOneOfOption->Flags = 0;
+ mOneOfOption->Option = EFI_STRING_ID_INVALID;
+ mOneOfOption->Type = EFI_IFR_TYPE_OTHER;
+ memset (&mOneOfOption->Value, 0, Size - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
+ }
+
+ VOID SetOption (IN EFI_STRING_ID Option) {
+ mOneOfOption->Option = Option;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) {
+ mOneOfOption->Flags = 0;
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_OPTION_DEFAULT)) {
+ mOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;
+ }
+
+ if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_OPTION_DEFAULT_MFG)) {
+ mOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;
+ }
+
+ if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_8)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_8);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_16)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_16);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_32)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_32);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_NUM_SIZE_64)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_NUM_SIZE_64);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_NUM_SIZE_64;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_BOOLEAN)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_BOOLEAN);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_BOOLEAN;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_TIME)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_TIME);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_TIME;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_DATE)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_DATE);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_DATE;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_STRING)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_STRING);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_STRING;
+ } else if (_IS_EQUAL (LFlags, EFI_IFR_TYPE_OTHER)) {
+ _FLAG_CLEAR (LFlags, EFI_IFR_TYPE_OTHER);
+ mOneOfOption->Flags |= EFI_IFR_TYPE_OTHER;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+
+ VOID SetType (IN UINT8 Type) {
+ mOneOfOption->Type = Type;
+ }
+
+ VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) {
+ memmove (&mOneOfOption->Value, &Value, mOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
+ }
+
+ UINT8 GetFlags (VOID) {
+ return mOneOfOption->Flags;
+ }
+};
+
+static EFI_GUID IfrTianoGuid = EFI_IFR_TIANO_GUID;
+static EFI_GUID IfrFrameworkGuid = EFI_IFR_FRAMEWORK_GUID;
+
+class CIfrClass : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_CLASS *mClass;
+
+public:
+ CIfrClass () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_CLASS)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_CLASS>())->Header, sizeof (EFI_IFR_GUID_CLASS)), mClass(GetObjBinAddr<EFI_IFR_GUID_CLASS>()) {
+ mClass->ExtendOpCode = EFI_IFR_EXTEND_OP_CLASS;
+ mClass->Guid = IfrTianoGuid;
+ mClass->Class = EFI_NON_DEVICE_CLASS;
+ }
+
+ VOID SetClass (IN UINT16 Class) {
+ mClass->Class = Class;
+ }
+};
+
+class CIfrSubClass : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_SUBCLASS *mSubClass;
+
+public:
+ CIfrSubClass () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_SUBCLASS)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_SUBCLASS>())->Header, sizeof (EFI_IFR_GUID_SUBCLASS)), mSubClass(GetObjBinAddr<EFI_IFR_GUID_SUBCLASS>()) {
+ mSubClass->ExtendOpCode = EFI_IFR_EXTEND_OP_SUBCLASS;
+ mSubClass->Guid = IfrTianoGuid;
+ mSubClass->SubClass = EFI_SETUP_APPLICATION_SUBCLASS;
+ }
+
+ VOID SetSubClass (IN UINT16 SubClass) {
+ mSubClass->SubClass = SubClass;
+ }
+};
+
+class CIfrLabel : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_LABEL *mLabel;
+
+public:
+ CIfrLabel () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_LABEL)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_LABEL>())->Header, sizeof (EFI_IFR_GUID_LABEL)), mLabel(GetObjBinAddr<EFI_IFR_GUID_LABEL>()) {
+ mLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ mLabel->Guid = IfrTianoGuid;
+ }
+
+ VOID SetNumber (IN UINT16 Number) {
+ mLabel->Number = Number;
+ }
+};
+
+class CIfrBanner : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_BANNER *mBanner;
+
+public:
+ CIfrBanner () : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_BANNER)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_BANNER>())->Header, sizeof (EFI_IFR_GUID_BANNER)), mBanner(GetObjBinAddr<EFI_IFR_GUID_BANNER>()) {
+ mBanner->ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;
+ mBanner->Guid = IfrTianoGuid;
+ }
+
+ VOID SetTitle (IN EFI_STRING_ID StringId) {
+ mBanner->Title = StringId;
+ }
+
+ VOID SetLine (IN UINT16 Line) {
+ mBanner->LineNumber = Line;
+ }
+
+ VOID SetAlign (IN UINT8 Align) {
+ mBanner->Alignment = Align;
+ }
+};
+
+class CIfrOptionKey : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_OPTIONKEY *mOptionKey;
+
+public:
+ CIfrOptionKey (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_IFR_TYPE_VALUE &OptionValue,
+ IN EFI_QUESTION_ID KeyValue
+ ) : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_OPTIONKEY)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_OPTIONKEY>())->Header, sizeof (EFI_IFR_GUID_OPTIONKEY)), mOptionKey(GetObjBinAddr<EFI_IFR_GUID_OPTIONKEY>()) {
+ mOptionKey->ExtendOpCode = EFI_IFR_EXTEND_OP_OPTIONKEY;
+ mOptionKey->Guid = IfrFrameworkGuid;
+ mOptionKey->QuestionId = QuestionId;
+ mOptionKey->OptionValue = OptionValue;
+ mOptionKey->KeyValue = KeyValue;
+ }
+};
+
+class CIfrVarEqName : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_VAREQNAME *mVarEqName;
+
+public:
+ CIfrVarEqName (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_STRING_ID NameId
+ ) : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_VAREQNAME)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_VAREQNAME>())->Header, sizeof (EFI_IFR_GUID_VAREQNAME)), mVarEqName(GetObjBinAddr<EFI_IFR_GUID_VAREQNAME>()) {
+ mVarEqName->ExtendOpCode = EFI_IFR_EXTEND_OP_VAREQNAME;
+ mVarEqName->Guid = IfrFrameworkGuid;
+ mVarEqName->QuestionId = QuestionId;
+ mVarEqName->NameId = NameId;
+ }
+};
+
+class CIfrTimeout : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID_TIMEOUT *mTimeout;
+
+public:
+ CIfrTimeout (IN UINT16 Timeout = 0) : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID_TIMEOUT)),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID_TIMEOUT>())->Header, sizeof (EFI_IFR_GUID_TIMEOUT)), mTimeout(GetObjBinAddr<EFI_IFR_GUID_TIMEOUT>()) {
+ mTimeout->ExtendOpCode = EFI_IFR_EXTEND_OP_TIMEOUT;
+ mTimeout->Guid = IfrTianoGuid;
+ mTimeout->TimeOut = Timeout;
+ }
+
+ VOID SetTimeout (IN UINT16 Timeout) {
+ mTimeout->TimeOut = Timeout;
+ }
+};
+
+class CIfrGuid : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_GUID *mGuid;
+
+public:
+ CIfrGuid (UINT8 Size) : CIfrObj (EFI_IFR_GUID_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_GUID)+Size),
+ CIfrOpHeader (EFI_IFR_GUID_OP, &(GetObjBinAddr<EFI_IFR_GUID>())->Header, sizeof (EFI_IFR_GUID)+Size), mGuid(GetObjBinAddr<EFI_IFR_GUID>()) {
+ memset (&mGuid->Guid, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetGuid (IN EFI_GUID *Guid) {
+ memmove (&mGuid->Guid, Guid, sizeof (EFI_GUID));
+ }
+
+ VOID SetData (IN UINT8* DataBuff, IN UINT8 Size) {
+ memmove ((UINT8 *)mGuid + sizeof (EFI_IFR_GUID), DataBuff, Size);
+ }
+};
+
+class CIfrDup : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrDup (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_DUP_OP),
+ CIfrOpHeader (EFI_IFR_DUP_OP, &(GetObjBinAddr<EFI_IFR_DUP>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrEqIdId : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_EQ_ID_ID *mEqIdId;
+
+public:
+ CIfrEqIdId (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_EQ_ID_ID_OP),
+ CIfrOpHeader (EFI_IFR_EQ_ID_ID_OP, &(GetObjBinAddr<EFI_IFR_EQ_ID_ID>())->Header), mEqIdId(GetObjBinAddr<EFI_IFR_EQ_ID_ID>()) {
+ SetLineNo (LineNo);
+ mEqIdId->QuestionId1 = EFI_QUESTION_ID_INVALID;
+ mEqIdId->QuestionId2 = EFI_QUESTION_ID_INVALID;
+ }
+
+ VOID SetQuestionId1 (
+ IN EFI_QUESTION_ID QuestionId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 LineNo
+ ) {
+ if (QuestionId != EFI_QUESTION_ID_INVALID) {
+ mEqIdId->QuestionId1 = QuestionId;
+ } else {
+ gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId1), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);
+ }
+ }
+
+ VOID SetQuestionId2 (
+ IN EFI_QUESTION_ID QuestionId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 LineNo
+ ) {
+ if (QuestionId != EFI_QUESTION_ID_INVALID) {
+ mEqIdId->QuestionId2 = QuestionId;
+ } else {
+ gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdId->QuestionId2), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);
+ }
+ }
+};
+
+class CIfrEqIdVal : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_EQ_ID_VAL *mEqIdVal;
+
+public:
+ CIfrEqIdVal (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_EQ_ID_VAL_OP),
+ CIfrOpHeader (EFI_IFR_EQ_ID_VAL_OP, &(GetObjBinAddr<EFI_IFR_EQ_ID_VAL>())->Header), mEqIdVal(GetObjBinAddr<EFI_IFR_EQ_ID_VAL>()) {
+ SetLineNo (LineNo);
+ mEqIdVal->QuestionId = EFI_QUESTION_ID_INVALID;
+ }
+
+ VOID SetQuestionId (
+ IN EFI_QUESTION_ID QuestionId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 LineNo
+ ) {
+ if (QuestionId != EFI_QUESTION_ID_INVALID) {
+ mEqIdVal->QuestionId = QuestionId;
+ } else {
+ gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVal->QuestionId), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);
+ }
+ }
+
+ VOID SetValue (IN UINT16 Value) {
+ mEqIdVal->Value = Value;
+ }
+};
+
+class CIfrEqIdList : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_EQ_ID_VAL_LIST *mEqIdVList;
+
+public:
+ CIfrEqIdList (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_EQ_ID_VAL_LIST_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_EQ_ID_VAL_LIST), TRUE),
+ CIfrOpHeader (EFI_IFR_EQ_ID_VAL_LIST_OP, &(GetObjBinAddr<EFI_IFR_EQ_ID_VAL_LIST>())->Header), mEqIdVList(GetObjBinAddr<EFI_IFR_EQ_ID_VAL_LIST>()) {
+ SetLineNo (LineNo);
+ mEqIdVList->QuestionId = EFI_QUESTION_ID_INVALID;
+ mEqIdVList->ListLength = 0;
+ mEqIdVList->ValueList[0] = 0;
+ }
+
+ VOID UpdateIfrBuffer (
+ ) {
+ _EMIT_PENDING_OBJ();
+ mEqIdVList = GetObjBinAddr<EFI_IFR_EQ_ID_VAL_LIST>();
+ UpdateHeader (&mEqIdVList->Header);
+ }
+
+ VOID SetQuestionId (
+ IN EFI_QUESTION_ID QuestionId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 LineNo
+ ) {
+ if (QuestionId != EFI_QUESTION_ID_INVALID) {
+ mEqIdVList->QuestionId = QuestionId;
+ } else {
+ gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mEqIdVList->QuestionId), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);
+ }
+ }
+
+ VOID SetListLength (IN UINT16 ListLength) {
+ mEqIdVList->ListLength = ListLength;
+ }
+
+ VOID SetValueList (IN UINT16 Index, IN UINT16 Value) {
+ if (Index == 0) {
+ mEqIdVList->ValueList[0] = Value;
+ return;
+ }
+
+ if (ExpendObjBin (sizeof (UINT16)) ==TRUE) {
+ IncLength (sizeof (UINT16));
+ mEqIdVList->ValueList[Index] = Value;
+ }
+ }
+};
+
+class CIfrQuestionRef1 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_QUESTION_REF1 *mQuestionRef1;
+
+public:
+ CIfrQuestionRef1 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_QUESTION_REF1_OP),
+ CIfrOpHeader (EFI_IFR_QUESTION_REF1_OP, &(GetObjBinAddr<EFI_IFR_QUESTION_REF1>())->Header), mQuestionRef1(GetObjBinAddr<EFI_IFR_QUESTION_REF1>()) {
+ SetLineNo (LineNo);
+ mQuestionRef1->QuestionId = EFI_QUESTION_ID_INVALID;
+ }
+
+ VOID SetQuestionId (
+ IN EFI_QUESTION_ID QuestionId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 LineNo
+ ) {
+ if (QuestionId != EFI_QUESTION_ID_INVALID) {
+ mQuestionRef1->QuestionId = QuestionId;
+ } else {
+ gCFormPkg.AssignPending (VarIdStr, (VOID *)(&mQuestionRef1->QuestionId), sizeof (EFI_QUESTION_ID), LineNo, NO_QST_REFED);
+ }
+ }
+};
+
+class CIfrQuestionRef2 : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrQuestionRef2 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_QUESTION_REF2_OP),
+ CIfrOpHeader (EFI_IFR_QUESTION_REF2_OP, &(GetObjBinAddr<EFI_IFR_QUESTION_REF2>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrQuestionRef3 : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrQuestionRef3 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP),
+ CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &(GetObjBinAddr<EFI_IFR_QUESTION_REF3>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrQuestionRef3_2 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_QUESTION_REF3_2 *mQuestionRef3_2;
+
+public:
+ CIfrQuestionRef3_2 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_QUESTION_REF3_2)),
+ CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &(GetObjBinAddr<EFI_IFR_QUESTION_REF3_2>())->Header, sizeof (EFI_IFR_QUESTION_REF3_2)), mQuestionRef3_2(GetObjBinAddr<EFI_IFR_QUESTION_REF3_2>()) {
+ SetLineNo (LineNo);
+ mQuestionRef3_2->DevicePath = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {
+ mQuestionRef3_2->DevicePath = DevicePath;
+ }
+};
+
+class CIfrQuestionRef3_3 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_QUESTION_REF3_3 *mQuestionRef3_3;
+
+public:
+ CIfrQuestionRef3_3 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_QUESTION_REF3_OP, (CHAR8 **)NULL, sizeof (EFI_IFR_QUESTION_REF3_3)),
+ CIfrOpHeader (EFI_IFR_QUESTION_REF3_OP, &(GetObjBinAddr<EFI_IFR_QUESTION_REF3_3>())->Header, sizeof (EFI_IFR_QUESTION_REF3_3)), mQuestionRef3_3(GetObjBinAddr<EFI_IFR_QUESTION_REF3_3>()) {
+ SetLineNo (LineNo);
+ mQuestionRef3_3->DevicePath = EFI_STRING_ID_INVALID;
+ memset (&mQuestionRef3_3->Guid, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetDevicePath (IN EFI_STRING_ID DevicePath) {
+ mQuestionRef3_3->DevicePath = DevicePath;
+ }
+
+ VOID SetGuid (IN EFI_GUID *Guid) {
+ mQuestionRef3_3->Guid = *Guid;
+ }
+};
+
+class CIfrRuleRef : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_RULE_REF *mRuleRef;
+
+public:
+ CIfrRuleRef (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_RULE_REF_OP),
+ CIfrOpHeader (EFI_IFR_RULE_REF_OP, &(GetObjBinAddr<EFI_IFR_RULE_REF>())->Header), mRuleRef(GetObjBinAddr<EFI_IFR_RULE_REF>()) {
+ SetLineNo (LineNo);
+ mRuleRef->RuleId = EFI_RULE_ID_INVALID;
+ }
+
+ VOID SetRuleId (IN UINT8 RuleId) {
+ mRuleRef->RuleId = RuleId;
+ }
+};
+
+class CIfrStringRef1 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_STRING_REF1 *mStringRef1;
+
+public:
+ CIfrStringRef1 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_STRING_REF1_OP),
+ CIfrOpHeader (EFI_IFR_STRING_REF1_OP, &(GetObjBinAddr<EFI_IFR_STRING_REF1>())->Header), mStringRef1(GetObjBinAddr<EFI_IFR_STRING_REF1>()) {
+ SetLineNo (LineNo);
+ mStringRef1->StringId = EFI_STRING_ID_INVALID;
+ }
+
+ VOID SetStringId (IN EFI_STRING_ID StringId) {
+ mStringRef1->StringId = StringId;
+ }
+};
+
+class CIfrStringRef2 : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrStringRef2 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_STRING_REF2_OP),
+ CIfrOpHeader (EFI_IFR_STRING_REF2_OP, &(GetObjBinAddr<EFI_IFR_STRING_REF2>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrThis : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrThis (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_THIS_OP),
+ CIfrOpHeader (EFI_IFR_THIS_OP, &(GetObjBinAddr<EFI_IFR_THIS>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrSecurity : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_SECURITY *mSecurity;
+
+public:
+ CIfrSecurity (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_SECURITY_OP),
+ CIfrOpHeader (EFI_IFR_SECURITY_OP, &(GetObjBinAddr<EFI_IFR_SECURITY>())->Header), mSecurity(GetObjBinAddr<EFI_IFR_SECURITY>()) {
+ SetLineNo (LineNo);
+ memset (&mSecurity->Permissions, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetPermissions (IN EFI_GUID *Permissions) {
+ memmove (&mSecurity->Permissions, Permissions, sizeof (EFI_GUID));
+ }
+};
+
+class CIfrUint8 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_UINT8 *mUint8;
+
+public:
+ CIfrUint8 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_UINT8_OP),
+ CIfrOpHeader (EFI_IFR_UINT8_OP, &(GetObjBinAddr<EFI_IFR_UINT8>())->Header), mUint8(GetObjBinAddr<EFI_IFR_UINT8>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetValue (IN UINT8 Value) {
+ mUint8->Value = Value;
+ }
+};
+
+class CIfrUint16 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_UINT16 *mUint16;
+
+public:
+ CIfrUint16 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_UINT16_OP),
+ CIfrOpHeader (EFI_IFR_UINT16_OP, &(GetObjBinAddr<EFI_IFR_UINT16>())->Header), mUint16(GetObjBinAddr<EFI_IFR_UINT16>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetValue (IN UINT16 Value) {
+ mUint16->Value = Value;
+ }
+};
+
+class CIfrUint32 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_UINT32 *mUint32;
+
+public:
+ CIfrUint32 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_UINT32_OP),
+ CIfrOpHeader (EFI_IFR_UINT32_OP, &(GetObjBinAddr<EFI_IFR_UINT32>())->Header), mUint32(GetObjBinAddr<EFI_IFR_UINT32>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetValue (IN UINT32 Value) {
+ mUint32->Value = Value;
+ }
+};
+
+class CIfrUint64 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_UINT64 *mUint64;
+
+public:
+ CIfrUint64 (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_UINT64_OP),
+ CIfrOpHeader (EFI_IFR_UINT64_OP, &(GetObjBinAddr<EFI_IFR_UINT64>())->Header), mUint64(GetObjBinAddr<EFI_IFR_UINT64>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetValue (IN UINT64 Value) {
+ mUint64->Value = Value;
+ }
+};
+
+class CIfrTrue : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrTrue (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TRUE_OP),
+ CIfrOpHeader (EFI_IFR_TRUE_OP, &(GetObjBinAddr<EFI_IFR_TRUE>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrFalse : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrFalse (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_FALSE_OP),
+ CIfrOpHeader (EFI_IFR_FALSE_OP, &(GetObjBinAddr<EFI_IFR_FALSE>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrOne : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrOne (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_ONE_OP),
+ CIfrOpHeader (EFI_IFR_ONE_OP, &(GetObjBinAddr<EFI_IFR_ONE>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrOnes : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrOnes (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_ONES_OP),
+ CIfrOpHeader (EFI_IFR_ONES_OP, &(GetObjBinAddr<EFI_IFR_ONES>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrZero : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrZero (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_ZERO_OP),
+ CIfrOpHeader (EFI_IFR_ZERO_OP, &(GetObjBinAddr<EFI_IFR_ZERO>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrUndefined : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrUndefined (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_UNDEFINED_OP),
+ CIfrOpHeader (EFI_IFR_UNDEFINED_OP, &(GetObjBinAddr<EFI_IFR_UNDEFINED>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrVersion : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrVersion (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_VERSION_OP),
+ CIfrOpHeader (EFI_IFR_VERSION_OP, &(GetObjBinAddr<EFI_IFR_VERSION>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrLength : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrLength (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_LENGTH_OP),
+ CIfrOpHeader (EFI_IFR_LENGTH_OP, &(GetObjBinAddr<EFI_IFR_LENGTH>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrNot : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrNot (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_NOT_OP),
+ CIfrOpHeader (EFI_IFR_NOT_OP, &(GetObjBinAddr<EFI_IFR_NOT>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrBitWiseNot : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrBitWiseNot (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_BITWISE_NOT_OP),
+ CIfrOpHeader (EFI_IFR_BITWISE_NOT_OP, &(GetObjBinAddr<EFI_IFR_BITWISE_NOT>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrToBoolean : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrToBoolean (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TO_BOOLEAN_OP),
+ CIfrOpHeader (EFI_IFR_TO_BOOLEAN_OP, &(GetObjBinAddr<EFI_IFR_TO_BOOLEAN>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrToString : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_TO_STRING *mToString;
+
+public:
+ CIfrToString (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TO_STRING_OP),
+ CIfrOpHeader (EFI_IFR_TO_STRING_OP, &(GetObjBinAddr<EFI_IFR_TO_STRING>())->Header), mToString(GetObjBinAddr<EFI_IFR_TO_STRING>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetFormat (IN UINT8 Format) {
+ mToString->Format = Format;
+ }
+};
+
+class CIfrToUint : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrToUint (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TO_UINT_OP),
+ CIfrOpHeader (EFI_IFR_TO_UINT_OP, &(GetObjBinAddr<EFI_IFR_TO_UINT>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrToUpper : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrToUpper (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TO_UPPER_OP),
+ CIfrOpHeader (EFI_IFR_TO_UPPER_OP, &(GetObjBinAddr<EFI_IFR_TO_UPPER>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrToLower : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrToLower (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TO_LOWER_OP),
+ CIfrOpHeader (EFI_IFR_TO_LOWER_OP, &(GetObjBinAddr<EFI_IFR_TO_LOWER>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrAdd : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrAdd (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_ADD_OP),
+ CIfrOpHeader (EFI_IFR_ADD_OP, &(GetObjBinAddr<EFI_IFR_ADD>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrBitWiseAnd : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrBitWiseAnd (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_BITWISE_AND_OP),
+ CIfrOpHeader (EFI_IFR_BITWISE_AND_OP, &(GetObjBinAddr<EFI_IFR_BITWISE_AND>())->Header) {
+ SetLineNo(LineNo);
+ }
+};
+
+class CIfrBitWiseOr : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrBitWiseOr (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_BITWISE_OR_OP),
+ CIfrOpHeader (EFI_IFR_BITWISE_OR_OP, &(GetObjBinAddr<EFI_IFR_BITWISE_OR>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrAnd : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrAnd (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_AND_OP),
+ CIfrOpHeader (EFI_IFR_AND_OP, &(GetObjBinAddr<EFI_IFR_AND>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrCatenate : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrCatenate (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_CATENATE_OP),
+ CIfrOpHeader (EFI_IFR_CATENATE_OP, &(GetObjBinAddr<EFI_IFR_CATENATE>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrDivide : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrDivide (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_DIVIDE_OP),
+ CIfrOpHeader (EFI_IFR_DIVIDE_OP, &(GetObjBinAddr<EFI_IFR_DIVIDE>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrEqual : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrEqual (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_EQUAL_OP),
+ CIfrOpHeader (EFI_IFR_EQUAL_OP, &(GetObjBinAddr<EFI_IFR_EQUAL>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrGreaterEqual : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrGreaterEqual (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_GREATER_EQUAL_OP),
+ CIfrOpHeader (EFI_IFR_GREATER_EQUAL_OP, &(GetObjBinAddr<EFI_IFR_GREATER_EQUAL>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrGreaterThan : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrGreaterThan (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_GREATER_THAN_OP),
+ CIfrOpHeader (EFI_IFR_GREATER_THAN_OP, &(GetObjBinAddr<EFI_IFR_GREATER_THAN>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrLessEqual : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrLessEqual (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_LESS_EQUAL_OP),
+ CIfrOpHeader (EFI_IFR_LESS_EQUAL_OP, &(GetObjBinAddr<EFI_IFR_LESS_EQUAL>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrLessThan : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrLessThan (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_LESS_THAN_OP),
+ CIfrOpHeader (EFI_IFR_LESS_THAN_OP, &(GetObjBinAddr<EFI_IFR_LESS_THAN>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrMap : public CIfrObj, public CIfrOpHeader{
+public:
+ CIfrMap (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_MAP_OP),
+ CIfrOpHeader (EFI_IFR_MAP_OP, &(GetObjBinAddr<EFI_IFR_MAP>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrMatch : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrMatch (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_MATCH_OP),
+ CIfrOpHeader (EFI_IFR_MATCH_OP, &(GetObjBinAddr<EFI_IFR_MATCH>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrMatch2 : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_MATCH2 *mMatch2;
+
+public:
+ CIfrMatch2 (
+ IN UINT32 LineNo,
+ IN EFI_GUID *Guid
+ ) : CIfrObj (EFI_IFR_MATCH2_OP),
+ CIfrOpHeader (EFI_IFR_MATCH2_OP, &(GetObjBinAddr<EFI_IFR_MATCH2>())->Header), mMatch2(GetObjBinAddr<EFI_IFR_MATCH2>()) {
+ SetLineNo (LineNo);
+ memmove (&mMatch2->SyntaxType, Guid, sizeof (EFI_GUID));
+ }
+};
+
+class CIfrMultiply : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrMultiply (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_MULTIPLY_OP),
+ CIfrOpHeader (EFI_IFR_MULTIPLY_OP, &(GetObjBinAddr<EFI_IFR_MULTIPLY>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrModulo : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrModulo (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_MODULO_OP),
+ CIfrOpHeader (EFI_IFR_MODULO_OP, &(GetObjBinAddr<EFI_IFR_MODULO>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrNotEqual : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrNotEqual (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_NOT_EQUAL_OP),
+ CIfrOpHeader (EFI_IFR_NOT_EQUAL_OP, &(GetObjBinAddr<EFI_IFR_NOT_EQUAL>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrOr : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrOr (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_OR_OP),
+ CIfrOpHeader (EFI_IFR_OR_OP, &(GetObjBinAddr<EFI_IFR_OR>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrShiftLeft : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrShiftLeft (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_SHIFT_LEFT_OP),
+ CIfrOpHeader (EFI_IFR_SHIFT_LEFT_OP, &(GetObjBinAddr<EFI_IFR_SHIFT_LEFT>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrShiftRight : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrShiftRight (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_SHIFT_RIGHT_OP),
+ CIfrOpHeader (EFI_IFR_SHIFT_RIGHT_OP, &(GetObjBinAddr<EFI_IFR_SHIFT_RIGHT>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrSubtract : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrSubtract (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_SUBTRACT_OP),
+ CIfrOpHeader (EFI_IFR_SUBTRACT_OP, &(GetObjBinAddr<EFI_IFR_SUBTRACT>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrConditional : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrConditional (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_CONDITIONAL_OP),
+ CIfrOpHeader (EFI_IFR_CONDITIONAL_OP, &(GetObjBinAddr<EFI_IFR_CONDITIONAL>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrFind : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_FIND *mFind;
+
+public:
+ CIfrFind (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_FIND_OP),
+ CIfrOpHeader (EFI_IFR_FIND_OP, &(GetObjBinAddr<EFI_IFR_FIND>())->Header), mFind(GetObjBinAddr<EFI_IFR_FIND>()) {
+ SetLineNo (LineNo);
+ }
+
+ VOID SetFormat (IN UINT8 Format) {
+ mFind->Format = Format;
+ }
+};
+
+class CIfrMid : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrMid (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_MID_OP),
+ CIfrOpHeader (EFI_IFR_MID_OP, &(GetObjBinAddr<EFI_IFR_MID>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrToken : public CIfrObj, public CIfrOpHeader {
+public:
+ CIfrToken (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_TOKEN_OP),
+ CIfrOpHeader (EFI_IFR_TOKEN_OP, &(GetObjBinAddr<EFI_IFR_TOKEN>())->Header) {
+ SetLineNo (LineNo);
+ }
+};
+
+class CIfrSpan : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_SPAN *mSpan;
+
+public:
+ CIfrSpan (
+ IN UINT32 LineNo
+ ) : CIfrObj (EFI_IFR_SPAN_OP),
+ CIfrOpHeader (EFI_IFR_SPAN_OP, &(GetObjBinAddr<EFI_IFR_SPAN>())->Header), mSpan(GetObjBinAddr<EFI_IFR_SPAN>()) {
+ SetLineNo (LineNo);
+ mSpan->Flags = EFI_IFR_FLAGS_FIRST_MATCHING;
+ }
+
+ EFI_VFR_RETURN_CODE SetFlags (IN UINT8 LFlags) {
+ if (_IS_EQUAL (LFlags, EFI_IFR_FLAGS_FIRST_MATCHING)) {
+ mSpan->Flags |= EFI_IFR_FLAGS_FIRST_MATCHING;
+ } else if (_FLAG_TEST_AND_CLEAR (LFlags, EFI_IFR_FLAGS_FIRST_NON_MATCHING)) {
+ mSpan->Flags |= EFI_IFR_FLAGS_FIRST_NON_MATCHING;
+ }
+
+ return _FLAGS_ZERO (LFlags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
+ }
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrSyntax.g
new file mode 100644
index 00000000..21bf1cbe
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -0,0 +1,5708 @@
+/*++ @file
+Vfr Syntax
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+--*/
+
+#header<<
+
+#include "EfiVfr.h"
+#include "VfrFormPkg.h"
+#include "VfrError.h"
+#include "VfrUtilityLib.h"
+#include "AToken.h"
+#include "ATokPtr.h"
+>>
+
+<<
+#ifdef UINT8_MAX
+#undef UINT8_MAX
+#endif
+#include "stdio.h"
+#include "PBlackBox.h"
+#include "DLexerBase.h"
+#include "VfrLexer.h"
+#include "AToken.h"
+
+#define GET_LINENO(Obj) ((Obj)->getLine())
+#define SET_LINE_INFO(Obj, L) do {(Obj).SetLineNo((L)->getLine());} while (0)
+#define CRT_END_OP(Obj) do {CIfrEnd EObj; if (Obj != NULL) EObj.SetLineNo ((Obj)->getLine());} while (0)
+
+typedef ANTLRCommonToken ANTLRToken;
+
+class CVfrDLGLexer : public VfrLexer
+{
+public:
+ CVfrDLGLexer (DLGFileInput *F) : VfrLexer (F) {};
+ void errstd (const char *Text)
+ {
+ printf ("unrecognized input '%s'\n", Text);
+ }
+};
+
+UINT8
+VfrParserStart (
+ IN FILE *File,
+ IN INPUT_INFO_TO_SYNTAX *InputInfo
+ )
+{
+ ParserBlackBox<CVfrDLGLexer, EfiVfrParser, ANTLRToken> VfrParser(File);
+ VfrParser.parser()->SetOverrideClassGuid (InputInfo->OverrideClassGuid);
+ return VfrParser.parser()->vfrProgram();
+}
+>>
+
+//
+// Define a lexical class for parsing quoted strings. Basically
+// starts with a double quote, and ends with a double quote that
+// is not preceded with a backslash.
+//
+#lexclass QUOTED_STRING
+#token TheString "~[\"]*\"" << mode (START); >>
+
+//
+// Define a lexclass for skipping over C++ style comments
+//
+#lexclass CPP_COMMENT
+#token "~[\n]*" << skip (); >>
+#token "\n" << skip (); mode (START); newline (); >>
+
+//
+// Standard lexclass is START
+//
+#lexclass START
+
+//
+// Find start of C++ style comments
+//
+#token "//" << skip (); mode (CPP_COMMENT); >>
+
+//
+// Skip whitespace
+//
+#token "[\ \t]" << skip (); >>
+
+//
+// Skip over newlines, but count them
+//
+#token "\n" << skip (); newline (); >>
+
+//
+// Skip over 'extern' in any included .H file
+//
+#token "extern" << skip (); mode (CPP_COMMENT); >>
+
+//
+// Tokens for the different keywords. Syntax is:
+// TokenName("ErrorMessageText") "TokenString"
+// where:
+// TokenName is the token name (must be capitalized) that is used in the rules
+// ErrorMessageText is the string the compiler emits when it detects a syntax error
+// TokenString is the actual matching string used in the user script
+//
+#token FormPkgType("formpkgtype") "formpkgtype"
+#token OpenBrace("{") "\{"
+#token CloseBrace("}") "\}"
+#token OpenParen("(") "\("
+#token CloseParen(")") "\)"
+#token OpenBracket("[") "\["
+#token CloseBracket("]") "\]"
+
+#token LineDefinition "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << gCVfrErrorHandle.ParseFileScopeRecord (begexpr (), line ()); skip (); newline (); >>
+#token DevicePath("devicepath") "devicepath"
+#token FormSet("formset") "formset"
+#token FormSetId("formsetid") "formsetid"
+#token EndFormSet("endformset") "endformset"
+#token Title("title") "title"
+#token FormId("formid") "formid"
+#token OneOf("oneof") "oneof"
+#token EndOneOf("endoneof") "endoneof"
+#token Prompt("prompt") "prompt"
+#token OrderedList("orderedlist") "orderedlist"
+#token MaxContainers("maxcontainers") "maxcontainers"
+#token EndList("endlist") "endlist"
+#token EndForm("endform") "endform"
+#token Form("form") "form"
+#token FormMap("formmap") "formmap"
+#token MapTitle("maptitle") "maptitle"
+#token MapGuid("mapguid") "mapguid"
+#token Subtitle("subtitle") "subtitle"
+#token EndSubtitle("endsubtitle") "endsubtitle"
+#token Help("help") "help"
+#token Text("text") "text"
+#token Option("option") "option"
+#token FLAGS("flags") "flags"
+#token Date("date") "date"
+#token EndDate("enddate") "enddate"
+#token Year("year") "year"
+#token Month("month") "month"
+#token Day("day") "day"
+#token Time("time") "time"
+#token EndTime("endtime") "endtime"
+#token Hour("hour") "hour"
+#token Minute("minute") "minute"
+#token Second("second") "second"
+#token GrayOutIf("grayoutif") "grayoutif"
+#token Label("label") "label"
+#token Timeout("timeout") "timeout"
+#token Inventory("inventory") "inventory"
+#token NonNvDataMap("_NON_NV_DATA_MAP") "_NON_NV_DATA_MAP"
+#token Struct("struct") "struct"
+#token Union("union") "union"
+#token Boolean("BOOLEAN") "BOOLEAN"
+#token Uint64("UINT64") "UINT64"
+#token Uint32("UINT32") "UINT32"
+#token Uint16("UINT16") "UINT16"
+#token Char16("CHAR16") "CHAR16"
+#token Uint8("UINT8") "UINT8"
+#token Uuid("guid") "guid"
+#token CheckBox("checkbox") "checkbox"
+#token EndCheckBox("endcheckbox") "endcheckbox"
+#token Numeric("numeric") "numeric"
+#token EndNumeric("endnumeric") "endnumeric"
+#token Minimum("minimum") "minimum"
+#token Maximum("maximum") "maximum"
+#token STEP("step") "step"
+#token Default("default") "default"
+#token Password("password") "password"
+#token EndPassword("endpassword") "endpassword"
+#token String("string") "string"
+#token EndString("endstring") "endstring"
+#token MinSize("minsize") "minsize"
+#token MaxSize("maxsize") "maxsize"
+#token Encoding("encoding") "encoding"
+#token SuppressIf("suppressif") "suppressif"
+#token DisableIf("disableif") "disableif"
+#token Hidden("hidden") "hidden"
+#token Goto("goto") "goto"
+#token FormSetGuid("formsetguid") "formsetguid"
+#token InconsistentIf("inconsistentif") "inconsistentif"
+#token WarningIf("warningif") "warningif"
+#token NoSubmitIf("nosubmitif") "nosubmitif"
+#token EndIf("endif") "endif"
+#token Key("key") "key"
+#token DefaultFlag("DEFAULT") "DEFAULT"
+#token ManufacturingFlag("MANUFACTURING") "MANUFACTURING"
+#token InteractiveFlag("INTERACTIVE") "INTERACTIVE"
+#token NVAccessFlag("NV_ACCESS") "NV_ACCESS"
+#token ResetRequiredFlag("RESET_REQUIRED") "RESET_REQUIRED"
+#token ReconnectRequiredFlag("RECONNECT_REQUIRED") "RECONNECT_REQUIRED"
+#token LateCheckFlag("LATE_CHECK") "LATE_CHECK"
+#token ReadOnlyFlag("READ_ONLY") "READ_ONLY"
+#token OptionOnlyFlag("OPTIONS_ONLY") "OPTIONS_ONLY"
+#token RestStyleFlag("REST_STYLE") "REST_STYLE"
+#token Class("class") "class"
+#token Subclass("subclass") "subclass"
+#token ClassGuid("classguid") "classguid"
+#token TypeDef("typedef") "typedef"
+#token Restore("restore") "restore"
+#token Save("save") "save"
+#token Defaults("defaults") "defaults"
+#token Banner("banner") "banner"
+#token Align("align") "align"
+#token Left("left") "left"
+#token Right("right") "right"
+#token Center("center") "center"
+#token Line("line") "line"
+#token Name("name") "name"
+
+#token VarId("varid") "varid"
+#token Question("question") "question"
+#token QuestionId("questionid") "questionid"
+#token Image("image") "image"
+#token Locked("locked") "locked"
+#token Rule("rule") "rule"
+#token EndRule("endrule") "endrule"
+#token Value("value") "value"
+#token Read("read") "read"
+#token Write("write") "write"
+#token ResetButton("resetbutton") "resetbutton"
+#token EndResetButton("endresetbutton") "endresetbutton"
+#token DefaultStore("defaultstore") "defaultstore"
+#token Attribute("attribute") "attribute"
+#token Varstore("varstore") "varstore"
+#token Efivarstore("efivarstore") "efivarstore"
+#token VarSize("varsize") "varsize"
+#token NameValueVarStore("namevaluevarstore") "namevaluevarstore"
+#token Action("action") "action"
+#token Config("config") "config"
+#token EndAction("endaction") "endaction"
+#token Refresh("refresh") "refresh"
+#token Interval("interval") "interval"
+#token VarstoreDevice("varstoredevice") "varstoredevice"
+#token GuidOp("guidop") "guidop"
+#token EndGuidOp("endguidop") "endguidop"
+#token DataType("datatype") "datatype"
+#token Data("data") "data"
+#token Modal("modal") "modal"
+
+//
+// Define the class and subclass tokens
+//
+#token ClassNonDevice("NONDEVICE") "NON_DEVICE"
+#token ClassDiskDevice("DISK_DEVICE") "DISK_DEVICE"
+#token ClassVideoDevice("VIDEO_DEVICE") "VIDEO_DEVICE"
+#token ClassNetworkDevice("NETWORK_DEVICE") "NETWORK_DEVICE"
+#token ClassInputDevice("INPUT_DEVICE") "INPUT_DEVICE"
+#token ClassOnBoardDevice("ONBOARD_DEVICE") "ONBOARD_DEVICE"
+#token ClassOtherDevice("OTHER_DEVICE") "OTHER_DEVICE"
+
+#token SubclassSetupApplication("SETUP_APPLICATION") "SETUP_APPLICATION"
+#token SubclassGeneralApplication("GENERAL_APPLICATION") "GENERAL_APPLICATION"
+#token SubclassFrontPage("FRONT_PAGE") "FRONT_PAGE"
+#token SubclassSingleUse("SINGLE_USE") "SINGLE_USE"
+
+//
+// This is the overall definition of a VFR form definition script.
+//
+
+vfrProgram > [UINT8 Return] :
+ <<
+ mParserStatus = 0;
+ mCIfrOpHdrIndex = 0;
+ mConstantOnlyInExpression = FALSE;
+ >>
+ (
+ vfrPragmaPackDefinition
+ | vfrDataStructDefinition
+ | vfrDataUnionDefinition
+ )*
+ vfrFormSetDefinition
+ << $Return = mParserStatus; >>
+ ;
+
+pragmaPackShowDef :
+ L:"show" << gCVfrVarDataTypeDB.Pack (L->getLine(), VFR_PACK_SHOW); >>
+ ;
+
+pragmaPackStackDef :
+ <<
+ UINT32 LineNum;
+ UINT8 PackAction;
+ CHAR8 *Identifier = NULL;
+ UINT32 PackNumber = DEFAULT_PACK_ALIGN;
+ >>
+ (
+ L1:"push" << LineNum = L1->getLine(); PackAction = VFR_PACK_PUSH; >>
+ | L2:"pop" << LineNum = L2->getLine(); PackAction = VFR_PACK_POP; >>
+ )
+ {
+ "," ID:StringIdentifier << Identifier = ID->getText(); >>
+ }
+ {
+ "," N:Number << PackAction |= VFR_PACK_ASSIGN; PackNumber = _STOU32(N->getText(), N->getLine()); >>
+ }
+ << gCVfrVarDataTypeDB.Pack (LineNum, PackAction, Identifier, PackNumber); >>
+ ;
+
+pragmaPackNumber :
+ <<
+ UINT32 LineNum;
+ UINT32 PackNumber = DEFAULT_PACK_ALIGN;
+ >>
+ N:Number << LineNum = N->getLine(); PackNumber = _STOU32(N->getText(), N->getLine()); >>
+ << gCVfrVarDataTypeDB.Pack (LineNum, VFR_PACK_ASSIGN, NULL, PackNumber); >>
+ ;
+
+vfrPragmaPackDefinition :
+ "\#pragma" "pack" "\("
+ {
+ pragmaPackShowDef
+ | pragmaPackStackDef
+ | pragmaPackNumber
+ }
+ "\)"
+ ;
+
+ vfrDataUnionDefinition :
+ { TypeDef } Union << gCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>
+ { NonNvDataMap }
+ {
+ N1:StringIdentifier << _PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>
+ }
+ OpenBrace
+ vfrDataStructFields[TRUE]
+ CloseBrace
+ {
+ N2:StringIdentifier << _PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N2->getText()), N2); >>
+ }
+ ";" << gCVfrVarDataTypeDB.DeclareDataTypeEnd ();>>
+ ;
+
+vfrDataStructDefinition :
+ { TypeDef } Struct << gCVfrVarDataTypeDB.DeclareDataTypeBegin (); >>
+ { NonNvDataMap }
+ {
+ N1:StringIdentifier << _PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N1->getText()), N1); >>
+ }
+ OpenBrace
+ vfrDataStructFields[FALSE]
+ CloseBrace
+ {
+ N2:StringIdentifier << _PCATCH(gCVfrVarDataTypeDB.SetNewTypeName (N2->getText()), N2); >>
+ }
+ ";" << gCVfrVarDataTypeDB.DeclareDataTypeEnd (); >>
+ ;
+
+vfrDataStructFields [BOOLEAN FieldInUnion]:
+ (
+ dataStructField64 [FieldInUnion] |
+ dataStructField32 [FieldInUnion] |
+ dataStructField16 [FieldInUnion] |
+ dataStructField8 [FieldInUnion] |
+ dataStructFieldBool [FieldInUnion] |
+ dataStructFieldString [FieldInUnion]|
+ dataStructFieldDate [FieldInUnion] |
+ dataStructFieldTime [FieldInUnion] |
+ dataStructFieldRef [FieldInUnion] |
+ dataStructFieldUser [FieldInUnion] |
+ dataStructBitField64 [FieldInUnion] |
+ dataStructBitField32 [FieldInUnion] |
+ dataStructBitField16 [FieldInUnion] |
+ dataStructBitField8 [FieldInUnion]
+ )*
+ ;
+
+dataStructField64 [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"UINT64"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructField32 [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"UINT32"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructField16 [BOOLEAN FieldInUnion]:
+ <<
+ UINT32 ArrayNum = 0;
+ >>
+ ("UINT16" | "CHAR16")
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), (CHAR8 *) "UINT16", ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructField8 [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"UINT8"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructFieldBool [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"BOOLEAN"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructFieldString [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"EFI_STRING_ID"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructFieldDate [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"EFI_HII_DATE"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructFieldTime [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"EFI_HII_TIME"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructFieldRef [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ D:"EFI_HII_REF"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum, FieldInUnion), N); >>
+ ;
+
+dataStructFieldUser [BOOLEAN FieldInUnion]:
+ << UINT32 ArrayNum = 0; >>
+ T:StringIdentifier
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText(), I->getLine()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), T->getText(), ArrayNum, FieldInUnion), T); >>
+ ;
+
+dataStructBitField64[BOOLEAN FieldInUnion]:
+ <<
+ UINT32 Width = 0;
+ BOOLEAN HasBitFieldName = FALSE;
+ >>
+ D:"UINT64"
+ {
+ N:StringIdentifier << HasBitFieldName = TRUE;>>
+ }
+ ":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
+
+ ";" << if (HasBitFieldName) {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
+ } else {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
+ }
+ >>
+ ;
+
+dataStructBitField32[BOOLEAN FieldInUnion]:
+ <<
+ UINT32 Width = 0;
+ BOOLEAN HasBitFieldName = FALSE;
+ >>
+ D:"UINT32"
+ {
+ N:StringIdentifier << HasBitFieldName = TRUE;>>
+ }
+
+ ":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
+
+ ";" << if (HasBitFieldName) {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
+ } else {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
+ }
+ >>
+ ;
+
+dataStructBitField16[BOOLEAN FieldInUnion]:
+ <<
+ UINT32 Width = 0;
+ BOOLEAN HasBitFieldName = FALSE;
+ >>
+ D:"UINT16"
+ {
+ N:StringIdentifier << HasBitFieldName = TRUE;>>
+ }
+ ":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
+
+ ";" << if (HasBitFieldName) {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
+ } else {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
+ }
+ >>
+ ;
+
+dataStructBitField8[BOOLEAN FieldInUnion]:
+ <<
+ UINT32 Width = 0;
+ BOOLEAN HasBitFieldName = FALSE;
+ >>
+ D:"UINT8"
+ {
+ N:StringIdentifier << HasBitFieldName = TRUE;>>
+ }
+ ":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
+
+ ";" << if (HasBitFieldName) {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
+ } else {
+ _PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
+ }
+ >>
+ ;
+
+//*****************************************************************************
+//
+// the syntax of GUID definition
+//
+guidSubDefinition [EFI_GUID &Guid] :
+ G4:Number "," G5:Number "," G6:Number "," G7:Number "," G8:Number "," G9:Number "," G10:Number "," G11:Number
+ <<
+ Guid.Data4[0] = _STOU8(G4->getText(), G4->getLine());
+ Guid.Data4[1] = _STOU8(G5->getText(), G5->getLine());
+ Guid.Data4[2] = _STOU8(G6->getText(), G6->getLine());
+ Guid.Data4[3] = _STOU8(G7->getText(), G7->getLine());
+ Guid.Data4[4] = _STOU8(G8->getText(), G8->getLine());
+ Guid.Data4[5] = _STOU8(G9->getText(), G9->getLine());
+ Guid.Data4[6] = _STOU8(G10->getText(), G10->getLine());
+ Guid.Data4[7] = _STOU8(G11->getText(), G11->getLine());
+ >>
+ ;
+
+guidDefinition [EFI_GUID &Guid] :
+ OpenBrace
+ G1:Number "," G2:Number "," G3:Number ","
+ <<
+ Guid.Data1 = _STOU32 (G1->getText(), G1->getLine());
+ Guid.Data2 = _STOU16 (G2->getText(), G2->getLine());
+ Guid.Data3 = _STOU16 (G3->getText(), G3->getLine());
+ >>
+ (
+ OpenBrace guidSubDefinition[Guid] CloseBrace
+ | guidSubDefinition[Guid]
+ )
+ CloseBrace
+ ;
+
+//*****************************************************************************
+//
+// the syntax of form set definition
+//
+vfrFormSetDefinition :
+ <<
+ EFI_GUID Guid;
+ EFI_GUID DefaultClassGuid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID;
+ EFI_GUID ClassGuid1, ClassGuid2, ClassGuid3, ClassGuid4;
+ UINT8 ClassGuidNum = 0;
+ CIfrFormSet *FSObj = NULL;
+ UINT16 C, SC;
+ CHAR8* InsertOpcodeAddr = NULL;
+ >>
+ L:FormSet
+ Uuid "=" guidDefinition[Guid] ","
+ Title "=" "STRING_TOKEN" "\(" S1:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" S2:Number "\)" ","
+ {
+ ClassGuid "=" guidDefinition[ClassGuid1] << ++ClassGuidNum; >>
+ {
+ "\|" guidDefinition[ClassGuid2] << ++ClassGuidNum; >>
+ {
+ "\|" guidDefinition[ClassGuid3] << ++ClassGuidNum; >>
+ {
+ "\|" guidDefinition[ClassGuid4] << ++ClassGuidNum; >>
+ }
+ }
+ }
+ ","
+ }
+ <<
+ if (mOverrideClassGuid != NULL && ClassGuidNum >= 4) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Already has 4 class guids, can't add extra class guid!");
+ }
+ switch (ClassGuidNum) {
+ case 0:
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum = 2;
+ } else {
+ ClassGuidNum = 1;
+ }
+ FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
+ FSObj->SetClassGuid(&DefaultClassGuid);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
+ break;
+ case 1:
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum ++;
+ }
+ FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
+ FSObj->SetClassGuid(&ClassGuid1);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
+ break;
+ case 2:
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum ++;
+ }
+ FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
+ FSObj->SetClassGuid(&ClassGuid1);
+ FSObj->SetClassGuid(&ClassGuid2);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
+ break;
+ case 3:
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum ++;
+ }
+ FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
+ FSObj->SetClassGuid(&ClassGuid1);
+ FSObj->SetClassGuid(&ClassGuid2);
+ FSObj->SetClassGuid(&ClassGuid3);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
+ break;
+ case 4:
+ FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
+ FSObj->SetClassGuid(&ClassGuid1);
+ FSObj->SetClassGuid(&ClassGuid2);
+ FSObj->SetClassGuid(&ClassGuid3);
+ FSObj->SetClassGuid(&ClassGuid4);
+ break;
+ default:
+ break;
+ }
+
+ SET_LINE_INFO (*FSObj, L);
+ FSObj->SetGuid (&Guid);
+ FSObj->SetFormSetTitle (_STOSID(S1->getText(), S1->getLine()));
+ FSObj->SetHelp (_STOSID(S2->getText(), S2->getLine()));
+ >>
+ {
+ FC:Class "=" classDefinition[C] "," << {CIfrClass CObj;SET_LINE_INFO (CObj, FC); CObj.SetClass(C);} >>
+ }
+ {
+ FSC:Subclass "=" subclassDefinition[SC] "," << {CIfrSubClass SCObj; SET_LINE_INFO (SCObj, FSC); SCObj.SetSubClass(SC);} >>
+ }
+ <<
+ _DeclareStandardDefaultStorage (GET_LINENO (L));
+ >>
+ vfrFormSetList
+ E:EndFormSet <<
+ //
+ // Declare undefined Question so that they can be used in expression.
+ //
+ if (gCFormPkg.HavePendingUnassigned()) {
+ mParserStatus += gCFormPkg.DeclarePendingQuestion (
+ gCVfrVarDataTypeDB,
+ gCVfrDataStorage,
+ mCVfrQuestionDB,
+ &mFormsetGuid,
+ E->getLine(),
+ &InsertOpcodeAddr
+ );
+ gNeedAdjustOpcode = TRUE;
+ }
+
+ CRT_END_OP (E);
+
+ //
+ // Adjust the pending question position.
+ // Move the position from current to before the end of the last form in the form set.
+ //
+ if (gNeedAdjustOpcode) {
+ gCFormPkg.AdjustDynamicInsertOpcode (
+ mLastFormEndAddr,
+ InsertOpcodeAddr,
+ FALSE
+ );
+ }
+
+ if (FSObj != NULL) {
+ delete FSObj;
+ }
+ >>
+ ";"
+ ;
+
+vfrFormSetList :
+ (
+ vfrFormDefinition |
+ vfrFormMapDefinition |
+ vfrStatementImage |
+ vfrStatementVarStoreLinear |
+ vfrStatementVarStoreEfi |
+ vfrStatementVarStoreNameValue |
+ vfrStatementDefaultStore |
+ vfrStatementDisableIfFormSet |
+ vfrStatementSuppressIfFormSet |
+ vfrStatementExtension
+ )*
+ ;
+
+vfrStatementExtension:
+ <<
+ EFI_GUID Guid;
+ CIfrGuid *GuidObj = NULL;
+ CHAR8 *TypeName = NULL;
+ UINT32 TypeSize = 0;
+ UINT8 *DataBuff = NULL;
+ UINT32 Size = 0;
+ UINT8 Idx = 0;
+ UINT32 LineNum;
+ BOOLEAN IsStruct = FALSE;
+ UINT32 ArrayNum = 0;
+ >>
+ L:GuidOp
+ Uuid "=" guidDefinition[Guid]
+ {"," DataType "="
+ (
+ U64:"UINT64" {OpenBracket AN1:Number CloseBracket <<ArrayNum = _STOU32(AN1->getText(), AN1->getLine());>>}
+ << TypeName = U64->getText(); LineNum = U64->getLine(); >>
+ | U32:"UINT32" {OpenBracket AN2:Number CloseBracket <<ArrayNum = _STOU32(AN2->getText(), AN2->getLine());>>}
+ << TypeName = U32->getText(); LineNum = U32->getLine(); >>
+ | U16:"UINT16" {OpenBracket AN3:Number CloseBracket <<ArrayNum = _STOU32(AN3->getText(), AN3->getLine());>>}
+ << TypeName = U16->getText(); LineNum = U16->getLine(); >>
+ | U8:"UINT8" {OpenBracket AN4:Number CloseBracket <<ArrayNum = _STOU32(AN4->getText(), AN4->getLine());>>}
+ << TypeName = U8->getText(); LineNum = U8->getLine(); >>
+ | BL:"BOOLEAN" {OpenBracket AN5:Number CloseBracket <<ArrayNum = _STOU32(AN5->getText(), AN5->getLine());>>}
+ << TypeName = BL->getText(); LineNum = BL->getLine(); >>
+ | SI:"EFI_STRING_ID" {OpenBracket AN6:Number CloseBracket <<ArrayNum = _STOU32(AN6->getText(), AN6->getLine());>>}
+ << TypeName = SI->getText(); LineNum = SI->getLine(); >>
+ | D:"EFI_HII_DATE" {OpenBracket AN7:Number CloseBracket <<ArrayNum = _STOU32(AN7->getText(), AN7->getLine());>>}
+ << TypeName = D->getText(); LineNum = D->getLine(); IsStruct = TRUE;>>
+ | T:"EFI_HII_TIME" {OpenBracket AN8:Number CloseBracket <<ArrayNum = _STOU32(AN8->getText(), AN8->getLine());>>}
+ << TypeName = T->getText(); LineNum = T->getLine(); IsStruct = TRUE;>>
+ | R:"EFI_HII_REF" {OpenBracket AN9:Number CloseBracket <<ArrayNum = _STOU32(AN9->getText(), AN9->getLine());>>}
+ << TypeName = R->getText(); LineNum = R->getLine(); IsStruct = TRUE;>>
+ | TN:StringIdentifier {OpenBracket AN10:Number CloseBracket <<ArrayNum = _STOU32(AN10->getText(), AN10->getLine());>>}
+ << TypeName = TN->getText(); LineNum = TN->getLine(); IsStruct = TRUE;>>
+ )
+ <<
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &TypeSize), LineNum);
+ if (ArrayNum > 0) {
+ Size = TypeSize*ArrayNum;
+ } else {
+ Size = TypeSize;
+ }
+ if (Size > (128 - sizeof (EFI_IFR_GUID))) return;
+ DataBuff = (UINT8 *)malloc(Size);
+ for (Idx = 0; Idx < Size; Idx++) {
+ DataBuff[Idx] = 0;
+ }
+ >>
+ vfrExtensionData [DataBuff, Size, TypeName, TypeSize, IsStruct, ArrayNum]
+ }
+ <<
+ {
+ GuidObj = new CIfrGuid(Size);
+ if (GuidObj != NULL) {
+ GuidObj->SetLineNo(L->getLine());
+ GuidObj->SetGuid (&Guid);
+ }
+ }
+ if (TypeName != NULL) {
+ GuidObj->SetData(DataBuff, Size);
+ }
+ >>
+ {","
+ (
+ vfrStatementExtension
+ )*
+ E:EndGuidOp << GuidObj->SetScope(1); CRT_END_OP (E); >>
+ }
+ <<
+ if (GuidObj != NULL) delete GuidObj;
+ if (DataBuff != NULL) free(DataBuff);
+ >>
+ ";"
+;
+
+vfrExtensionData[UINT8 *DataBuff, UINT32 Size, CHAR8 *TypeName, UINT32 TypeSize, BOOLEAN IsStruct, UINT32 ArrayNum]:
+ <<
+ CHAR8 *TFName = NULL;
+ UINT32 ArrayIdx = 0;
+ UINT16 FieldOffset;
+ UINT8 FieldType;
+ UINT32 FieldSize;
+ UINT64 Data_U64 = 0;
+ UINT32 Data_U32 = 0;
+ UINT16 Data_U16 = 0;
+ UINT8 Data_U8 = 0;
+ BOOLEAN Data_BL = 0;
+ EFI_STRING_ID Data_SID = 0;
+ BOOLEAN IsArray = FALSE;
+ UINT8 *ByteOffset = NULL;
+ BOOLEAN BitField = FALSE;
+ UINT64 Value;
+ UINT64 Mask;
+ UINT16 Offset;
+ UINT8 PreBits;
+ >>
+(
+ ("," "data" {OpenBracket IDX1:Number CloseBracket <<IsArray = TRUE;>>}
+ <<
+ ArrayIdx = 0;
+ if (IsArray == TRUE) {
+ ArrayIdx = _STOU8(IDX1->getText(), IDX1->getLine());
+ if (ArrayIdx >= ArrayNum) return;
+ IsArray = FALSE;
+ }
+ ByteOffset = DataBuff + (ArrayIdx * TypeSize);
+ if (IsStruct == TRUE) {
+ _STRCAT(&TFName, TypeName);
+ }
+ >>
+ ("." FN:StringIdentifier
+ <<
+ if (IsStruct == TRUE) {
+ _STRCAT(&TFName, ".");
+ _STRCAT(&TFName, FN->getText());
+ }
+ >>
+ {
+ OpenBracket IDX2:Number CloseBracket
+ <<
+ if (IsStruct == TRUE) {
+ _STRCAT(&TFName, "[");
+ _STRCAT(&TFName, IDX2->getText());
+ _STRCAT(&TFName, "]");
+ }
+ >>
+ }
+ )*
+ "=" RD:Number
+ <<
+ if (IsStruct == FALSE) {
+ if (strcmp ("UINT64", TypeName) == 0) {
+ Data_U64 = _STOU64(RD->getText(), RD->getLine());
+ memcpy (ByteOffset, &Data_U64, TypeSize);
+ }else if (strcmp ("UINT32", TypeName) == 0) {
+ Data_U32 = _STOU32(RD->getText(), RD->getLine());
+ memcpy (ByteOffset, &Data_U32, TypeSize);
+ }else if (strcmp ("UINT16", TypeName) == 0) {
+ Data_U16 = _STOU16(RD->getText(), RD->getLine());
+ memcpy (ByteOffset, &Data_U16, TypeSize);
+ }else if (strcmp ("UINT8", TypeName) == 0) {
+ Data_U8 = _STOU8(RD->getText(), RD->getLine());
+ memcpy (ByteOffset, &Data_U8, TypeSize);
+ }else if (strcmp ("BOOLEAN", TypeName)== 0) {
+ Data_BL = _STOU8(RD->getText(), RD->getLine());
+ memcpy (ByteOffset, &Data_BL, TypeSize);
+ }else if (strcmp ("EFI_STRING_ID", TypeName) == 0) {
+ Data_SID = _STOSID(RD->getText(), RD->getLine());
+ memcpy (ByteOffset, &Data_SID, TypeSize);
+ }
+ } else {
+ gCVfrVarDataTypeDB.GetDataFieldInfo(TFName, FieldOffset, FieldType, FieldSize, BitField);
+ if (BitField) {
+ Mask = (1 << FieldSize) - 1;
+ Offset = FieldOffset / 8;
+ PreBits = FieldOffset % 8;
+ Mask <<= PreBits;
+ }
+ switch (FieldType) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data_U8 = _STOU8(RD->getText(), RD->getLine());
+ if (BitField) {
+ //
+ // Set the value to the bit fileds.
+ //
+ Value = *(UINT8*) (ByteOffset + Offset);
+ Data_U8 <<= PreBits;
+ Value = (Value & (~Mask)) | Data_U8;
+ memcpy (ByteOffset + Offset, &Value, sizeof (UINT8));
+ } else {
+ memcpy (ByteOffset + FieldOffset, &Data_U8, FieldSize);
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data_U16 = _STOU16(RD->getText(), RD->getLine());
+ if (BitField) {
+ //
+ // Set the value to the bit fileds.
+ //
+ Value = *(UINT16*) (ByteOffset + Offset);
+ Data_U16 <<= PreBits;
+ Value = (Value & (~Mask)) | Data_U16;
+ memcpy (ByteOffset + Offset, &Value, sizeof (UINT16));
+ } else {
+ memcpy (ByteOffset + FieldOffset, &Data_U16, FieldSize);
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data_U32 = _STOU32(RD->getText(), RD->getLine());
+ if (BitField) {
+ //
+ // Set the value to the bit fileds.
+ //
+ Value = *(UINT32*) (ByteOffset + Offset);
+ Data_U32 <<= PreBits;
+ Value = (Value & (~Mask)) | Data_U32;
+ memcpy (ByteOffset + Offset, &Value, sizeof (UINT32));
+ } else {
+ memcpy (ByteOffset + FieldOffset, &Data_U32, FieldSize);
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data_U64 = _STOU64(RD->getText(), RD->getLine());
+ if (BitField) {
+ //
+ // Set the value to the bit fileds.
+ //
+ Value = *(UINT64*) (ByteOffset + Offset);
+ Data_U64 <<= PreBits;
+ Value = (Value & (~Mask)) | Data_U64;
+ memcpy (ByteOffset + Offset, &Value, sizeof (UINT64));
+ } else {
+ memcpy (ByteOffset + FieldOffset, &Data_U64, FieldSize);
+ }
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data_BL = _STOU8(RD->getText(), RD->getLine());
+ memcpy (ByteOffset + FieldOffset, &Data_BL, FieldSize);
+ break;
+ case EFI_IFR_TYPE_STRING:
+ Data_SID = _STOSID(RD->getText(), RD->getLine());
+ memcpy (ByteOffset + FieldOffset, &Data_SID, FieldSize);
+ break;
+ default:
+ break;
+ }
+ }
+ if (TFName != NULL) { delete[] TFName; TFName = NULL; }
+ >>
+ )*
+)
+;
+
+
+vfrStatementDefaultStore :
+ << UINT16 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD; >>
+ D:DefaultStore N:StringIdentifier ","
+ Prompt "=" "STRING_TOKEN" "\(" S:Number "\)"
+ {
+ "," Attribute "=" A:Number << DefaultId = _STOU16(A->getText(), A->getLine()); >>
+ }
+ <<
+ if (gCVfrDefaultStore.DefaultIdRegistered (DefaultId) == FALSE) {
+ CIfrDefaultStore DSObj;
+ _PCATCH(gCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr<CHAR8>(), N->getText(), _STOSID(S->getText(), S->getLine()), DefaultId)), D->getLine();
+ DSObj.SetLineNo(D->getLine());
+ DSObj.SetDefaultName (_STOSID(S->getText(), S->getLine()));
+ DSObj.SetDefaultId (DefaultId);
+ } else {
+ _PCATCH(gCVfrDefaultStore.ReRegisterDefaultStoreById (DefaultId, N->getText(), _STOSID(S->getText(), S->getLine()))), D->getLine();
+ }
+ >>
+ ";"
+ ;
+
+vfrStatementVarStoreLinear :
+ <<
+ EFI_GUID Guid;
+ CIfrVarStore VSObj;
+ CHAR8 *TypeName;
+ CHAR8 *StoreName;
+ UINT32 LineNum;
+ EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
+ UINT32 Size;
+ BOOLEAN IsBitVarStore = FALSE;
+ >>
+ V:Varstore << VSObj.SetLineNo(V->getLine()); >>
+ (
+ TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); IsBitVarStore = gCVfrVarDataTypeDB.DataTypeHasBitField (TN->getText());>>
+ | U8:"UINT8" "," << TypeName = U8->getText(); LineNum = U8->getLine(); >>
+ | U16:"UINT16" "," << TypeName = U16->getText(); LineNum = U16->getLine(); >>
+ | C16:"CHAR16" "," << TypeName = (CHAR8 *) "UINT16"; LineNum = C16->getLine(); >>
+ | U32:"UINT32" "," << TypeName = U32->getText(); LineNum = U32->getLine(); >>
+ | U64:"UINT64" "," << TypeName = U64->getText(); LineNum = U64->getLine(); >>
+ | D:"EFI_HII_DATE" "," << TypeName = D->getText(); LineNum = D->getLine(); >>
+ | T:"EFI_HII_TIME" "," << TypeName = T->getText(); LineNum = T->getLine(); >>
+ | R:"EFI_HII_REF" "," << TypeName = R->getText(); LineNum = R->getLine(); >>
+ )
+ {
+ VarId "=" ID:Number "," <<
+ _PCATCH(
+ (INTN)(VarStoreId = _STOU16(ID->getText(), ID->getLine())) != 0,
+ (INTN)TRUE,
+ ID,
+ "varid 0 is not allowed."
+ );
+ >>
+ }
+ Name "=" SN:StringIdentifier ","
+ Uuid "=" guidDefinition[Guid]
+ <<
+
+ StoreName = SN->getText();
+ _PCATCH(gCVfrDataStorage.DeclareBufferVarStore (
+ StoreName,
+ &Guid,
+ &gCVfrVarDataTypeDB,
+ TypeName,
+ VarStoreId,
+ IsBitVarStore
+ ), LineNum);
+ VSObj.SetGuid (&Guid);
+ _PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);
+ VSObj.SetVarStoreId (VarStoreId);
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);
+ VSObj.SetSize ((UINT16) Size);
+ VSObj.SetName (SN->getText());
+ >>
+ ";"
+ ;
+
+vfrStatementVarStoreEfi :
+ <<
+ BOOLEAN IsUEFI23EfiVarstore = TRUE;
+ EFI_GUID Guid;
+ CIfrVarStoreEfi VSEObj;
+ EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
+ UINT32 Attr = 0;
+ UINT32 Size;
+ CHAR8 *TypeName;
+ UINT32 LineNum;
+ CHAR8 *StoreName = NULL;
+ BOOLEAN CustomizedName = FALSE;
+ BOOLEAN IsBitVarStore = FALSE;
+ >>
+ E:Efivarstore << VSEObj.SetLineNo(E->getLine()); >>
+ (
+ TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); CustomizedName = TRUE; IsBitVarStore = gCVfrVarDataTypeDB.DataTypeHasBitField (TN->getText());>>
+ | U8:"UINT8" "," << TypeName = U8->getText(); LineNum = U8->getLine(); >>
+ | U16:"UINT16" "," << TypeName = U16->getText(); LineNum = U16->getLine(); >>
+ | C16:"CHAR16" "," << TypeName = (CHAR8 *) "UINT16"; LineNum = C16->getLine(); >>
+ | U32:"UINT32" "," << TypeName = U32->getText(); LineNum = U32->getLine(); >>
+ | U64:"UINT64" "," << TypeName = U64->getText(); LineNum = U64->getLine(); >>
+ | D:"EFI_HII_DATE" "," << TypeName = D->getText(); LineNum = D->getLine(); >>
+ | T:"EFI_HII_TIME" "," << TypeName = T->getText(); LineNum = T->getLine(); >>
+ | R:"EFI_HII_REF" "," << TypeName = R->getText(); LineNum = R->getLine(); >>
+ )
+ {
+ VarId "=" ID:Number "," <<
+ _PCATCH(
+ (INTN)(VarStoreId = _STOU16(ID->getText(), ID->getLine())) != 0,
+ (INTN)TRUE,
+ ID,
+ "varid 0 is not allowed."
+ );
+ >>
+ }
+ Attribute "=" vfrVarStoreEfiAttr[Attr] ( "\|" vfrVarStoreEfiAttr[Attr] )* ","
+ << VSEObj.SetAttributes (Attr); >>
+
+ (
+ Name "=" SN:StringIdentifier "," << StoreName = SN->getText(); >>
+ |
+ Name "=" "STRING_TOKEN" "\(" VN:Number "\)" ","
+ VarSize "=" N:Number "," <<
+ IsUEFI23EfiVarstore = FALSE;
+ StoreName = gCVfrStringDB.GetVarStoreNameFormStringId(_STOSID(VN->getText(), VN->getLine()));
+ if (StoreName == NULL) {
+ _PCATCH (VFR_RETURN_UNSUPPORTED, VN->getLine(), "Can't get varstore name for this StringId!");
+ }
+ if (!CustomizedName) {
+ _PCATCH (VFR_RETURN_UNSUPPORTED, E->getLine(), "Old style efivarstore must have String Identifier!");
+ return;
+ }
+ Size = _STOU32(N->getText(), N->getLine());
+ switch (Size) {
+ case 1:
+ TypeName = (CHAR8 *) "UINT8";
+ break;
+ case 2:
+ TypeName = (CHAR8 *) "UINT16";
+ break;
+ case 4:
+ TypeName = (CHAR8 *) "UINT32";
+ break;
+ case 8:
+ TypeName = (CHAR8 *) "UINT64";
+ break;
+ default:
+ _PCATCH (VFR_RETURN_UNSUPPORTED, N);
+ break;
+ }
+ >>
+ )
+
+ Uuid "=" guidDefinition[Guid] <<
+ if (IsUEFI23EfiVarstore) {
+ _PCATCH(gCVfrDataStorage.DeclareBufferVarStore (
+ StoreName,
+ &Guid,
+ &gCVfrVarDataTypeDB,
+ TypeName,
+ VarStoreId,
+ IsBitVarStore
+ ), LineNum);
+ _PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);
+ } else {
+ _PCATCH(gCVfrDataStorage.DeclareBufferVarStore (
+ TN->getText(),
+ &Guid,
+ &gCVfrVarDataTypeDB,
+ TypeName,
+ VarStoreId,
+ FALSE
+ ), LineNum);
+ _PCATCH(gCVfrDataStorage.GetVarStoreId(TN->getText(), &VarStoreId, &Guid), VN);
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), N->getLine());
+ }
+ VSEObj.SetGuid (&Guid);
+ VSEObj.SetVarStoreId (VarStoreId);
+
+ VSEObj.SetSize ((UINT16) Size);
+ VSEObj.SetName (StoreName);
+ if (IsUEFI23EfiVarstore == FALSE && StoreName != NULL) {
+ delete[] StoreName;
+ }
+ >>
+ ";"
+ ;
+
+vfrVarStoreEfiAttr [UINT32 & Attr] :
+ N:Number << $Attr |= _STOU32(N->getText(), N->getLine()); >>
+ ;
+
+vfrStatementVarStoreNameValue :
+ <<
+ EFI_GUID Guid;
+ CIfrVarStoreNameValue VSNVObj;
+ EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
+ BOOLEAN Created = FALSE;
+ >>
+ L:NameValueVarStore << VSNVObj.SetLineNo(L->getLine()); >>
+ SN:StringIdentifier ","
+ {
+ VarId "=" ID:Number "," <<
+ _PCATCH(
+ (INTN)(VarStoreId = _STOU16(ID->getText(), ID->getLine())) != 0,
+ (INTN)TRUE,
+ ID,
+ "varid 0 is not allowed."
+ );
+ >>
+ }
+ (
+ Name "=" "STRING_TOKEN" "\(" N:Number "\)" "," <<
+ if (!Created) {
+ _PCATCH(gCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText(), VarStoreId), SN);
+ Created = TRUE;
+ }
+ _PCATCH(gCVfrDataStorage.NameTableAddItem (_STOSID(N->getText(), N->getLine())), SN);
+ >>
+ )+
+ Uuid "=" guidDefinition[Guid] << _PCATCH(gCVfrDataStorage.DeclareNameVarStoreEnd (&Guid), SN); >>
+ <<
+ VSNVObj.SetGuid (&Guid);
+ _PCATCH(gCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId, &Guid), SN);
+ VSNVObj.SetVarStoreId (VarStoreId);
+ >>
+ ";"
+ ;
+
+//
+// keep classDefinition and validClassNames for compatibility but not generate
+// any IFR object
+//
+classDefinition[UINT16 & Class] :
+ << $Class = 0; >>
+ validClassNames[$Class] ( "\|" validClassNames[$Class] )*
+ ;
+
+validClassNames[UINT16 & Class] :
+ ClassNonDevice << $Class |= EFI_NON_DEVICE_CLASS; >>
+ | ClassDiskDevice << $Class |= EFI_DISK_DEVICE_CLASS; >>
+ | ClassVideoDevice << $Class |= EFI_VIDEO_DEVICE_CLASS; >>
+ | ClassNetworkDevice << $Class |= EFI_NETWORK_DEVICE_CLASS; >>
+ | ClassInputDevice << $Class |= EFI_INPUT_DEVICE_CLASS; >>
+ | ClassOnBoardDevice << $Class |= EFI_ON_BOARD_DEVICE_CLASS; >>
+ | ClassOtherDevice << $Class |= EFI_OTHER_DEVICE_CLASS; >>
+ | N:Number << $Class |= _STOU16(N->getText(), N->getLine()); >>
+ ;
+
+subclassDefinition[UINT16 & SubClass] :
+ << $SubClass = 0; >>
+ SubclassSetupApplication << $SubClass |= EFI_SETUP_APPLICATION_SUBCLASS; >>
+ | SubclassGeneralApplication << $SubClass |= EFI_GENERAL_APPLICATION_SUBCLASS; >>
+ | SubclassFrontPage << $SubClass |= EFI_FRONT_PAGE_SUBCLASS; >>
+ | SubclassSingleUse << $SubClass |= EFI_SINGLE_USE_SUBCLASS; >>
+ | N:Number << $SubClass |= _STOU16(N->getText(), N->getLine()); >>
+ ;
+
+vfrStatementDisableIfFormSet :
+ <<
+ CIfrDisableIf DIObj;
+ mConstantOnlyInExpression = TRUE;
+ >>
+ D:DisableIf << DIObj.SetLineNo(D->getLine()); >>
+ vfrStatementExpression[0] ";" << mConstantOnlyInExpression = FALSE; >>
+ vfrFormSetList
+ E:EndIf << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrStatementSuppressIfFormSet :
+ << CIfrSuppressIf SIObj;>>
+ L:SuppressIf <<
+ SIObj.SetLineNo(L->getLine());
+ >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0] ";"
+ vfrFormSetList
+ E: EndIf
+ ";" << CRT_END_OP (E); >>
+ ;
+
+//*****************************************************************************
+//
+// the syntax of question header and statement header
+//
+vfrStatementHeader[CIfrStatementHeader *SHObj] :
+ Prompt "=" "STRING_TOKEN" "\(" S1:Number "\)" "," << $SHObj->SetPrompt (_STOSID(S1->getText(), S1->getLine())); >>
+ Help "=" "STRING_TOKEN" "\(" S2:Number "\)" << $SHObj->SetHelp (_STOSID(S2->getText(), S2->getLine())); >>
+ ;
+
+vfrQuestionBaseInfo[EFI_VARSTORE_INFO & Info, EFI_QUESTION_ID & QId, EFI_QUESION_TYPE QType = QUESTION_NORMAL]:
+ <<
+ CHAR8 *QName = NULL;
+ CHAR8 *VarIdStr = NULL;
+ mUsedDefaultCount = 0;
+ >>
+ {
+ Name "=" QN:StringIdentifier "," <<
+ QName = QN->getText();
+ _PCATCH(mCVfrQuestionDB.FindQuestion (QName), VFR_RETURN_UNDEFINED, QN, "has already been used please used anther name");
+ >>
+ }
+ { V:VarId "=" vfrStorageVarId[Info, VarIdStr] "," }
+ {
+ QuestionId "=" ID:Number "," <<
+ QId = _STOQID(ID->getText(), ID->getLine());
+ _PCATCH(mCVfrQuestionDB.FindQuestion (QId), VFR_RETURN_UNDEFINED, ID, "has already been used please assign another number");
+ >>
+ }
+ <<
+ switch (QType) {
+ case QUESTION_NORMAL:
+ mCVfrQuestionDB.RegisterQuestion (QName, VarIdStr, QId);
+ break;
+ case QUESTION_DATE:
+ mCVfrQuestionDB.RegisterNewDateQuestion (QName, VarIdStr, QId);
+ break;
+ case QUESTION_TIME:
+ mCVfrQuestionDB.RegisterNewTimeQuestion (QName, VarIdStr, QId);
+ break;
+ case QUESTION_REF:
+ //
+ // VarIdStr != NULL stand for question with storagae.
+ //
+ if (VarIdStr != NULL) {
+ mCVfrQuestionDB.RegisterRefQuestion (QName, VarIdStr, QId);
+ } else {
+ mCVfrQuestionDB.RegisterQuestion (QName, NULL, QId);
+ }
+ break;
+ default:
+ _PCATCH(VFR_RETURN_FATAL_ERROR);
+ }
+ >>
+ <<
+ if (VarIdStr != NULL) {
+ delete[] VarIdStr;
+ }
+ _SAVE_CURRQEST_VARINFO (Info);
+ >>
+ ;
+
+vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_NORMAL]:
+ <<
+ EFI_VARSTORE_INFO Info;
+ Info.mVarType = EFI_IFR_TYPE_OTHER;
+ Info.mVarTotalSize = 0;
+ Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ Info.mIsBitVar = FALSE;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ >>
+ vfrQuestionBaseInfo[Info, QId, QType]
+ << $QHObj.SetQuestionId (QId);
+ if (Info.mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ $QHObj.SetVarStoreInfo (&Info);
+ }
+ >>
+ vfrStatementHeader[&$QHObj]
+ ;
+
+questionheaderFlagsField[UINT8 & Flags] :
+ ReadOnlyFlag << $Flags |= 0x01; >>
+ | InteractiveFlag << $Flags |= 0x04; >>
+ | ResetRequiredFlag << $Flags |= 0x10; >>
+ | RestStyleFlag << $Flags |= 0x20; >>
+ | ReconnectRequiredFlag << $Flags |= 0x40; >>
+ | O:OptionOnlyFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ O->getLine(),
+ O->getText()
+ );
+ >>
+ | N:NVAccessFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ N->getLine(),
+ N->getText()
+ );
+ >>
+ | L:LateCheckFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ L->getLine(),
+ L->getText()
+ );
+ >>
+ ;
+
+vfrStorageVarId[EFI_VARSTORE_INFO & Info, CHAR8 *&QuestVarIdStr, BOOLEAN CheckFlag = TRUE] :
+ <<
+ UINT32 Idx;
+ UINT32 LineNo;
+ EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
+ CHAR8 *VarIdStr = NULL;
+ CHAR8 *VarStr = NULL;
+ CHAR8 *SName = NULL;
+ CHAR8 *TName = NULL;
+ EFI_VFR_RETURN_CODE VfrReturnCode = VFR_RETURN_SUCCESS;
+ EFI_IFR_TYPE_VALUE Dummy = gZeroEfiIfrTypeValue;
+ EFI_GUID *VarGuid = NULL;
+ >>
+ (
+ SN1:StringIdentifier << SName = SN1->getText(); _STRCAT(&VarIdStr, SN1->getText()); >>
+ OpenBracket I1:Number CloseBracket <<
+ Idx = _STOU32(I1->getText(), I1->getLine());
+ _STRCAT(&VarIdStr, "[");
+ _STRCAT(&VarIdStr, I1->getText());
+ _STRCAT(&VarIdStr, "]");
+ >>
+ <<
+ VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId);
+ if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {
+ _PCATCH(VfrReturnCode, SN1);
+ _PCATCH(gCVfrDataStorage.GetNameVarStoreInfo (&$Info, Idx), SN1);
+ }
+
+ QuestVarIdStr = VarIdStr;
+ >>
+ )
+ |
+ (
+ SN2:StringIdentifier << SName = SN2->getText(); _STRCAT(&VarIdStr, SName); >>
+ <<
+ VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId);
+ if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {
+ _PCATCH(VfrReturnCode, SN2);
+ VarStoreType = gCVfrDataStorage.GetVarStoreType ($Info.mVarStoreId);
+ if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {
+ _PCATCH(gCVfrDataStorage.GetBufferVarStoreDataTypeName(Info.mVarStoreId, &TName), SN2);
+ _STRCAT(&VarStr, TName);
+ }
+ }
+ >>
+
+ (
+ "." <<
+ if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {
+ _PCATCH((((VarStoreType != EFI_VFR_VARSTORE_BUFFER) && (VarStoreType != EFI_VFR_VARSTORE_BUFFER_BITS))? VFR_RETURN_EFIVARSTORE_USE_ERROR : VFR_RETURN_SUCCESS), SN2);
+ }
+ _STRCAT(&VarIdStr, "."); _STRCAT(&VarStr, ".");
+ >>
+ SF:StringIdentifier << _STRCAT(&VarIdStr, SF->getText()); _STRCAT(&VarStr, SF->getText()); >>
+ {
+ OpenBracket I2:Number CloseBracket <<
+ Idx = _STOU32(I2->getText(), I2->getLine());
+ if (Idx > 0) {
+ //
+ // Idx == 0, [0] can be ignored.
+ // Array[0] is same to Array for unify the varid name to cover [0]
+ //
+ _STRCAT(&VarIdStr, "[");
+ _STRCAT(&VarIdStr, I2->getText());
+ _STRCAT(&VarIdStr, "]");
+ }
+ _STRCAT(&VarStr, "[");
+ _STRCAT(&VarStr, I2->getText());
+ _STRCAT(&VarStr, "]");
+ >>
+ }
+ )* <<
+ switch (VarStoreType) {
+ case EFI_VFR_VARSTORE_EFI:
+ _PCATCH(gCVfrDataStorage.GetEfiVarStoreInfo (&$Info), SN2);
+ break;
+ case EFI_VFR_VARSTORE_BUFFER:
+ case EFI_VFR_VARSTORE_BUFFER_BITS:
+ _PCATCH(gCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, $Info.mInfo.mVarOffset, $Info.mVarType, $Info.mVarTotalSize, $Info.mIsBitVar), SN2->getLine(), VarStr);
+ VarGuid = gCVfrDataStorage.GetVarStoreGuid($Info.mVarStoreId);
+ _PCATCH((EFI_VFR_RETURN_CODE)gCVfrBufferConfig.Register (
+ SName,
+ VarGuid,
+ NULL),
+ SN2->getLine());
+ _PCATCH((EFI_VFR_RETURN_CODE)gCVfrBufferConfig.Write (
+ 'a',
+ SName,
+ VarGuid,
+ NULL,
+ $Info.mVarType,
+ $Info.mInfo.mVarOffset,
+ $Info.mVarTotalSize,
+ Dummy),
+ SN2->getLine());
+ _PCATCH(gCVfrDataStorage.AddBufferVarStoreFieldInfo(&$Info ),SN2->getLine());
+ break;
+ case EFI_VFR_VARSTORE_NAME:
+ default: break;
+ }
+
+ QuestVarIdStr = VarIdStr;
+ if (VarStr != NULL) {delete[] VarStr;}
+ >>
+ )
+ ;
+
+vfrQuestionDataFieldName [EFI_QUESTION_ID &QId, UINT32 &Mask, CHAR8 *&VarIdStr, UINT32 &LineNo] :
+ <<
+ UINT32 Idx;
+ VarIdStr = NULL; LineNo = 0;
+ >>
+ (
+ SN1:StringIdentifier << _STRCAT(&VarIdStr, SN1->getText()); LineNo = SN1->getLine(); >>
+ OpenBracket I1:Number CloseBracket <<
+ _STRCAT(&VarIdStr, "[");
+ _STRCAT(&VarIdStr, I1->getText());
+ _STRCAT(&VarIdStr, "]");
+ mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, $QId, $Mask);
+ if (mConstantOnlyInExpression) {
+ _PCATCH(VFR_RETURN_CONSTANT_ONLY, LineNo);
+ }
+ >>
+ )
+ |
+ (
+ SN2:StringIdentifier << _STRCAT (&VarIdStr, SN2->getText()); LineNo = SN2->getLine(); >>
+ (
+ "." <<
+ _STRCAT (&VarIdStr, ".");
+ if (mConstantOnlyInExpression) {
+ _PCATCH(VFR_RETURN_CONSTANT_ONLY, LineNo);
+ }
+ >>
+ SF:StringIdentifier << _STRCAT (&VarIdStr, SF->getText()); >>
+ {
+ OpenBracket I2:Number CloseBracket <<
+ Idx = _STOU32(I2->getText(), I2->getLine());
+ if (Idx > 0) {
+ //
+ // Idx == 0, [0] can be ignored.
+ // Array[0] is same to Array
+ //
+ _STRCAT(&VarIdStr, "[");
+ _STRCAT(&VarIdStr, I2->getText());
+ _STRCAT(&VarIdStr, "]");
+ }
+ >>
+ }
+ )*
+ << mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, $QId, $Mask); >>
+ )
+ ;
+
+vfrConstantValueField[UINT8 Type, EFI_IFR_TYPE_VALUE &Value, BOOLEAN &ListType] :
+ <<
+ EFI_GUID Guid;
+ BOOLEAN Negative = FALSE;
+ BOOLEAN IntDecStyle = FALSE;
+ CIfrNumeric *NumericQst = NULL;
+ if (gCurrentMinMaxData != NULL && gCurrentMinMaxData->IsNumericOpcode()) {
+ NumericQst = (CIfrNumeric *) gCurrentQuestion;
+ IntDecStyle = (NumericQst->GetNumericFlags() & EFI_IFR_DISPLAY) == 0 ? TRUE : FALSE;
+ }
+ UINT8 *Type8 = (UINT8 *) &Value;
+ UINT16 *Type16 = (UINT16 *) &Value;
+ UINT32 *Type32 = (UINT32 *) &Value;
+ UINT64 *Type64 = (UINT64 *) &Value;
+ UINT16 Index = 0;
+ ListType = FALSE;
+ >>
+ {
+ "\-" << Negative = TRUE; >>
+ }
+ N1:Number <<
+ //
+ // The value stored in bit fields is always set to UINT32 type.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $Value.u32 = _STOU32(N1->getText(), N1->getLine());
+ } else {
+ switch ($Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ $Value.u8 = _STOU8(N1->getText(), N1->getLine());
+ if (IntDecStyle) {
+ if (Negative) {
+ if ($Value.u8 > 0x80) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT8 type can't big than 0x7F, small than -0x80");
+ }
+ } else {
+ if ($Value.u8 > 0x7F) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT8 type can't big than 0x7F, small than -0x80");
+ }
+ }
+ }
+ if (Negative) {
+ $Value.u8 = ~$Value.u8 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ $Value.u16 = _STOU16(N1->getText(), N1->getLine());
+ if (IntDecStyle) {
+ if (Negative) {
+ if ($Value.u16 > 0x8000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT16 type can't big than 0x7FFF, small than -0x8000");
+ }
+ } else {
+ if ($Value.u16 > 0x7FFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT16 type can't big than 0x7FFF, small than -0x8000");
+ }
+ }
+ }
+ if (Negative) {
+ $Value.u16 = ~$Value.u16 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ $Value.u32 = _STOU32(N1->getText(), N1->getLine());
+ if (IntDecStyle) {
+ if (Negative) {
+ if ($Value.u32 > 0x80000000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT32 type can't big than 0x7FFFFFFF, small than -0x80000000");
+ }
+ } else {
+ if ($Value.u32 > 0X7FFFFFFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT32 type can't big than 0x7FFFFFFF, small than -0x80000000");
+ }
+ }
+ }
+ if (Negative) {
+ $Value.u32 = ~$Value.u32 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ $Value.u64 = _STOU64(N1->getText(), N1->getLine());
+ if (IntDecStyle) {
+ if (Negative) {
+ if ($Value.u64 > 0x8000000000000000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT64 type can't big than 0x7FFFFFFFFFFFFFFF, small than -0x8000000000000000");
+ }
+ } else {
+ if ($Value.u64 > 0x7FFFFFFFFFFFFFFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N1->getLine(), "INT64 type can't big than 0x7FFFFFFFFFFFFFFF, small than -0x8000000000000000");
+ }
+ }
+ }
+ if (Negative) {
+ $Value.u64 = ~$Value.u64 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_BOOLEAN :
+ $Value.b = _STOU8(N1->getText(), N1->getLine());
+ break;
+ case EFI_IFR_TYPE_STRING :
+ $Value.string = _STOU16(N1->getText(), N1->getLine());
+ break;
+ case EFI_IFR_TYPE_TIME :
+ case EFI_IFR_TYPE_DATE :
+ case EFI_IFR_TYPE_REF :
+ default :
+ break;
+ }
+ }
+ >>
+ | B1:True << $Value.b = TRUE; >>
+ | B2:False << $Value.b = FALSE; >>
+ | O1:One << $Value.u8 = _STOU8(O1->getText(), O1->getLine()); >>
+ | O2:Ones << $Value.u64 = _STOU64(O2->getText(), O2->getLine()); >>
+ | Z:Zero << $Value.u8 = _STOU8(Z->getText(), Z->getLine()); >>
+ | HOUR:Number ":" MINUTE:Number ":" SECOND:Number << $Value.time = _STOT(HOUR->getText(), MINUTE->getText(),SECOND->getText(), HOUR->getLine()); >>
+ | YEAR:Number "/" MONTH:Number "/" DAY:Number << $Value.date = _STOD(YEAR->getText(), MONTH->getText(), DAY->getText(), YEAR->getLine()); >>
+ | QI:Number";" FI:Number";" guidDefinition[Guid] ";" "STRING_TOKEN" "\(" DP:Number "\)"
+ << $Value.ref = _STOR(QI->getText(), FI->getText(), &Guid, DP->getText(), QI->getLine()); >>
+ | "STRING_TOKEN" "\(" S1:Number "\)" << $Value.string = _STOSID(S1->getText(), S1->getLine()); >>
+ | "\{" << ListType = TRUE; >>
+ L1:Number <<
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ Type8[Index] = _STOU8(L1->getText(), L1->getLine());
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ Type16[Index] = _STOU16(L1->getText(), L1->getLine());
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ Type32[Index] = _STOU32(L1->getText(), L1->getLine());
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ Type64[Index] = _STOU64(L1->getText(), L1->getLine());
+ break;
+ default:
+ break;
+ }
+ Index++;
+ >>
+ (
+ ","
+ L2:Number <<
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ Type8[Index] = _STOU8(L2->getText(), L2->getLine());
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ Type16[Index] = _STOU16(L2->getText(), L2->getLine());
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ Type32[Index] = _STOU32(L2->getText(), L2->getLine());
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ Type64[Index] = _STOU64(L2->getText(), L2->getLine());
+ break;
+ default:
+ break;
+ }
+ Index++;
+ >>
+ )*
+ "\}"
+ ;
+
+//*****************************************************************************
+//
+// the syntax of form definition
+//
+vfrFormDefinition :
+ << CIfrForm FObj; >>
+ F:Form << FObj.SetLineNo(F->getLine()); >>
+ FormId "=" S1:Number "," << _PCATCH(FObj.SetFormId (_STOFID(S1->getText(), S1->getLine())), S1); >>
+ Title "=" "STRING_TOKEN" "\(" S2:Number "\)" ";" << FObj.SetFormTitle (_STOSID(S2->getText(), S2->getLine())); >>
+ (
+ vfrStatementImage |
+ vfrStatementLocked |
+ vfrStatementRules |
+ vfrStatementDefault |
+ vfrStatementStat |
+ vfrStatementQuestions |
+ vfrStatementConditional |
+ vfrStatementLabel |
+ vfrStatementBanner |
+ // Just for framework vfr compatibility
+ vfrStatementInvalid |
+ vfrStatementExtension |
+ vfrStatementModal |
+ vfrStatementRefreshEvent ";"
+ )*
+ E:EndForm <<
+ {CIfrEnd EObj; EObj.SetLineNo (E->getLine()); mLastFormEndAddr = EObj.GetObjBinAddr<CHAR8>(); gAdjustOpcodeOffset = EObj.GetObjBinOffset ();}
+ >>
+ ";"
+ ;
+
+vfrFormMapDefinition :
+ <<
+ CIfrFormMap *FMapObj = NULL;
+ UINT32 FormMapMethodNumber = 0;
+ EFI_GUID Guid;
+ >>
+ F:FormMap << FMapObj = new CIfrFormMap(); FMapObj->SetLineNo(F->getLine()); >>
+ FormId "=" S1:Number "," << _PCATCH(FMapObj->SetFormId (_STOFID(S1->getText(), S1->getLine())), S1); >>
+ (
+ MapTitle "=" "STRING_TOKEN" "\(" S2:Number "\)" ";"
+ MapGuid "=" guidDefinition[Guid] ";" << FMapObj->SetFormMapMethod (_STOFID(S2->getText(), S2->getLine()), &Guid); FormMapMethodNumber ++; >>
+ )* << if (FormMapMethodNumber == 0) {_PCATCH (VFR_RETURN_INVALID_PARAMETER, F->getLine(), "No MapMethod is set for FormMap!");} delete FMapObj;>>
+ (
+ vfrStatementImage |
+ vfrStatementLocked |
+ vfrStatementRules |
+ vfrStatementDefault |
+ vfrStatementStat |
+ vfrStatementQuestions |
+ vfrStatementConditional |
+ vfrStatementLabel |
+ vfrStatementBanner |
+ vfrStatementExtension |
+ vfrStatementModal |
+ vfrStatementRefreshEvent ";"
+ )*
+ E:EndForm << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrStatementRules :
+ << CIfrRule RObj; >>
+ R:Rule << RObj.SetLineNo(R->getLine()); >>
+ S1:StringIdentifier "," <<
+ mCVfrRulesDB.RegisterRule (S1->getText());
+ RObj.SetRuleId (mCVfrRulesDB.GetRuleId(S1->getText()));
+ >>
+ vfrStatementExpression[0]
+ E:EndRule << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrStatementDefault :
+ <<
+ BOOLEAN IsExp = FALSE;
+ UINT64 ValueList[EFI_IFR_MAX_LENGTH] = {0,};
+ EFI_IFR_TYPE_VALUE *Val = (EFI_IFR_TYPE_VALUE *) ValueList;
+ CIfrDefault *DObj = NULL;
+ CIfrDefault2 *DObj2 = NULL;
+ EFI_DEFAULT_ID DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
+ CHAR8 *VarStoreName = NULL;
+ EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
+ UINT32 Size = 0;
+ EFI_GUID *VarGuid = NULL;
+ BOOLEAN ArrayType = FALSE;
+ UINT8 *Type8 = (UINT8 *) ValueList;
+ UINT16 *Type16 = (UINT16 *) ValueList;
+ UINT32 *Type32 = (UINT32 *) ValueList;
+ UINT64 *Type64 = (UINT64 *) ValueList;
+ CIfrNumeric *NumericQst = NULL;
+
+ >>
+ D:Default
+ (
+ (
+ "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE(), *Val, ArrayType] ","
+ <<
+ if (gCurrentMinMaxData != NULL && gCurrentMinMaxData->IsNumericOpcode()) {
+ //check default value is valid for Numeric Opcode
+ NumericQst = (CIfrNumeric *) gCurrentQuestion;
+ if ((NumericQst->GetNumericFlags() & EFI_IFR_DISPLAY) == 0 && !(_GET_CURRQEST_VARTINFO().mIsBitVar)) {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ if (((INT8) Val->u8 < (INT8) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
+ ((INT8) Val->u8 > (INT8) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ if (((INT16) Val->u16 < (INT16) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
+ ((INT16) Val->u16 > (INT16) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ if (((INT32) Val->u32 < (INT32) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
+ ((INT32) Val->u32 > (INT32) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ if (((INT64) Val->u64 < (INT64) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
+ ((INT64) Val->u64 > (INT64) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ //
+ // Value for question stored in bit fields is always set to UINT32 type.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ if (Val->u32 < gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), TRUE) || Val->u32 > gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), TRUE)) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
+ }
+ } else {
+ if (Val->u64 < gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE) || Val->u64 > gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE)) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
+ }
+ }
+ }
+ }
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ _PCATCH (VFR_RETURN_FATAL_ERROR, D->getLine(), "Default data type error.");
+ Size = sizeof (EFI_IFR_TYPE_VALUE);
+ } else if (ArrayType) {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ while (Type8[Size] != 0) {
+ Size++;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ while (Type16[Size] != 0) {
+ Size++;
+ }
+ Size *= sizeof (UINT16);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ while (Type32[Size] != 0) {
+ Size++;
+ }
+ Size *= sizeof (UINT32);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ while (Type64[Size] != 0) {
+ Size++;
+ }
+ Size *= sizeof (UINT64);
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ Size = sizeof (UINT32);
+ } else {
+ _PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &Size), D->getLine());
+ }
+ }
+ Size += OFFSET_OF (EFI_IFR_DEFAULT, Value);
+ DObj = new CIfrDefault ((UINT8)Size);
+ DObj->SetLineNo(D->getLine());
+ if (ArrayType) {
+ DObj->SetType (EFI_IFR_TYPE_BUFFER);
+ } else if (gIsStringOp) {
+ DObj->SetType (EFI_IFR_TYPE_STRING);
+ } else {
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ DObj->SetType (EFI_IFR_TYPE_NUM_SIZE_32);
+ } else {
+ DObj->SetType (_GET_CURRQEST_DATATYPE());
+ }
+ }
+ DObj->SetValue(*Val);
+ >>
+ | << IsExp = TRUE; DObj2 = new CIfrDefault2; DObj2->SetLineNo(D->getLine()); DObj2->SetScope (1); >>
+ vfrStatementValue "," << CIfrEnd EndObj1; EndObj1.SetLineNo(D->getLine()); >>
+ )
+ {
+ DefaultStore "=" SN:StringIdentifier "," <<
+ _PCATCH(gCVfrDefaultStore.GetDefaultId (SN->getText(), &DefaultId), SN);
+ if (DObj != NULL) {
+ DObj->SetDefaultId (DefaultId);
+ }
+
+ if (DObj2 != NULL) {
+ DObj2->SetDefaultId (DefaultId);
+ }
+ >>
+ }
+ <<
+ CheckDuplicateDefaultValue (DefaultId, D);
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ _PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), D->getLine());
+ VarGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);
+ VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
+ if ((IsExp == FALSE) && (VarStoreType == EFI_VFR_VARSTORE_BUFFER)) {
+ _PCATCH(gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
+ DefaultId,
+ _GET_CURRQEST_VARTINFO(),
+ VarStoreName,
+ VarGuid,
+ _GET_CURRQEST_DATATYPE (),
+ *Val),
+ D->getLine()
+ );
+ }
+ }
+ if (DObj != NULL) {delete DObj;}
+ if (DObj2 != NULL) {delete DObj2;}
+ >>
+ )
+ ;
+
+vfrStatementStat :
+ vfrStatementSubTitle |
+ vfrStatementStaticText |
+ vfrStatementCrossReference
+ ;
+
+vfrStatementQuestions :
+ vfrStatementBooleanType |
+ vfrStatementDate |
+ vfrStatementNumericType |
+ vfrStatementStringType |
+ vfrStatementOrderedList |
+ vfrStatementTime
+ ;
+
+vfrStatementConditional :
+ vfrStatementDisableIfStat |
+ vfrStatementSuppressIfStat | //enhance to be compatible for framework endif
+ vfrStatementGrayOutIfStat |
+ vfrStatementInconsistentIfStat //to be compatible for framework
+ ;
+
+vfrStatementConditionalNew :
+ vfrStatementDisableIfStat |
+ vfrStatementSuppressIfStatNew |
+ vfrStatementGrayOutIfStatNew |
+ vfrStatementInconsistentIfStat //to be compatible for framework
+ ;
+
+vfrStatementSuppressIfStat :
+ vfrStatementSuppressIfStatNew
+ ;
+
+vfrStatementGrayOutIfStat :
+ vfrStatementGrayOutIfStatNew
+ ;
+
+vfrStatementInvalid :
+ (
+ vfrStatementInvalidHidden |
+ vfrStatementInvalidInventory |
+ vfrStatementInvalidSaveRestoreDefaults
+ )
+ << _CRT_OP (TRUE); >>
+ ;
+
+flagsField :
+ Number
+ | InteractiveFlag
+ | ManufacturingFlag
+ | DefaultFlag
+ | ResetRequiredFlag
+ | ReconnectRequiredFlag
+ | N:NVAccessFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ N->getLine(),
+ N->getText()
+ );
+ >>
+ | L:LateCheckFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ L->getLine(),
+ L->getText()
+ );
+ >>
+ ;
+
+vfrStatementValue :
+ << CIfrValue VObj; >>
+ V:Value << VObj.SetLineNo(V->getLine()); >>
+ "=" vfrStatementExpression[0] << {CIfrEnd EndObj; EndObj.SetLineNo(V->getLine());} >>
+ ;
+
+vfrStatementRead :
+ << CIfrRead RObj; >>
+ R:Read << RObj.SetLineNo(R->getLine()); >>
+ vfrStatementExpression[0] ";"
+ ;
+
+vfrStatementWrite :
+ << CIfrWrite WObj; >>
+ W:Write << WObj.SetLineNo(W->getLine()); >>
+ vfrStatementExpression[0] ";"
+ ;
+
+vfrStatementSubTitle :
+ << CIfrSubtitle SObj; >>
+ L:Subtitle << SObj.SetLineNo(L->getLine()); >>
+ Text "=" "STRING_TOKEN" "\(" S:Number "\)" << SObj.SetPrompt (_STOSID(S->getText(), S->getLine())); >>
+ {
+ "," FLAGS "=" vfrSubtitleFlags[SObj]
+ }
+ (
+ {vfrStatementStatTagList "," }
+ E:";" << CRT_END_OP (E); >>
+ |
+ { "," vfrStatementStatTagList}
+ { "," (vfrStatementStat | vfrStatementQuestions)*}
+ D: EndSubtitle ";" << CRT_END_OP (D); >>
+ )
+ ;
+
+vfrSubtitleFlags [CIfrSubtitle & SObj] :
+ << UINT8 LFlags = 0; >>
+ subtitleFlagsField[LFlags] ( "\|" subtitleFlagsField[LFlags] )*
+ << _PCATCH(SObj.SetFlags (LFlags)); >>
+ ;
+
+subtitleFlagsField [UINT8 & Flags] :
+ N:Number << $Flags |= _STOU8(N->getText(), N->getLine()); >>
+ | "HORIZONTAL" << $Flags |= 0x01; >>
+ ;
+
+vfrStatementStaticText :
+ <<
+ UINT8 Flags = 0;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ EFI_STRING_ID TxtTwo = EFI_STRING_ID_INVALID;
+ >>
+ T:Text
+ Help "=" "STRING_TOKEN" "\(" S1:Number "\)" ","
+ Text "=" "STRING_TOKEN" "\(" S2:Number "\)"
+ {
+ "," Text "=" "STRING_TOKEN" "\(" S3:Number "\)" << TxtTwo = _STOSID(S3->getText(), S3->getLine()); >>
+ }
+ {
+ "," F:FLAGS "=" staticTextFlagsField[Flags] ( "\|" staticTextFlagsField[Flags] )*
+ "," Key "=" KN:Number
+ }
+ <<
+ if (Flags & EFI_IFR_FLAG_CALLBACK) {
+ if (TxtTwo != EFI_STRING_ID_INVALID) {
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_ACTION_WITH_TEXT_TWO,
+ S3->getLine(),
+ S3->getText()
+ );
+ }
+ CIfrAction AObj;
+ mCVfrQuestionDB.RegisterQuestion (NULL, NULL, QId);
+ AObj.SetLineNo (F->getLine());
+ AObj.SetQuestionId (QId);
+ AObj.SetPrompt (_STOSID(S2->getText(), S2->getLine()));
+ AObj.SetHelp (_STOSID(S1->getText(), S1->getLine()));
+ _PCATCH(AObj.SetFlags (Flags), F->getLine());
+ AssignQuestionKey (AObj, KN);
+ CRT_END_OP (KN);
+ } else {
+ CIfrText TObj;
+ TObj.SetLineNo (T->getLine());
+ TObj.SetHelp (_STOSID(S1->getText(), S1->getLine()));
+ TObj.SetPrompt (_STOSID(S2->getText(), S2->getLine()));
+ TObj.SetTextTwo (TxtTwo);
+ }
+ >>
+ { "," vfrStatementStatTagList }
+ ";"
+ ;
+
+staticTextFlagsField[UINT8 & HFlags] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+vfrStatementCrossReference :
+ vfrStatementGoto |
+ vfrStatementResetButton
+ ;
+
+vfrStatementGoto :
+ <<
+ UINT8 RefType = 5;
+ EFI_STRING_ID DevPath = EFI_STRING_ID_INVALID;
+ EFI_GUID FSId = {0,};
+ EFI_FORM_ID FId;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ UINT32 BitMask;
+ CIfrQuestionHeader *QHObj = NULL;
+ CIfrOpHeader *OHObj = NULL;
+ CIfrRef *R1Obj = NULL;
+ CIfrRef2 *R2Obj = NULL;
+ CIfrRef3 *R3Obj = NULL;
+ CIfrRef4 *R4Obj = NULL;
+ CIfrRef5 *R5Obj = NULL;
+ >>
+ G:Goto
+ {
+ (
+ DevicePath "=" "STRING_TOKEN" "\(" P:Number "\)" ","
+ FormSetGuid "=" guidDefinition[FSId] ","
+ FormId "=" F1:Number ","
+ Question "=" QN1:Number ","
+ <<
+ RefType = 4;
+ DevPath = _STOSID(P->getText(), P->getLine());
+ FId = _STOFID(F1->getText(), F1->getLine());
+ QId = _STOQID(QN1->getText(), QN1->getLine());
+ >>
+ )
+ |
+ (
+ FormSetGuid "=" guidDefinition[FSId] ","
+ FormId "=" F2:Number ","
+ Question "=" QN2:Number ","
+ <<
+ RefType = 3;
+ FId = _STOFID(F2->getText(), F2->getLine());
+ QId = _STOQID(QN2->getText(), QN2->getLine());
+ >>
+ )
+ |
+ (
+ FormId "=" F3:Number "," << RefType = 2; FId = _STOFID(F3->getText(), F3->getLine()); >>
+ Question "="
+ (
+ QN3:StringIdentifier "," <<
+ mCVfrQuestionDB.GetQuestionId (QN3->getText (), NULL, QId, BitMask);
+ if (QId == EFI_QUESTION_ID_INVALID) {
+ _PCATCH(VFR_RETURN_UNDEFINED, QN3);
+ }
+ >>
+ | QN4:Number "," << QId = _STOQID(QN4->getText(), QN4->getLine()); >>
+ )
+ )
+ |
+ (
+ F4:Number "," <<
+ RefType = 1;
+ FId = _STOFID(F4->getText(), F4->getLine());
+ >>
+ )
+ }
+ <<
+ switch (RefType) {
+ case 5:
+ {
+ R5Obj = new CIfrRef5;
+ QHObj = R5Obj;
+ OHObj = R5Obj;
+ R5Obj->SetLineNo(G->getLine());
+ break;
+ }
+ case 4:
+ {
+ R4Obj = new CIfrRef4;
+ QHObj = R4Obj;
+ OHObj = R4Obj;
+ R4Obj->SetLineNo(G->getLine());
+ R4Obj->SetDevicePath (DevPath);
+ R4Obj->SetFormSetId (FSId);
+ R4Obj->SetFormId (FId);
+ R4Obj->SetQuestionId (QId);
+ break;
+ }
+ case 3:
+ {
+ R3Obj = new CIfrRef3;
+ QHObj = R3Obj;
+ OHObj = R3Obj;
+ R3Obj->SetLineNo(G->getLine());
+ R3Obj->SetFormSetId (FSId);
+ R3Obj->SetFormId (FId);
+ R3Obj->SetQuestionId (QId);
+ break;
+ }
+ case 2:
+ {
+ R2Obj = new CIfrRef2;
+ QHObj = R2Obj;
+ OHObj = R2Obj;
+ R2Obj->SetLineNo(G->getLine());
+ R2Obj->SetFormId (FId);
+ R2Obj->SetQuestionId (QId);
+ break;
+ }
+ case 1:
+ {
+ R1Obj = new CIfrRef;
+ QHObj = R1Obj;
+ OHObj = R1Obj;
+ R1Obj->SetLineNo(G->getLine());
+ R1Obj->SetFormId (FId);
+ break;
+ }
+ default: break;
+ }
+ >>
+ vfrQuestionHeader[*QHObj, QUESTION_REF] <<
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ _GET_CURRQEST_VARTINFO().mVarType = EFI_IFR_TYPE_REF;
+ }
+ >>
+ { "," F:FLAGS "=" vfrGotoFlags[QHObj, F->getLine()] }
+ {
+ "," Key "=" KN:Number << AssignQuestionKey (*QHObj, KN); >>
+ }
+ {
+ E:","
+ vfrStatementQuestionOptionList << OHObj->SetScope(1); CRT_END_OP (E);>>
+ }
+ ";" << if (R1Obj != NULL) {delete R1Obj;} if (R2Obj != NULL) {delete R2Obj;} if (R3Obj != NULL) {delete R3Obj;} if (R4Obj != NULL) {delete R4Obj;} if (R5Obj != NULL) {delete R5Obj;}>>
+ ;
+
+vfrGotoFlags [CIfrQuestionHeader *QHObj, UINT32 LineNum] :
+ << UINT8 HFlags = 0; >>
+ gotoFlagsField[HFlags] ( "\|" gotoFlagsField[HFlags] )*
+ << _PCATCH(QHObj->SetFlags (HFlags), LineNum); >>
+ ;
+
+gotoFlagsField[UINT8 & HFlags] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+getStringId :
+ "STRING_TOKEN" "\("
+ IdVal:Number
+ "\)"
+ ;
+
+vfrStatementResetButton :
+ <<
+ CIfrResetButton RBObj;
+ UINT16 DefaultId;
+ >>
+ L:ResetButton << RBObj.SetLineNo(L->getLine()); >>
+ DefaultStore
+ "=" N:StringIdentifier "," <<
+ _PCATCH(gCVfrDefaultStore.GetDefaultId (N->getText(), &DefaultId), N->getLine());
+ RBObj.SetDefaultId (DefaultId);
+ >>
+ vfrStatementHeader[&RBObj] ","
+ { vfrStatementStatTagList "," }
+ E:EndResetButton << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrStatementBooleanType :
+ vfrStatementCheckBox |
+ vfrStatementAction
+ ;
+
+//*****************************************************
+// Syntax of checkbox
+//
+// Example:
+// checkbox
+// varid = MySTestData.mField1,
+// prompt = STRING_TOKEN(STR_CHECK_BOX_PROMPT),
+// help = STRING_TOKEN(STR_CHECK_BOX_HELP),
+// flags = CHECKBOX_DEFAULT | CALLBACK,
+// default value = TRUE, defaultstore = MyDefaultStore,
+// endcheckbox;
+//
+vfrStatementCheckBox :
+ <<
+ CIfrCheckBox *CBObj = NULL;
+ EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
+ CHAR8 *VarStoreName = NULL;
+ UINT32 DataTypeSize;
+ EFI_GUID *VarStoreGuid = NULL;
+ CIfrGuid *GuidObj = NULL;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;;
+ EFI_VARSTORE_INFO Info;
+ Info.mVarType = EFI_IFR_TYPE_OTHER;
+ Info.mVarTotalSize = 0;
+ Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ Info.mIsBitVar = FALSE;
+ >>
+ L:CheckBox
+ vfrQuestionBaseInfo[Info, QId] <<
+ //
+ // Create a GUID opcode to wrap the checkbox opcode, if it refer to bit varstore.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ GuidObj = new CIfrGuid(0);
+ GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
+ GuidObj->SetLineNo(L->getLine());
+ }
+ CBObj = new CIfrCheckBox;
+ CBObj->SetLineNo(L->getLine());
+ CBObj->SetQuestionId (QId);
+ CBObj->SetVarStoreInfo (&Info);
+ >>
+ vfrStatementHeader[CBObj]"," << //check data type
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ _GET_CURRQEST_VARTINFO().mVarType = EFI_IFR_TYPE_BOOLEAN;
+ }
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ //
+ // Check whether the question refers to a bit field, if yes. create a Guid to indicate the question refers to a bit field.
+ //
+ if (_GET_CURRQEST_VARTINFO ().mIsBitVar) {
+ _PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "CheckBox varid is not the valid data type");
+ if ((gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId) == EFI_VFR_VARSTORE_BUFFER_BITS) &&
+ (_GET_CURRQEST_VARSIZE() != 1)) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid only occupy 1 bit in Bit Varstore");
+ }
+ } else {
+ _PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "CheckBox varid is not the valid data type");
+ if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid doesn't support array");
+ } else if ((gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId) == EFI_VFR_VARSTORE_BUFFER) &&
+ (_GET_CURRQEST_VARSIZE() != sizeof (BOOLEAN))) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid only support BOOLEAN data type");
+ }
+ }
+ }
+ >>
+ {
+ F:FLAGS "=" vfrCheckBoxFlags[*CBObj, F->getLine()] ","
+ <<
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ _PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), VFR_RETURN_SUCCESS, L, "Failed to retrieve varstore name");
+ VarStoreGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);
+ Val.b = TRUE;
+ if (CBObj->GetFlags () & 0x01) {
+ CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_STANDARD, F);
+ _PCATCH(
+ gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
+ EFI_HII_DEFAULT_CLASS_STANDARD,
+ _GET_CURRQEST_VARTINFO(),
+ VarStoreName,
+ VarStoreGuid,
+ _GET_CURRQEST_DATATYPE (),
+ Val
+ ),
+ VFR_RETURN_SUCCESS,
+ L,
+ "No standard default storage found"
+ );
+ }
+ if (CBObj->GetFlags () & 0x02) {
+ CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_MANUFACTURING, F);
+ _PCATCH(
+ gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
+ EFI_HII_DEFAULT_CLASS_MANUFACTURING,
+ _GET_CURRQEST_VARTINFO(),
+ VarStoreName,
+ VarStoreGuid,
+ _GET_CURRQEST_DATATYPE (),
+ Val
+ ),
+ VFR_RETURN_SUCCESS,
+ L,
+ "No manufacturing default storage found"
+ );
+ }
+ }
+ >>
+ }
+ {
+ Key "=" KN:Number "," << AssignQuestionKey (*CBObj, KN); >>
+ }
+ vfrStatementQuestionOptionList
+ E:EndCheckBox << CRT_END_OP (E);
+ if (GuidObj != NULL) {
+ GuidObj->SetScope(1);
+ CRT_END_OP (E);
+ delete GuidObj;
+ }
+ if (CBObj != NULL) delete CBObj;
+ >>
+ ";"
+ ;
+
+vfrCheckBoxFlags [CIfrCheckBox & CBObj, UINT32 LineNum] :
+ <<
+ UINT8 LFlags = 0;
+ UINT8 HFlags = 0;
+ >>
+ checkboxFlagsField[LFlags, HFlags] ( "\|" checkboxFlagsField[LFlags, HFlags] )*
+ << _PCATCH(CBObj.SetFlags (HFlags, LFlags), LineNum); >>
+ ;
+
+checkboxFlagsField[UINT8 & LFlags, UINT8 & HFlags] :
+ N:Number <<
+ _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine());
+ >>
+ | D:"DEFAULT" <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, D);
+ >>
+ | M:"MANUFACTURING" <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, M);
+ >>
+ | "CHECKBOX_DEFAULT" << $LFlags |= 0x01; >>
+ | "CHECKBOX_DEFAULT_MFG" << $LFlags |= 0x02; >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+//*****************************************************
+// Syntax of action
+//
+// Example:
+// action
+// prompt = STRING_TOKEN(STR_ACTION_PROMPT),
+// help = STRING_TOKEN(STR_ACTION_HELP),
+// flags = CALLBACK,
+// config = STRING_TOKEN(STR_ACTION_CONFIG),
+// endaction;
+//
+vfrStatementAction :
+ << CIfrAction AObj; >>
+ L:Action << AObj.SetLineNo(L->getLine()); >>
+ vfrQuestionHeader[AObj] ","
+ { F:FLAGS "=" vfrActionFlags[AObj, F->getLine()] "," }
+ Config "=" "STRING_TOKEN" "\(" S:Number "\)" "," << AObj.SetQuestionConfig (_STOSID(S->getText(), S->getLine())); >>
+ vfrStatementQuestionTagList
+ E:EndAction << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrActionFlags[CIfrAction & AObj, UINT32 LineNum] :
+ << UINT8 HFlags = 0; >>
+ actionFlagsField[HFlags] ( "\|" actionFlagsField[HFlags] )*
+ << _PCATCH(AObj.SetFlags (HFlags), LineNum); >>
+ ;
+
+actionFlagsField[UINT8 & HFlags] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+vfrStatementDate :
+ <<
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ CHAR8 *VarIdStr[3] = {NULL, };
+ CIfrDate DObj;
+ EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
+ UINT8 Size = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (EFI_HII_DATE);
+ >>
+ L:Date << DObj.SetLineNo(L->getLine()); >>
+ (
+ (
+ vfrQuestionHeader[DObj, QUESTION_DATE] "," <<
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ _GET_CURRQEST_VARTINFO().mVarType = EFI_IFR_TYPE_DATE;
+ }
+ >>
+ { F:FLAGS "=" vfrDateFlags[DObj, F->getLine()] "," }
+ vfrStatementQuestionOptionList
+ )
+ |
+ (
+ Year VarId "=" D1:StringIdentifier "." D1Y:StringIdentifier ","
+ << _STRCAT(&VarIdStr[0], D1->getText()); _STRCAT(&VarIdStr[0], "."); _STRCAT(&VarIdStr[0], D1Y->getText()); >>
+ Prompt "=" "STRING_TOKEN" "\(" YP:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" YH:Number "\)" ","
+ minMaxDateStepDefault[Val.date, 0]
+
+ Month VarId "=" D2:StringIdentifier "." D2M:StringIdentifier ","
+ << _STRCAT(&VarIdStr[1], D2->getText()); _STRCAT(&VarIdStr[1], "."); _STRCAT(&VarIdStr[1], D2M->getText()); >>
+ Prompt "=" "STRING_TOKEN" "\(" MP:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" MH:Number "\)" ","
+ minMaxDateStepDefault[Val.date, 1]
+
+ Day VarId "=" D3:StringIdentifier "." D3D:StringIdentifier ","
+ << _STRCAT(&VarIdStr[2], D3->getText()); _STRCAT(&VarIdStr[2], "."); _STRCAT(&VarIdStr[2], D3D->getText()); >>
+ Prompt "=" "STRING_TOKEN" "\(" DP:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" DH:Number "\)" ","
+ minMaxDateStepDefault[Val.date, 2]
+ { G:FLAGS "=" vfrDateFlags[DObj, G->getLine()] "," }
+ <<
+ mCVfrQuestionDB.RegisterOldDateQuestion (VarIdStr[0], VarIdStr[1], VarIdStr[2], QId);
+ DObj.SetQuestionId (QId);
+ DObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, QF_DATE_STORAGE_TIME);
+ DObj.SetPrompt (_STOSID(YP->getText(), YP->getLine()));
+ DObj.SetHelp (_STOSID(YH->getText(), YH->getLine()));
+ if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; }
+ >>
+ << {CIfrDefault DefaultObj(Size, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_DATE, Val); DefaultObj.SetLineNo(L->getLine());} >>
+ )
+ ( vfrStatementInconsistentIf )*
+ )
+ E:EndDate << CRT_END_OP (E); >>
+ ";"
+ ;
+
+minMaxDateStepDefault[EFI_HII_DATE & D, UINT8 KeyValue] :
+ Minimum "=" MinN:Number ","
+ Maximum "=" MaxN:Number ","
+ { "step" "=" Number "," }
+ {
+ "default" "=" N:Number "," <<
+ switch (KeyValue) {
+ case 0:
+ D.Year = _STOU16(N->getText(), N->getLine());
+ if (D.Year < _STOU16 (MinN->getText(), MinN->getLine()) || D.Year > _STOU16 (MaxN->getText(), MaxN->getLine())) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N->getLine(), "Year default value must be between Min year and Max year.");
+ }
+ break;
+ case 1:
+ D.Month = _STOU8(N->getText(), N->getLine());
+ if (D.Month < 1 || D.Month > 12) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N->getLine(), "Month default value must be between 1 and 12.");
+ }
+ break;
+ case 2:
+ D.Day = _STOU8(N->getText(), N->getLine());
+ if (D.Day < 1 || D.Day > 31) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N->getLine(), "Day default value must be between 1 and 31.");
+ }
+ break;
+ }
+ >>
+ }
+ ;
+
+vfrDateFlags [CIfrDate & DObj, UINT32 LineNum] :
+ << UINT8 LFlags = 0; >>
+ dateFlagsField[LFlags] ( "\|" dateFlagsField[LFlags] )*
+ << _PCATCH(DObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, LFlags), LineNum); >>
+ ;
+
+dateFlagsField [UINT8 & Flags] :
+ N:Number << $Flags |= _STOU8(N->getText(), N->getLine()); >>
+ | "YEAR_SUPPRESS" << $Flags |= 0x01; >>
+ | "MONTH_SUPPRESS" << $Flags |= 0x02; >>
+ | "DAY_SUPPRESS" << $Flags |= 0x04; >>
+ | "STORAGE_NORMAL" << $Flags |= 0x00; >>
+ | "STORAGE_TIME" << $Flags |= 0x10; >>
+ | "STORAGE_WAKEUP" << $Flags |= 0x20; >>
+ ;
+
+vfrStatementNumericType :
+ vfrStatementNumeric |
+ vfrStatementOneOf
+ ;
+
+vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
+ <<
+ UINT64 MaxU8 = 0, MinU8 = 0, StepU8 = 0;
+ UINT32 MaxU4 = 0, MinU4 = 0, StepU4 = 0;
+ UINT16 MaxU2 = 0, MinU2 = 0, StepU2 = 0;
+ UINT8 MaxU1 = 0, MinU1 = 0, StepU1 = 0;
+ BOOLEAN IntDecStyle = FALSE;
+ CIfrNumeric *NObj = (CIfrNumeric *) (&MMSDObj);
+ if (((_GET_CURRQEST_VARTINFO().mIsBitVar) && (NObj->GetOpCode() == EFI_IFR_NUMERIC_OP) && ((NObj->GetNumericFlags() & EDKII_IFR_DISPLAY_BIT) == 0)) ||
+ (!(_GET_CURRQEST_VARTINFO().mIsBitVar) && (NObj->GetOpCode() == EFI_IFR_NUMERIC_OP) && ((NObj->GetNumericFlags() & EFI_IFR_DISPLAY) == 0))) {
+ IntDecStyle = TRUE;
+ }
+ BOOLEAN MinNegative = FALSE;
+ BOOLEAN MaxNegative = FALSE;
+ >>
+ Minimum "="
+ {
+ "\-" << MinNegative = TRUE; >>
+ }
+ I:Number "," <<
+ if (!IntDecStyle && MinNegative) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "\"-\" can't be used when not in int decimal type. ");
+ }
+ //
+ // Value for question stored in bit fields is always set to UINT32 type.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ MinU4 = _STOU32(I->getText(), I->getLine());
+ if (!IntDecStyle && MinU4 > (1<< _GET_CURRQEST_VARTINFO().mVarTotalSize) -1) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "BIT type minimum can't small than 0, bigger than 2^BitWidth -1");
+ }
+ } else {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ MinU8 = _STOU64(I->getText(), I->getLine());
+ if (IntDecStyle) {
+ if (MinNegative) {
+ if (MinU8 > 0x8000000000000000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT64 type minimum can't small than -0x8000000000000000, big than 0x7FFFFFFFFFFFFFFF");
+ }
+ } else {
+ if (MinU8 > 0x7FFFFFFFFFFFFFFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT64 type minimum can't small than -0x8000000000000000, big than 0x7FFFFFFFFFFFFFFF");
+ }
+ }
+ }
+ if (MinNegative) {
+ MinU8 = ~MinU8 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ MinU4 = _STOU32(I->getText(), I->getLine());
+ if (IntDecStyle) {
+ if (MinNegative) {
+ if (MinU4 > 0x80000000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT32 type minimum can't small than -0x80000000, big than 0x7FFFFFFF");
+ }
+ } else {
+ if (MinU4 > 0x7FFFFFFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT32 type minimum can't small than -0x80000000, big than 0x7FFFFFFF");
+ }
+ }
+ }
+ if (MinNegative) {
+ MinU4 = ~MinU4 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ MinU2 = _STOU16(I->getText(), I->getLine());
+ if (IntDecStyle) {
+ if (MinNegative) {
+ if (MinU2 > 0x8000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT16 type minimum can't small than -0x8000, big than 0x7FFF");
+ }
+ } else {
+ if (MinU2 > 0x7FFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT16 type minimum can't small than -0x8000, big than 0x7FFF");
+ }
+ }
+ }
+ if (MinNegative) {
+ MinU2 = ~MinU2 + 1;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ MinU1 = _STOU8(I->getText(), I->getLine());
+ if (IntDecStyle) {
+ if (MinNegative) {
+ if (MinU1 > 0x80) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT8 type minimum can't small than -0x80, big than 0x7F");
+ }
+ } else {
+ if (MinU1 > 0x7F) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT8 type minimum can't small than -0x80, big than 0x7F");
+ }
+ }
+ }
+ if (MinNegative) {
+ MinU1 = ~MinU1 + 1;
+ }
+ break;
+ }
+ }
+ >>
+ Maximum "="
+ {
+ "\-" << MaxNegative = TRUE; >>
+ }
+ A:Number "," <<
+ if (!IntDecStyle && MaxNegative) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "\"-\" can't be used when not in int decimal type. ");
+ }
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ MaxU4 = _STOU32(A->getText(), A->getLine());
+ if (!IntDecStyle && MaxU4 > (1<< _GET_CURRQEST_VARTINFO().mVarTotalSize) -1) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "BIT type maximum can't bigger than 2^BitWidth -1");
+ }
+ } else {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ MaxU8 = _STOU64(A->getText(), A->getLine());
+ if (IntDecStyle) {
+ if (MaxNegative) {
+ if (MaxU8 > 0x8000000000000000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT64 type maximum can't small than -0x8000000000000000, big than 0x7FFFFFFFFFFFFFFF");
+ }
+ } else {
+ if (MaxU8 > 0x7FFFFFFFFFFFFFFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT64 type maximum can't small than -0x8000000000000000, big than 0x7FFFFFFFFFFFFFFF");
+ }
+ }
+ }
+ if (MaxNegative) {
+ MaxU8 = ~MaxU8 + 1;
+ }
+ if (IntDecStyle) {
+ if ((INT64) MaxU8 < (INT64) MinU8) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ } else {
+ if (MaxU8 < MinU8) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ MaxU4 = _STOU32(A->getText(), A->getLine());
+ if (IntDecStyle) {
+ if (MaxNegative) {
+ if (MaxU4 > 0x80000000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT32 type maximum can't small than -0x80000000, big than 0x7FFFFFFF");
+ }
+ } else {
+ if (MaxU4 > 0x7FFFFFFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT32 type maximum can't small than -0x80000000, big than 0x7FFFFFFF");
+ }
+ }
+ }
+ if (MaxNegative) {
+ MaxU4 = ~MaxU4 + 1;
+ }
+ if (IntDecStyle) {
+ if ((INT32) MaxU4 < (INT32) MinU4) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ } else {
+ if (MaxU4 < MinU4) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ MaxU2 = _STOU16(A->getText(), A->getLine());
+ if (IntDecStyle) {
+ if (MaxNegative) {
+ if (MaxU2 > 0x8000) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT16 type maximum can't small than -0x8000, big than 0x7FFF");
+ }
+ } else {
+ if (MaxU2 > 0x7FFF) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT16 type maximum can't small than -0x8000, big than 0x7FFF");
+ }
+ }
+ }
+ if (MaxNegative) {
+ MaxU2 = ~MaxU2 + 1;
+ }
+ if (IntDecStyle) {
+ if ((INT16) MaxU2 < (INT16) MinU2) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ } else {
+ if (MaxU2 < MinU2) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ MaxU1 = _STOU8(A->getText(), A->getLine());
+ if (IntDecStyle) {
+ if (MaxNegative) {
+ if (MaxU1 > 0x80) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT8 type maximum can't small than -0x80, big than 0x7F");
+ }
+ } else {
+ if (MaxU1 > 0x7F) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT8 type maximum can't small than -0x80, big than 0x7F");
+ }
+ }
+ }
+ if (MaxNegative) {
+ MaxU1 = ~MaxU1 + 1;
+ }
+ if (IntDecStyle) {
+ if ((INT8) MaxU1 < (INT8) MinU1) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ } else {
+ if (MaxU1 < MinU1) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than Minimum");
+ }
+ }
+ break;
+ }
+ }
+ >>
+ {
+ STEP "=" S:Number ","
+ <<
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ StepU4 = _STOU32(S->getText(), S->getLine());
+ } else {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_64 : StepU8 = _STOU64(S->getText(), S->getLine()); break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 : StepU4 = _STOU32(S->getText(), S->getLine()); break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 : StepU2 = _STOU16(S->getText(), S->getLine()); break;
+ case EFI_IFR_TYPE_NUM_SIZE_8 : StepU1 = _STOU8(S->getText(), S->getLine()); break;
+ }
+ }
+ >>
+ }
+ <<
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $MMSDObj.SetMinMaxStepData (MinU4, MaxU4, StepU4);
+ } else {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_64 : $MMSDObj.SetMinMaxStepData (MinU8, MaxU8, StepU8); break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 : $MMSDObj.SetMinMaxStepData (MinU4, MaxU4, StepU4); break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 : $MMSDObj.SetMinMaxStepData (MinU2, MaxU2, StepU2); break;
+ case EFI_IFR_TYPE_NUM_SIZE_8 : $MMSDObj.SetMinMaxStepData (MinU1, MaxU1, StepU1); break;
+ }
+ }
+ >>
+ ;
+
+vfrStatementNumeric :
+ <<
+ CIfrNumeric *NObj = NULL;
+ UINT32 DataTypeSize;
+ BOOLEAN IsSupported = TRUE;
+ UINT8 ShrinkSize = 0;
+ CIfrGuid *GuidObj = NULL;
+ UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ EFI_VARSTORE_INFO Info;
+ Info.mVarType = EFI_IFR_TYPE_OTHER;
+ Info.mVarTotalSize = 0;
+ Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ Info.mIsBitVar = FALSE;
+ >>
+ L:Numeric
+ vfrQuestionBaseInfo[Info, QId] <<
+ //
+ // Create a GUID opcode to wrap the numeric opcode, if it refer to bit varstore.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ GuidObj = new CIfrGuid(0);
+ GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
+ GuidObj->SetLineNo(L->getLine());
+ }
+ NObj = new CIfrNumeric;
+ NObj->SetLineNo(L->getLine());
+ NObj->SetQuestionId (QId);
+ NObj->SetVarStoreInfo (&Info);
+ >>
+ vfrStatementHeader[NObj]","
+ <<
+ // check data type
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & (_GET_CURRQEST_VARSIZE()));
+ _PCATCH(NObj->SetFlagsForBitField (NObj->FLAGS(), LFlags), L->getLine());
+ } else {
+ _PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "Numeric varid is not the valid data type");
+ if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Numeric varid doesn't support array");
+ }
+ _PCATCH(NObj->SetFlags (NObj->FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine());
+ }
+ }
+ >>
+ { F:FLAGS "=" vfrNumericFlags[*NObj, F->getLine()] "," }
+ {
+ Key "=" KN:Number "," << AssignQuestionKey (*NObj, KN); >>
+ }
+ vfrSetMinMaxStep[*NObj] <<
+ if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ //
+ // Base on the type to know the actual used size,shrink the buffer
+ // size allocate before.
+ //
+ case EFI_IFR_TYPE_NUM_SIZE_8: ShrinkSize = 21;break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:ShrinkSize = 18;break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:ShrinkSize = 12;break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:break;
+ default:
+ IsSupported = FALSE;
+ break;
+ }
+ } else {
+ //
+ // Question stored in bit fields saved as UINT32 type, so the ShrinkSize same as EFI_IFR_TYPE_NUM_SIZE_32.
+ //
+ ShrinkSize = 12;
+ }
+ NObj->ShrinkBinSize (ShrinkSize);
+
+ if (!IsSupported) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Numeric question only support UINT8, UINT16, UINT32 and UINT64 data type.");
+ }
+ >>
+ vfrStatementQuestionOptionList
+ E:EndNumeric <<
+ CRT_END_OP (E);
+ if (GuidObj != NULL) {
+ GuidObj->SetScope(1);
+ CRT_END_OP (E);
+ delete GuidObj;
+ }
+ if (NObj != NULL) delete NObj;
+ >>
+ ";"
+ ;
+
+vfrNumericFlags [CIfrNumeric & NObj, UINT32 LineNum] :
+ <<
+ UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
+ UINT8 HFlags = 0;
+ BOOLEAN IsSetType = FALSE;
+ BOOLEAN IsDisplaySpecified = FALSE;
+ EFI_VFR_VARSTORE_TYPE VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
+ >>
+ numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] ( "\|" numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] )*
+ <<
+ //check data type flag
+ if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_EFI) {
+ if (_GET_CURRQEST_DATATYPE() != (LFlags & EFI_IFR_NUMERIC_SIZE)) {
+ _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Numeric Flag is not same to Numeric VarData type");
+ }
+ } else {
+ // update data type for name/value store
+ UINT32 DataTypeSize;
+ _GET_CURRQEST_VARTINFO().mVarType = LFlags & EFI_IFR_NUMERIC_SIZE;
+ gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize);
+ _GET_CURRQEST_VARTINFO().mVarTotalSize = DataTypeSize;
+ }
+ } else if (IsSetType){
+ _GET_CURRQEST_VARTINFO().mVarType = LFlags & EFI_IFR_NUMERIC_SIZE;
+ }
+ _PCATCH(NObj.SetFlags (HFlags, LFlags, IsDisplaySpecified), LineNum);
+ } else if ((_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) && (_GET_CURRQEST_VARTINFO().mIsBitVar)) {
+ LFlags |= (EDKII_IFR_NUMERIC_SIZE_BIT & (_GET_CURRQEST_VARSIZE()));
+ _PCATCH(NObj.SetFlagsForBitField (HFlags, LFlags, IsDisplaySpecified), LineNum);
+ }
+ >>
+ ;
+
+numericFlagsField [UINT8 & HFlags, UINT8 & LFlags, BOOLEAN & IsSetType, BOOLEAN & IsDisplaySpecified, UINT32 LineNum] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | "NUMERIC_SIZE_1" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_1;IsSetType = TRUE;
+ } else {
+ _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
+ }
+ >>
+ | "NUMERIC_SIZE_2" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_2;IsSetType = TRUE;
+ } else {
+ _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
+ }
+ >>
+ | "NUMERIC_SIZE_4" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_4; IsSetType = TRUE;
+ } else {
+ _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
+ }
+ >>
+ | "NUMERIC_SIZE_8" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_8; IsSetType = TRUE;
+ } else {
+ _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
+ }
+ >>
+ | "DISPLAY_INT_DEC" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_INT_DEC;
+ } else {
+ $LFlags = ($LFlags & ~EDKII_IFR_DISPLAY_BIT) | EDKII_IFR_DISPLAY_INT_DEC_BIT;
+ }
+ IsDisplaySpecified = TRUE;
+ >>
+ | "DISPLAY_UINT_DEC" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_UINT_DEC;
+ } else {
+ $LFlags = ($LFlags & ~EDKII_IFR_DISPLAY_BIT) | EDKII_IFR_DISPLAY_UINT_DEC_BIT;
+ }
+ IsDisplaySpecified = TRUE;
+ >>
+ | "DISPLAY_UINT_HEX" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ $LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_UINT_HEX;
+ } else {
+ $LFlags = ($LFlags & ~EDKII_IFR_DISPLAY_BIT) | EDKII_IFR_DISPLAY_UINT_HEX_BIT;
+ }
+ IsDisplaySpecified = TRUE;
+ >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+vfrStatementOneOf :
+ <<
+ CIfrOneOf *OObj = NULL;
+ UINT32 DataTypeSize;
+ BOOLEAN IsSupported = TRUE;
+ UINT8 ShrinkSize = 0;
+ CIfrGuid *GuidObj = NULL;
+ UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;;
+ EFI_VARSTORE_INFO Info;
+ Info.mVarType = EFI_IFR_TYPE_OTHER;
+ Info.mVarTotalSize = 0;
+ Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ Info.mIsBitVar = FALSE;
+ >>
+ L:OneOf
+ vfrQuestionBaseInfo[Info, QId] <<
+ //
+ // Create a GUID opcode to wrap the oneof opcode, if it refer to bit varstore.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ GuidObj = new CIfrGuid(0);
+ GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
+ GuidObj->SetLineNo(L->getLine());
+ }
+ OObj = new CIfrOneOf;
+ OObj->SetLineNo(L->getLine());
+ OObj->SetQuestionId (QId);
+ OObj->SetVarStoreInfo (&Info);
+ >>
+ vfrStatementHeader[OObj]","
+ << //check data type
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & (_GET_CURRQEST_VARSIZE()));
+ _PCATCH(OObj->SetFlagsForBitField (OObj->FLAGS(), LFlags), L->getLine());
+ } else {
+ _PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "OneOf varid is not the valid data type");
+ if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "OneOf varid doesn't support array");
+ }
+ _PCATCH(OObj->SetFlags (OObj->FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine());
+ }
+ }
+ >>
+ { F:FLAGS "=" vfrOneofFlagsField[*OObj, F->getLine()] "," }
+ {
+ vfrSetMinMaxStep[*OObj]
+ }
+ <<
+ if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ //
+ // Base on the type to know the actual used size,shrink the buffer
+ // size allocate before.
+ //
+ case EFI_IFR_TYPE_NUM_SIZE_8: ShrinkSize = 21;break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:ShrinkSize = 18;break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:ShrinkSize = 12;break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:break;
+ default:
+ IsSupported = FALSE;
+ break;
+ }
+ } else {
+ //
+ // Question stored in bit fields saved as UINT32 type, so the ShrinkSize same as EFI_IFR_TYPE_NUM_SIZE_32.
+ //
+ ShrinkSize = 12;
+ }
+ OObj->ShrinkBinSize (ShrinkSize);
+
+ if (!IsSupported) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "OneOf question only support UINT8, UINT16, UINT32 and UINT64 data type.");
+ }
+ >>
+ vfrStatementQuestionOptionList
+ E:EndOneOf <<
+ CRT_END_OP (E);
+ if (GuidObj != NULL) {
+ GuidObj->SetScope(1);
+ CRT_END_OP (E);
+ delete GuidObj;
+ }
+ if (OObj != NULL) delete OObj;
+ >>
+ ";"
+ ;
+
+vfrOneofFlagsField [CIfrOneOf & OObj, UINT32 LineNum] :
+ <<
+ UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
+ UINT8 HFlags = 0;
+ BOOLEAN IsSetType = FALSE;
+ BOOLEAN IsDisplaySpecified = FALSE;
+ EFI_VFR_VARSTORE_TYPE VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
+ >>
+ numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] ( "\|" numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] )*
+ <<
+ //check data type flag
+ if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_EFI) {
+ if (_GET_CURRQEST_DATATYPE() != (LFlags & EFI_IFR_NUMERIC_SIZE)) {
+ _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Numeric Flag is not same to Numeric VarData type");
+ }
+ } else {
+ // update data type for Name/Value store
+ UINT32 DataTypeSize;
+ _GET_CURRQEST_VARTINFO().mVarType = LFlags & EFI_IFR_NUMERIC_SIZE;
+ gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize);
+ _GET_CURRQEST_VARTINFO().mVarTotalSize = DataTypeSize;
+ }
+ } else if (IsSetType){
+ _GET_CURRQEST_VARTINFO().mVarType = LFlags & EFI_IFR_NUMERIC_SIZE;
+ }
+ _PCATCH(OObj.SetFlags (HFlags, LFlags), LineNum);
+ } else if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ _PCATCH(OObj.SetFlagsForBitField (HFlags, LFlags), LineNum);
+ }
+ >>
+ ;
+
+vfrStatementStringType :
+ vfrStatementString |
+ vfrStatementPassword
+ ;
+
+vfrStatementString :
+ <<
+ CIfrString SObj;
+ UINT32 VarArraySize;
+ UINT8 StringMinSize;
+ UINT8 StringMaxSize;
+ >>
+ L:String << SObj.SetLineNo(L->getLine()); gIsStringOp = TRUE;>>
+ vfrQuestionHeader[SObj] ","
+ { F:FLAGS "=" vfrStringFlagsField[SObj, F->getLine()] "," }
+ {
+ Key "=" KN:Number "," << AssignQuestionKey (SObj, KN); >>
+ }
+ MinSize "=" MIN:Number "," <<
+ VarArraySize = _GET_CURRQEST_ARRAY_SIZE();
+ StringMinSize = _STOU8(MIN->getText(), MIN->getLine());
+ if (_STOU64(MIN->getText(), MIN->getLine()) > StringMinSize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MIN->getLine(), "String MinSize takes only one byte, which can't be larger than 0xFF.");
+ } else if (VarArraySize != 0 && StringMinSize > VarArraySize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MIN->getLine(), "String MinSize can't be larger than the max number of elements in string array.");
+ }
+ SObj.SetMinSize (StringMinSize);
+ >>
+ MaxSize "=" MAX:Number "," <<
+ StringMaxSize = _STOU8(MAX->getText(), MAX->getLine());
+ if (_STOU64(MAX->getText(), MAX->getLine()) > StringMaxSize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MAX->getLine(), "String MaxSize takes only one byte, which can't be larger than 0xFF.");
+ } else if (VarArraySize != 0 && StringMaxSize > VarArraySize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MAX->getLine(), "String MaxSize can't be larger than the max number of elements in string array.");
+ } else if (StringMaxSize < StringMinSize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MAX->getLine(), "String MaxSize can't be less than String MinSize.");
+ }
+ SObj.SetMaxSize (StringMaxSize);
+ >>
+ vfrStatementQuestionOptionList
+ E:EndString << CRT_END_OP (E); gIsStringOp = FALSE;>>
+ ";"
+ ;
+
+vfrStringFlagsField [CIfrString & SObj, UINT32 LineNum] :
+ <<
+ UINT8 LFlags = 0;
+ UINT8 HFlags = 0;
+ >>
+ stringFlagsField[HFlags, LFlags] ( "\|" stringFlagsField[HFlags, LFlags] )*
+ << _PCATCH(SObj.SetFlags (HFlags, LFlags), LineNum); >>
+ ;
+
+stringFlagsField [UINT8 & HFlags, UINT8 & LFlags] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | "MULTI_LINE" << $LFlags = 0x01; >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+vfrStatementPassword :
+ <<
+ CIfrPassword PObj;
+ UINT32 VarArraySize;
+ UINT16 PasswordMinSize;
+ UINT16 PasswordMaxSize;
+ >>
+ L:Password << PObj.SetLineNo(L->getLine()); >>
+ vfrQuestionHeader[PObj] ","
+ { F:FLAGS "=" vfrPasswordFlagsField[PObj, F->getLine()] "," }
+ {
+ Key "=" KN:Number "," << AssignQuestionKey (PObj, KN); >>
+ }
+ MinSize "=" MIN:Number "," <<
+ VarArraySize = _GET_CURRQEST_ARRAY_SIZE();
+ PasswordMinSize = _STOU16(MIN->getText(), MIN->getLine());
+ if (_STOU64(MIN->getText(), MIN->getLine()) > PasswordMinSize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MIN->getLine(), "Password MinSize takes only two byte, which can't be larger than 0xFFFF.");
+ } else if (VarArraySize != 0 && PasswordMinSize > VarArraySize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MIN->getLine(), "Password MinSize can't be larger than the max number of elements in password array.");
+ }
+ PObj.SetMinSize (PasswordMinSize);
+ >>
+ MaxSize "=" MAX:Number "," <<
+ PasswordMaxSize = _STOU16(MAX->getText(), MAX->getLine());
+ if (_STOU64(MAX->getText(), MAX->getLine()) > PasswordMaxSize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MAX->getLine(), "Password MaxSize takes only two byte, which can't be larger than 0xFFFF.");
+ } else if (VarArraySize != 0 && PasswordMaxSize > VarArraySize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MAX->getLine(), "Password MaxSize can't be larger than the max number of elements in password array.");
+ } else if (PasswordMaxSize < PasswordMinSize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, MAX->getLine(), "Password MaxSize can't be less than Password MinSize.");
+ }
+ PObj.SetMaxSize (PasswordMaxSize);
+ >>
+ { Encoding "=" Number "," }
+ vfrStatementQuestionOptionList
+ E:EndPassword << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrPasswordFlagsField [CIfrPassword & PObj, UINT32 LineNum] :
+ << UINT8 HFlags = 0; >>
+ passwordFlagsField[HFlags] ( "\|" passwordFlagsField[HFlags] )*
+ << _PCATCH(PObj.SetFlags(HFlags), LineNum); >>
+ ;
+
+passwordFlagsField [UINT8 & HFlags] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+vfrStatementOrderedList :
+ <<
+ CIfrOrderedList OLObj;
+ UINT32 VarArraySize;
+ >>
+ L:OrderedList << OLObj.SetLineNo(L->getLine()); gIsOrderedList = TRUE;>>
+ vfrQuestionHeader[OLObj] ","
+ <<
+ VarArraySize = _GET_CURRQEST_ARRAY_SIZE();
+ OLObj.SetMaxContainers ((UINT8) (VarArraySize > 0xFF ? 0xFF : VarArraySize));
+ >>
+ {
+ MaxContainers "=" M:Number "," <<
+ if (_STOU64(M->getText(), M->getLine()) > _STOU8(M->getText(), M->getLine())) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, M->getLine(), "OrderedList MaxContainers takes only one byte, which can't be larger than 0xFF.");
+ } else if (VarArraySize != 0 && _STOU8(M->getText(), M->getLine()) > VarArraySize) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, M->getLine(), "OrderedList MaxContainers can't be larger than the max number of elements in array.");
+ }
+ OLObj.SetMaxContainers (_STOU8(M->getText(), M->getLine()));
+ >>
+ }
+ { F:FLAGS "=" vfrOrderedListFlags[OLObj, F->getLine()] {","}}
+ vfrStatementQuestionOptionList
+ E:EndList << CRT_END_OP (E); gIsOrderedList = FALSE;>>
+ ";"
+ ;
+
+vfrOrderedListFlags [CIfrOrderedList & OLObj, UINT32 LineNum] :
+ <<
+ UINT8 HFlags = 0;
+ UINT8 LFlags = 0;
+ >>
+ orderedlistFlagsField[HFlags, LFlags] ( "\|" orderedlistFlagsField[HFlags, LFlags] )*
+ << _PCATCH(OLObj.SetFlags (HFlags, LFlags), LineNum); >>
+ ;
+
+orderedlistFlagsField [UINT8 & HFlags, UINT8 & LFlags] :
+ N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
+ | "UNIQUE" << $LFlags |= 0x01; >>
+ | "NOEMPTY" << $LFlags |= 0x02; >>
+ | questionheaderFlagsField[HFlags]
+ ;
+
+vfrStatementTime :
+ <<
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ CHAR8 *VarIdStr[3] = {NULL, };
+ CIfrTime TObj;
+ EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
+ UINT8 Size = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (EFI_HII_TIME);
+ >>
+ L:Time << TObj.SetLineNo(L->getLine()); >>
+ (
+ (
+ vfrQuestionHeader[TObj, QUESTION_TIME] "," <<
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ _GET_CURRQEST_VARTINFO().mVarType = EFI_IFR_TYPE_TIME;
+ }
+ >>
+ { F:FLAGS "=" vfrTimeFlags[TObj, F->getLine()] "," }
+ vfrStatementQuestionOptionList
+ )
+ |
+ (
+ Hour VarId "=" T1:StringIdentifier "." T1H:StringIdentifier ","
+ << _STRCAT(&VarIdStr[0], T1->getText()); _STRCAT(&VarIdStr[0], "."); _STRCAT(&VarIdStr[0], T1H->getText()); >>
+ Prompt "=" "STRING_TOKEN" "\(" HP:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" HH:Number "\)" ","
+ minMaxTimeStepDefault[Val.time, 0]
+
+ Minute VarId "=" T2:StringIdentifier "." T2M:StringIdentifier ","
+ << _STRCAT(&VarIdStr[1], T2->getText()); _STRCAT(&VarIdStr[1], "."); _STRCAT(&VarIdStr[1], T2M->getText()); >>
+ Prompt "=" "STRING_TOKEN" "\(" MP:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" MH:Number "\)" ","
+ minMaxTimeStepDefault[Val.time, 1]
+
+ Second VarId "=" T3:StringIdentifier "." T3S:StringIdentifier ","
+ << _STRCAT(&VarIdStr[2], T3->getText()); _STRCAT(&VarIdStr[2], "."); _STRCAT(&VarIdStr[2], T3S->getText()); >>
+ Prompt "=" "STRING_TOKEN" "\(" SP:Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" SH:Number "\)" ","
+ minMaxTimeStepDefault[Val.time, 2]
+ { G:FLAGS "=" vfrTimeFlags[TObj, G->getLine()] "," }
+ <<
+ mCVfrQuestionDB.RegisterOldTimeQuestion (VarIdStr[0], VarIdStr[1], VarIdStr[2], QId);
+ TObj.SetQuestionId (QId);
+ TObj.SetFlags (EFI_IFR_QUESTION_FLAG_DEFAULT, QF_TIME_STORAGE_TIME);
+ TObj.SetPrompt (_STOSID(HP->getText(), HP->getLine()));
+ TObj.SetHelp (_STOSID(HH->getText(), HH->getLine()));
+ if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; }
+ >>
+ << {CIfrDefault DefaultObj(Size, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_TIME, Val); DefaultObj.SetLineNo(L->getLine());} >>
+ )
+ ( vfrStatementInconsistentIf )*
+ )
+ E:EndTime << CRT_END_OP (E); >>
+ ";"
+ ;
+
+minMaxTimeStepDefault[EFI_HII_TIME & T, UINT8 KeyValue] :
+ Minimum "=" Number ","
+ Maximum "=" Number ","
+ { "step" "=" Number "," }
+ {
+ "default" "=" N:Number "," <<
+ switch (KeyValue) {
+ case 0:
+ T.Hour = _STOU8(N->getText(), N->getLine());
+ if (T.Hour > 23) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N->getLine(), "Hour default value must be between 0 and 23.");
+ }
+ break;
+ case 1:
+ T.Minute = _STOU8(N->getText(), N->getLine());
+ if (T.Minute > 59) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N->getLine(), "Minute default value must be between 0 and 59.");
+ }
+ break;
+ case 2:
+ T.Second = _STOU8(N->getText(), N->getLine());
+ if (T.Second > 59) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, N->getLine(), "Second default value must be between 0 and 59.");
+ }
+ break;
+ }
+ >>
+ }
+ ;
+
+vfrTimeFlags [CIfrTime & TObj, UINT32 LineNum] :
+ << UINT8 LFlags = 0; >>
+ timeFlagsField[LFlags] ( "\|" timeFlagsField[LFlags] )*
+ << _PCATCH(TObj.SetFlags(EFI_IFR_QUESTION_FLAG_DEFAULT, LFlags), LineNum); >>
+ ;
+
+timeFlagsField [UINT8 & Flags] :
+ N:Number << $Flags |= _STOU8(N->getText(), N->getLine()); >>
+ | "HOUR_SUPPRESS" << $Flags |= 0x01; >>
+ | "MINUTE_SUPPRESS" << $Flags |= 0x02; >>
+ | "SECOND_SUPPRESS" << $Flags |= 0x04; >>
+ | "STORAGE_NORMAL" << $Flags |= 0x00; >>
+ | "STORAGE_TIME" << $Flags |= 0x10; >>
+ | "STORAGE_WAKEUP" << $Flags |= 0x20; >>
+ ;
+
+vfrStatementQuestionTag :
+ vfrStatementStatTag "," |
+ vfrStatementInconsistentIf |
+ vfrStatementNoSubmitIf |
+ vfrStatementDisableIfQuest |
+ vfrStatementRefresh |
+ vfrStatementVarstoreDevice |
+ vfrStatementExtension |
+ vfrStatementRefreshEvent "," |
+ vfrStatementWarningIf
+ ;
+
+vfrStatementQuestionTagList :
+ ( vfrStatementQuestionTag )*
+ ;
+
+vfrStatementQuestionOptionTag :
+ vfrStatementSuppressIfQuest |
+ vfrStatementGrayOutIfQuest |
+ vfrStatementValue |
+ vfrStatementDefault |
+ vfrStatementRead |
+ vfrStatementWrite |
+ vfrStatementOptions
+ ;
+
+vfrStatementQuestionOptionList :
+ (
+ vfrStatementQuestionTag |
+ vfrStatementQuestionOptionTag
+ )*
+ ;
+
+vfrStatementStatList :
+ vfrStatementStat |
+ vfrStatementQuestions |
+ vfrStatementConditionalNew |
+ vfrStatementLabel |
+ vfrStatementExtension |
+ // Just for framework vfr compatibility
+ vfrStatementInvalid
+ ;
+
+vfrStatementStatListOld :
+ vfrStatementStat |
+ vfrStatementQuestions |
+ vfrStatementLabel |
+ // Just for framework vfr compatibility
+ vfrStatementInvalid
+ ;
+
+vfrStatementDisableIfStat :
+ <<
+ CIfrDisableIf DIObj;
+ >>
+ L:DisableIf << DIObj.SetLineNo(L->getLine()); >>
+ vfrStatementExpression[0] ";"
+ ( vfrStatementStatList )*
+ E:EndIf << CRT_END_OP (E); >>
+ ";"
+ ;
+
+vfrStatementInconsistentIfStat :
+ << CIfrInconsistentIf IIObj; >>
+ L:InconsistentIf <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, L);
+ IIObj.SetLineNo(L->getLine());
+ >>
+ Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," << IIObj.SetError (_STOSID(S->getText(), S->getLine())); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ E:EndIf << CRT_END_OP (E); >>
+ ";"
+ ;
+
+//
+// Compatible for framework vfr file
+//
+vfrStatementgrayoutIfSuppressIf:
+ << CIfrSuppressIf SIObj; >>
+ L:SuppressIf << SIObj.SetLineNo(L->getLine()); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ ";"
+ ;
+
+vfrStatementsuppressIfGrayOutIf:
+ << CIfrGrayOutIf GOIObj; >>
+ L:GrayOutIf << GOIObj.SetLineNo(L->getLine()); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ ";"
+ ;
+
+vfrStatementSuppressIfStatNew :
+ << CIfrSuppressIf SIObj;>>
+ L:SuppressIf << SIObj.SetLineNo(L->getLine()); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ ";"
+ ( vfrStatementStatList )*
+ E: EndIf ";" << CRT_END_OP (E); >>
+ ;
+
+vfrStatementGrayOutIfStatNew :
+ << CIfrGrayOutIf GOIObj;>>
+ L:GrayOutIf << GOIObj.SetLineNo(L->getLine()); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ ";"
+ ( vfrStatementStatList )*
+ E: EndIf ";" << CRT_END_OP (E); >>
+ ;
+
+vfrImageTag :
+ << CIfrImage IObj; >>
+ L:Image "=" "IMAGE_TOKEN" "\(" S1:Number "\)" << IObj.SetImageId (_STOSID(S1->getText(), S1->getLine())); IObj.SetLineNo(L->getLine()); >>
+ ;
+
+vfrLockedTag :
+ << CIfrLocked LObj; >>
+ L:Locked << LObj.SetLineNo(L->getLine()); >>
+ ;
+
+vfrModalTag :
+ << CIfrModal MObj; >>
+ L:Modal << MObj.SetLineNo(L->getLine()); >>
+ ;
+
+vfrStatementStatTag :
+ vfrImageTag |
+ vfrLockedTag
+ ;
+
+vfrStatementStatTagList :
+ vfrStatementStatTag ( "," vfrStatementStatTag )*
+ ;
+
+vfrStatementImage :
+ vfrImageTag
+ ";"
+ ;
+
+vfrStatementModal :
+ vfrModalTag
+ ";"
+ ;
+
+vfrStatementLocked :
+ vfrLockedTag
+ ";"
+ ;
+
+vfrStatementInconsistentIf :
+ << CIfrInconsistentIf IIObj; >>
+ L:InconsistentIf << IIObj.SetLineNo(L->getLine()); >>
+ Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," << IIObj.SetError (_STOSID(S->getText(), S->getLine())); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ E:EndIf {";"} << CRT_END_OP (E); >>
+ ;
+
+vfrStatementNoSubmitIf :
+ << CIfrNoSubmitIf NSIObj; >>
+ L:NoSubmitIf << NSIObj.SetLineNo(L->getLine()); >>
+ Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," << NSIObj.SetError (_STOSID(S->getText(), S->getLine())); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ E:EndIf {";"} << CRT_END_OP (E); >>
+ ;
+
+vfrStatementWarningIf :
+ << CIfrWarningIf WIObj; >>
+ L:WarningIf << WIObj.SetLineNo(L->getLine()); >>
+ Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" "," << WIObj.SetWarning (_STOSID(S->getText(), S->getLine())); >>
+ {Timeout "=" T:Number "," << WIObj.SetTimeOut (_STOU8(T->getText(), T->getLine())); >>}
+ vfrStatementExpression[0]
+ E:EndIf {";"} << CRT_END_OP (E); >>
+ ;
+
+vfrStatementDisableIfQuest :
+ <<
+ CIfrDisableIf DIObj;
+ >>
+ L:DisableIf << DIObj.SetLineNo(L->getLine()); >>
+ vfrStatementExpression[0] ";"
+ vfrStatementQuestionOptionList
+ E:EndIf {";"} << CRT_END_OP (E); >>
+ ;
+
+vfrStatementRefresh :
+ << CIfrRefresh RObj; >>
+ L:Refresh << RObj.SetLineNo(L->getLine()); >>
+ Interval "=" I:Number << RObj.SetRefreshInterval (_STOU8(I->getText(), I->getLine())); >>
+ ;
+
+vfrStatementRefreshEvent :
+ <<
+ CIfrRefreshId RiObj;
+ EFI_GUID Guid;
+ >>
+ L:RefreshGuid << RiObj.SetLineNo(L->getLine()); >>
+ "=" guidDefinition[Guid] << RiObj.SetRefreshEventGroutId (&Guid); >>
+ ;
+
+vfrStatementVarstoreDevice :
+ << CIfrVarStoreDevice VDObj; >>
+ L:VarstoreDevice << VDObj.SetLineNo(L->getLine()); >>
+ "=" "STRING_TOKEN" "\(" S:Number "\)" "," << VDObj.SetDevicePath (_STOSID(S->getText(), S->getLine())); >>
+ ;
+
+vfrStatementSuppressIfQuest :
+ << CIfrSuppressIf SIObj; >>
+ L:SuppressIf << SIObj.SetLineNo(L->getLine()); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0] ";"
+ vfrStatementQuestionOptionList
+ E:EndIf {";"} << CRT_END_OP (E); >>
+ ;
+
+vfrStatementGrayOutIfQuest :
+ << CIfrGrayOutIf GOIObj; >>
+ L:GrayOutIf << GOIObj.SetLineNo(L->getLine()); >>
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0] ";"
+ vfrStatementQuestionOptionList
+ E:EndIf {";"} << CRT_END_OP (E); >>
+ ;
+
+vfrStatementOptions :
+ vfrStatementOneOfOption
+ ;
+
+vfrStatementOneOfOption :
+ <<
+ UINT8 ValueList[EFI_IFR_MAX_LENGTH] = {0,};
+ EFI_IFR_TYPE_VALUE *Val = (EFI_IFR_TYPE_VALUE *) ValueList;
+ CHAR8 *VarStoreName = NULL;
+ UINT32 Size = 0;
+ BOOLEAN TypeError = FALSE;
+ EFI_VFR_RETURN_CODE ReturnCode = VFR_RETURN_SUCCESS;
+ EFI_GUID *VarStoreGuid = NULL;
+ BOOLEAN ArrayType = FALSE;
+ CIfrOneOfOption *OOOObj;
+ UINT8 *Type8 = (UINT8 *) ValueList;
+ UINT16 *Type16 = (UINT16 *) ValueList;
+ UINT32 *Type32 = (UINT32 *) ValueList;
+ UINT64 *Type64 = (UINT64 *) ValueList;
+ >>
+ L:Option <<
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ _PCATCH (VFR_RETURN_FATAL_ERROR, L->getLine(), "Get data type error.");
+ }
+
+ >>
+ Text "=" "STRING_TOKEN" "\(" S:Number "\)" ","
+ Value "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE(), *Val, ArrayType] ","
+ <<
+ if (gCurrentMinMaxData != NULL) {
+ //set min/max value for oneof opcode
+ UINT64 Step = gCurrentMinMaxData->GetStepData(_GET_CURRQEST_DATATYPE(), _GET_CURRQEST_VARTINFO().mIsBitVar);
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ gCurrentMinMaxData->SetMinMaxStepData(Val->u32, Val->u32, (UINT32) Step);
+ } else {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ gCurrentMinMaxData->SetMinMaxStepData(Val->u64, Val->u64, Step);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ gCurrentMinMaxData->SetMinMaxStepData(Val->u32, Val->u32, (UINT32) Step);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ gCurrentMinMaxData->SetMinMaxStepData(Val->u16, Val->u16, (UINT16) Step);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ gCurrentMinMaxData->SetMinMaxStepData(Val->u8, Val->u8, (UINT8) Step);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
+ Size = sizeof (EFI_IFR_TYPE_VALUE);
+ } else if (ArrayType) {
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ while (Type8[Size] != 0) {
+ Size++;
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ while (Type16[Size] != 0) {
+ Size++;
+ }
+ Size *= sizeof (UINT16);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ while (Type32[Size] != 0) {
+ Size++;
+ }
+ Size *= sizeof (UINT32);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ while (Type64[Size] != 0) {
+ Size++;
+ }
+ Size *= sizeof (UINT64);
+ break;
+ default:
+ break;
+ }
+ } else {
+ //
+ // For the oneof stored in bit fields, set the option type as UINT32.
+ //
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ Size = sizeof (UINT32);
+ } else {
+ ReturnCode = gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &Size);
+ }
+ }
+ if (ReturnCode != VFR_RETURN_SUCCESS) {
+ _PCATCH (ReturnCode, L->getLine());
+ }
+
+ Size += OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
+ OOOObj = new CIfrOneOfOption((UINT8)Size);
+ OOOObj->SetLineNo(L->getLine());
+ OOOObj->SetOption (_STOSID(S->getText(), S->getLine()));
+ if (ArrayType) {
+ OOOObj->SetType (EFI_IFR_TYPE_BUFFER);
+ } else {
+ if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
+ OOOObj->SetType ( EFI_IFR_TYPE_NUM_SIZE_32);
+ } else {
+ OOOObj->SetType (_GET_CURRQEST_DATATYPE());
+ }
+ }
+ OOOObj->SetValue (*Val);
+ >>
+ F:FLAGS "=" vfrOneOfOptionFlags[*OOOObj, F->getLine()]
+ <<
+ //
+ // Array type only for default type OneOfOption.
+ //
+ if ((OOOObj->GetFlags () & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) == 0 && ArrayType) {
+ _PCATCH (VFR_RETURN_FATAL_ERROR, L->getLine(), "Default keyword should with array value type!");
+ }
+
+ //
+ // Clear the default flag if the option not use array value but has default flag.
+ //
+ if ((OOOObj->GetFlags () & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0 && !ArrayType && gIsOrderedList) {
+ OOOObj->SetFlags(OOOObj->GetFlags () & ~(EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));
+ }
+
+ if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
+ _PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), L->getLine());
+ VarStoreGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);
+ if (OOOObj->GetFlags () & EFI_IFR_OPTION_DEFAULT) {
+ CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_STANDARD, F);
+ _PCATCH(gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
+ EFI_HII_DEFAULT_CLASS_STANDARD,
+ _GET_CURRQEST_VARTINFO(),
+ VarStoreName,
+ VarStoreGuid,
+ _GET_CURRQEST_DATATYPE (),
+ *Val
+ ), L->getLine());
+ }
+ if (OOOObj->GetFlags () & EFI_IFR_OPTION_DEFAULT_MFG) {
+ CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_MANUFACTURING, F);
+ _PCATCH(gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
+ EFI_HII_DEFAULT_CLASS_MANUFACTURING,
+ _GET_CURRQEST_VARTINFO(),
+ VarStoreName,
+ VarStoreGuid,
+ _GET_CURRQEST_DATATYPE (),
+ *Val
+ ), L->getLine());
+ }
+ }
+ >>
+ {
+ "," Key "=" KN:Number <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, KN);
+ //
+ // Guid Option Key
+ //
+ CIfrOptionKey IfrOptionKey (
+ gCurrentQuestion->QUESTION_ID(),
+ *Val,
+ _STOQID(KN->getText(), KN->getLine())
+ );
+ SET_LINE_INFO (IfrOptionKey, KN);
+ >>
+ }
+ (
+ T:"," vfrImageTag << OOOObj->SetScope (1); CRT_END_OP (T); >>
+ )*
+ ";" << if (OOOObj != NULL) {delete OOOObj;} >>
+ ;
+
+vfrOneOfOptionFlags [CIfrOneOfOption & OOOObj, UINT32 LineNum] :
+ <<
+ UINT8 LFlags = _GET_CURRQEST_DATATYPE();
+ UINT8 HFlags = 0;
+ >>
+ oneofoptionFlagsField[HFlags, LFlags] ( "\|" oneofoptionFlagsField[HFlags, LFlags] )*
+ << _PCATCH(gCurrentQuestion->SetFlags(HFlags), LineNum); >>
+ << _PCATCH(OOOObj.SetFlags(LFlags), LineNum); >>
+ ;
+
+oneofoptionFlagsField [UINT8 & HFlags, UINT8 & LFlags] :
+ N:Number << $LFlags |= _STOU8(N->getText(), N->getLine()); >>
+ | "OPTION_DEFAULT" << $LFlags |= 0x10; >>
+ | "OPTION_DEFAULT_MFG" << $LFlags |= 0x20; >>
+ | InteractiveFlag << $HFlags |= 0x04; >>
+ | ResetRequiredFlag << $HFlags |= 0x10; >>
+ | RestStyleFlag << $HFlags |= 0x20; >>
+ | ReconnectRequiredFlag << $HFlags |= 0x40; >>
+ | ManufacturingFlag << $LFlags |= 0x20; >>
+ | DefaultFlag << $LFlags |= 0x10; >>
+ | A:NVAccessFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ A->getLine(),
+ A->getText()
+ );
+ >>
+ | L:LateCheckFlag <<
+ gCVfrErrorHandle.HandleWarning (
+ VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE,
+ L->getLine(),
+ L->getText()
+ );
+ >>
+ ;
+
+vfrStatementLabel :
+ L:Label
+ N:Number <<
+ {
+ CIfrLabel LObj2;
+ LObj2.SetLineNo(L->getLine());
+ LObj2.SetNumber (_STOU16(N->getText(), N->getLine()));
+ }
+ >>
+ ";"
+ ;
+
+vfrStatementBanner :
+ << CIfrBanner BObj; >>
+ B:Banner { "," } << BObj.SetLineNo(B->getLine()); >>
+ Title "=" "STRING_TOKEN" "\(" S:Number "\)" "," << BObj.SetTitle (_STOSID(S->getText(), S->getLine())); >>
+ (
+ (
+ Line L:Number "," << BObj.SetLine (_STOU16(L->getText(), L->getLine())); >>
+ Align
+ (
+ Left << BObj.SetAlign (0); >>
+ | Center << BObj.SetAlign (1); >>
+ | Right << BObj.SetAlign (2); >>
+ ) ";"
+ )
+ |
+ (
+ Timeout "=" T:Number ";" << {CIfrTimeout TObj(_STOU16(T->getText(), T->getLine()));} >>
+ )
+ )
+ ;
+
+//******************************************************************************
+//
+// keep some syntax for compatibility but not generate any IFR object
+//
+vfrStatementInvalidHidden :
+ L:Hidden <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, L);
+ >>
+ Value "=" Number ","
+ Key "=" Number ";"
+ ;
+
+vfrStatementInvalidInconsistentIf :
+ InconsistentIf
+ Prompt "=" "STRING_TOKEN" "\(" S:Number "\)" ","
+ { FLAGS "=" flagsField ( "\|" flagsField )* "," }
+ vfrStatementExpression[0]
+ EndIf
+ ";"
+ ;
+
+vfrStatementInvalidInventory :
+ L:Inventory <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, L);
+ >>
+ Help "=" "STRING_TOKEN" "\(" Number "\)" ","
+ Text "=" "STRING_TOKEN" "\(" Number "\)" ","
+ {
+ Text "=" "STRING_TOKEN" "\(" Number "\)"
+ }
+ ";"
+ ;
+
+vfrStatementInvalidSaveRestoreDefaults :
+ (
+ L:Save <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, L);
+ >>
+ |
+ K:Restore <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, K);
+ >>
+ )
+ Defaults ","
+ FormId "=" Number ","
+ Prompt "=" "STRING_TOKEN" "\(" Number "\)" ","
+ Help "=" "STRING_TOKEN" "\(" Number "\)"
+ { "," FLAGS "=" flagsField ( "\|" flagsField )* }
+ { "," Key "=" Number }
+ ";"
+ ;
+
+//******************************************************************************
+//
+// The syntax of expression
+//
+#token Dup("dup") "dup"
+#token VarEqVal("vareqval") "vareqval"
+#token Var("var") "var"
+#token IdEqVal("ideqval") "ideqval"
+#token IdEqId("ideqid") "ideqid"
+#token IdEqValList("ideqvallist") "ideqvallist"
+#token QuestionRef("questionref") "questionref"
+#token RuleRef("ruleref") "ruleref"
+#token StringRef("stringref") "stringref"
+#token PushThis("pushthis") "pushthis"
+#token Security("security") "security"
+#token Get("get") "get"
+#token True("TRUE") "TRUE"
+#token False("FALSE") "FALSE"
+#token One("ONE") "ONE"
+#token Ones("ONES") "ONES"
+#token Zero("ZERO") "ZERO"
+#token Undefined("UNDEFINED") "UNDEFINED"
+#token Version("VERSION") "VERSION"
+#token Length("length") "length"
+#token AND("AND") "AND"
+#token OR("OR") "OR"
+#token NOT("NOT") "NOT"
+#token Set("set") "set"
+#token BitWiseNot("~") "\~"
+#token BoolVal("boolval") "boolval"
+#token StringVal("stringval") "stringval"
+#token UnIntVal("unintval") "unintval"
+#token ToUpper("toupper") "toupper"
+#token ToLower("tolower") "tolower"
+#token Match("match") "match"
+#token Match2("match2") "match2"
+#token Catenate("catenate") "catenate"
+#token QuestionRefVal("questionrefval") "questionrefval"
+#token StringRefVal("stringrefval") "stringrefval"
+#token Map("map") "map"
+#token RefreshGuid("refreshguid") "refreshguid"
+
+//
+// Root expression extension function called by other function.
+//
+vfrStatementExpression [UINT32 RootLevel, UINT32 ExpOpCount = 0] :
+ <<
+ if ($RootLevel == 0) {
+ mCIfrOpHdrIndex ++;
+ if (mCIfrOpHdrIndex >= MAX_IFR_EXPRESSION_DEPTH) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, 0, "The depth of expression exceeds the max supported level 8!");
+ }
+ _INIT_OPHDR_COND ();
+ }
+ >>
+ andTerm[$RootLevel, $ExpOpCount]
+ (
+ L:OR andTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrOr OObj(L->getLine()); >>
+ )*
+ <<
+ //
+ // Extend OpCode Scope only for the root expression.
+ //
+ if ($ExpOpCount > 1 && $RootLevel == 0) {
+ if (_SET_SAVED_OPHDR_SCOPE()) {
+ CIfrEnd EObj;
+ if (mCIfrOpHdrLineNo[mCIfrOpHdrIndex] != 0) {
+ EObj.SetLineNo (mCIfrOpHdrLineNo[mCIfrOpHdrIndex]);
+ }
+ }
+ }
+
+ if ($RootLevel == 0) {
+ _CLEAR_SAVED_OPHDR ();
+ mCIfrOpHdrIndex --;
+ }
+ >>
+ ;
+
+//
+// Add new sub function for the sub expression extension to remember the ExpOpCount
+// This function is only called by sub expression.
+//
+vfrStatementExpressionSub [UINT32 RootLevel, UINT32 & ExpOpCount] :
+ andTerm[$RootLevel, $ExpOpCount]
+ (
+ L:OR andTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrOr OObj(L->getLine()); >>
+ )*
+ ;
+
+andTerm[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ bitwiseorTerm[$RootLevel, $ExpOpCount]
+ (
+ L:AND bitwiseorTerm [$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrAnd AObj(L->getLine()); >>
+ )*
+ ;
+
+bitwiseorTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ bitwiseandTerm[$RootLevel, $ExpOpCount]
+ (
+ L:"\|" bitwiseandTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrBitWiseOr BWOObj(L->getLine()); >>
+ )*
+ ;
+
+bitwiseandTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ equalTerm[$RootLevel, $ExpOpCount]
+ (
+ L:"&" equalTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrBitWiseAnd BWAObj(L->getLine()); >>
+ )*
+ ;
+
+equalTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ compareTerm[$RootLevel, $ExpOpCount]
+ (
+ (
+ L1:"==" compareTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrEqual EObj(L1->getLine()); >>
+ )
+ |
+ (
+ L2:"!=" compareTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrNotEqual NEObj(L2->getLine()); >>
+ )
+ )*
+ ;
+
+compareTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ shiftTerm[$RootLevel, $ExpOpCount]
+ (
+ (
+ L1:"<" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrLessThan LTObj(L1->getLine()); >>
+ )
+ |
+ (
+ L2:"<=" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrLessEqual LEObj(L2->getLine()); >>
+ )
+ |
+ (
+ L3:">" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrGreaterThan GTObj(L3->getLine()); >>
+ )
+ |
+ (
+ L4:">=" shiftTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrGreaterEqual GEObj(L4->getLine()); >>
+ )
+ )*
+ ;
+
+shiftTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ addMinusTerm[$RootLevel, $ExpOpCount]
+ (
+ (
+ L1:"\<<" addMinusTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrShiftLeft SLObj(L1->getLine()); >>
+ )
+ |
+ (
+ L2:"\>>" addMinusTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrShiftRight SRObj(L2->getLine()); >>
+ )
+ )*
+ ;
+
+addMinusTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ multdivmodTerm[$RootLevel, $ExpOpCount]
+ (
+ (
+ L1:"\+" multdivmodTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrAdd AObj(L1->getLine()); >>
+ )
+ |
+ (
+ L2:"\-" multdivmodTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrSubtract SObj(L2->getLine()); >>
+ )
+ )*
+ ;
+
+multdivmodTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ castTerm[$RootLevel, $ExpOpCount]
+ (
+ (
+ L1:"\*" castTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrMultiply MObj(L1->getLine()); >>
+ )
+ |
+ (
+ L2:"/" castTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrDivide DObj(L2->getLine()); >>
+ )
+ |
+ (
+ L3:"%" castTerm[$RootLevel, $ExpOpCount] << $ExpOpCount++; CIfrModulo MObj(L3->getLine()); >>
+ )
+ )*
+ ;
+
+castTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ << UINT8 CastType = 0xFF; >>
+ (
+ L:"\("
+ (
+ Boolean << CastType = 0; >>
+ | Uint64 << CastType = 1; >>
+ | Uint32 << CastType = 1; >>
+ | Uint16 << CastType = 1; >>
+ | Uint8 << CastType = 1; >>
+ )
+ "\)"
+ )*
+ atomTerm[$RootLevel, $ExpOpCount]
+ <<
+ switch (CastType) {
+ case 0: { CIfrToBoolean TBObj(L->getLine()); $ExpOpCount++; } break;
+ case 1: { CIfrToUint TUObj(L->getLine()); $ExpOpCount++; } break;
+ }
+ >>
+ ;
+
+atomTerm [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ vfrExpressionCatenate[$RootLevel, $ExpOpCount]
+ | vfrExpressionMatch[$RootLevel, $ExpOpCount]
+ | vfrExpressionMatch2[$RootLevel, $ExpOpCount]
+ | vfrExpressionParen[$RootLevel, $ExpOpCount]
+ | vfrExpressionBuildInFunction[$RootLevel, $ExpOpCount]
+ | vfrExpressionConstant[$RootLevel, $ExpOpCount]
+ | vfrExpressionUnaryOp[$RootLevel, $ExpOpCount]
+ | vfrExpressionTernaryOp[$RootLevel, $ExpOpCount]
+ | vfrExpressionMap[$RootLevel, $ExpOpCount]
+ | (
+ L:NOT
+ atomTerm[$RootLevel, $ExpOpCount] << { CIfrNot NObj(L->getLine()); $ExpOpCount++; } >>
+ )
+ ;
+
+vfrExpressionCatenate [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ L:Catenate
+ "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrCatenate CObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+vfrExpressionMatch [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ L:Match
+ "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrMatch MObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+vfrExpressionMatch2 [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ <<
+ EFI_GUID Guid;
+ >>
+ L:Match2
+ "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ guidDefinition[Guid]
+ "\)" << { CIfrMatch2 M2Obj(L->getLine(), &Guid); $ExpOpCount++; } >>
+ ;
+
+vfrExpressionParen [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)"
+ ;
+
+vfrExpressionBuildInFunction [UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ dupExp[$RootLevel, $ExpOpCount]
+ | vareqvalExp[$RootLevel, $ExpOpCount] //Compatible for Framework vareqval
+ | ideqvalExp[$RootLevel, $ExpOpCount]
+ | ideqidExp[$RootLevel, $ExpOpCount]
+ | ideqvallistExp[$RootLevel, $ExpOpCount]
+ | questionref1Exp[$RootLevel, $ExpOpCount]
+ | rulerefExp[$RootLevel, $ExpOpCount]
+ | stringref1Exp[$RootLevel, $ExpOpCount]
+ | pushthisExp[$RootLevel, $ExpOpCount]
+ | securityExp[$RootLevel, $ExpOpCount]
+ | getExp[$RootLevel, $ExpOpCount]
+ ;
+
+dupExp [UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:Dup << { CIfrDup DObj(L->getLine()); _SAVE_OPHDR_COND(DObj, ($ExpOpCount == 0), L->getLine()); $ExpOpCount++; } >>
+ ;
+
+vareqvalExp [UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_QUESTION_ID QId;
+ UINT32 Mask;
+ UINT16 ConstVal;
+ CHAR8 *VarIdStr;
+ UINT32 LineNo;
+ EFI_VFR_RETURN_CODE VfrReturnCode = VFR_RETURN_SUCCESS;
+ EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
+ >>
+ L:VarEqVal <<
+ _PCATCH (VFR_RETURN_UNSUPPORTED, L);
+ >>
+ VK:Var
+ OpenParen
+ VN:Number <<
+ VarIdStr = NULL; _STRCAT(&VarIdStr, VK->getText()); _STRCAT(&VarIdStr, VN->getText());
+ VfrReturnCode = gCVfrDataStorage.GetVarStoreId (VarIdStr, &VarStoreId);
+ if (VfrReturnCode == VFR_RETURN_UNDEFINED) {
+ _PCATCH (gCVfrDataStorage.DeclareEfiVarStore (
+ VarIdStr,
+ &mFormsetGuid,
+ _STOSID(VN->getText(), VN->getLine()),
+ 0x2, //default type is UINT16
+ FALSE
+ ), VN);
+ } else {
+ _PCATCH (VfrReturnCode, VN);
+ }
+ mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, QId, Mask);
+ LineNo = GET_LINENO(VN);
+ >>
+ CloseParen
+ (
+ (
+ "=="
+ V1:Number << ConstVal = _STOU16(V1->getText(), V1->getLine()); >>
+ <<
+ if (Mask == 0) {
+ CIfrEqIdVal EIVObj (L->getLine());
+ _SAVE_OPHDR_COND (EIVObj, ($ExpOpCount == 0), L->getLine());
+ EIVObj.SetQuestionId (QId, VarIdStr, LineNo);
+ EIVObj.SetValue (ConstVal);
+ $ExpOpCount++;
+ } else {
+ IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, EQUAL);
+ }
+ >>
+ )
+ |
+ (
+ "<="
+ V2:Number << ConstVal = _STOU16(V2->getText(), V2->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_EQUAL); >>
+ )
+ |
+ (
+ "<"
+ V3:Number << ConstVal = _STOU16(V3->getText(), V3->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_THAN); >>
+ )
+ |
+ (
+ ">="
+ V4:Number << ConstVal = _STOU16(V4->getText(), V4->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_EQUAL); >>
+ )
+ |
+ (
+ ">"
+ V5:Number << ConstVal = _STOU16(V5->getText(), V5->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_THAN); >>
+ )
+ )
+ <<
+ if (VarIdStr != NULL) {
+ delete[] VarIdStr;
+ VarIdStr = NULL;
+ }
+ >>
+ ;
+
+ideqvalExp [UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_QUESTION_ID QId;
+ UINT32 Mask;
+ UINT16 ConstVal;
+ CHAR8 *VarIdStr;
+ UINT32 LineNo;
+ >>
+ L:IdEqVal
+ vfrQuestionDataFieldName[QId, Mask, VarIdStr, LineNo]
+ (
+ (
+ "=="
+ V1:Number << ConstVal = _STOU16(V1->getText(), V1->getLine()); >>
+ <<
+ if (Mask == 0) {
+ CIfrEqIdVal EIVObj (L->getLine());
+ _SAVE_OPHDR_COND (EIVObj, ($ExpOpCount == 0), L->getLine());
+ EIVObj.SetQuestionId (QId, VarIdStr, LineNo);
+ EIVObj.SetValue (ConstVal);
+ $ExpOpCount++;
+ } else {
+ IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, EQUAL);
+ }
+ >>
+ )
+ |
+ (
+ "<="
+ V2:Number << ConstVal = _STOU16(V2->getText(), V2->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_EQUAL); >>
+ )
+ |
+ (
+ "<"
+ V3:Number << ConstVal = _STOU16(V3->getText(), V3->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, LESS_THAN); >>
+ )
+ |
+ (
+ ">="
+ V4:Number << ConstVal = _STOU16(V4->getText(), V4->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_EQUAL); >>
+ )
+ |
+ (
+ ">"
+ V5:Number << ConstVal = _STOU16(V5->getText(), V5->getLine()); >>
+ << IdEqValDoSpecial ($ExpOpCount, L->getLine(), QId, VarIdStr, Mask, ConstVal, GREATER_THAN); >>
+ )
+ )
+ <<
+ if (VarIdStr != NULL) {
+ delete[] VarIdStr;
+ VarIdStr = NULL;
+ }
+ >>
+ ;
+
+ideqidExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_QUESTION_ID QId[2];
+ UINT32 Mask[2];
+ CHAR8 *VarIdStr[2];
+ UINT32 LineNo[2];
+ >>
+ L:IdEqId
+ vfrQuestionDataFieldName[QId[0], Mask[0], VarIdStr[0], LineNo[0]]
+ (
+ (
+ "=="
+ vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]
+ <<
+ if (Mask[0] & Mask[1]) {
+ IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], EQUAL);
+ } else {
+ CIfrEqIdId EIIObj(L->getLine());
+ _SAVE_OPHDR_COND (EIIObj, ($ExpOpCount == 0), L->getLine());
+ EIIObj.SetQuestionId1 (QId[0], VarIdStr[0], LineNo[0]);
+ EIIObj.SetQuestionId2 (QId[1], VarIdStr[1], LineNo[1]);
+ $ExpOpCount++;
+ }
+ >>
+ )
+ |
+ (
+ "<="
+ vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]
+ << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], LESS_EQUAL); >>
+ )
+ |
+ (
+ "<"
+ vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]
+ << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], LESS_THAN); >>
+ )
+ |
+ (
+ ">="
+ vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]
+ << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], GREATER_EQUAL); >>
+ )
+ |
+ (
+ ">"
+ vfrQuestionDataFieldName[QId[1], Mask[1], VarIdStr[1], LineNo[1]]
+ << IdEqIdDoSpecial ($ExpOpCount, L->getLine(), QId[0], VarIdStr[0], Mask[0], QId[1], VarIdStr[1], Mask[1], GREATER_THAN); >>
+ )
+ )
+ <<
+ if (VarIdStr[0] != NULL) {
+ delete[] VarIdStr[0];
+ VarIdStr[0] = NULL;
+ }
+ if (VarIdStr[1] != NULL) {
+ delete[] VarIdStr[1];
+ VarIdStr[1] = NULL;
+ }
+ >>
+ ;
+
+ideqvallistExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ UINT16 ListLen = 0;
+ EFI_QUESTION_ID QId;
+ UINT32 Mask;
+ UINT16 ValueList[EFI_IFR_MAX_LENGTH] = {0,};
+ CHAR8 *VarIdStr;
+ UINT32 LineNo;
+ >>
+ L:IdEqValList
+ vfrQuestionDataFieldName[QId, Mask, VarIdStr, LineNo]
+ "=="
+ (
+ V:Number << ValueList[ListLen] = _STOU16(V->getText(), V->getLine()); ListLen++; >>
+ )+
+ <<
+ if (Mask != 0) {
+ IdEqListDoSpecial ($ExpOpCount, LineNo, QId, VarIdStr, Mask, ListLen, ValueList);
+ } else {
+ UINT16 Index;
+ CIfrEqIdList EILObj(L->getLine());
+ if (QId != EFI_QUESTION_ID_INVALID) {
+ EILObj.SetQuestionId (QId, VarIdStr, LineNo);
+ }
+ EILObj.SetListLength (ListLen);
+ for (Index = 0; Index < ListLen; Index++) {
+ EILObj.SetValueList (Index, ValueList[Index]);
+ }
+
+ EILObj.UpdateIfrBuffer();
+ _SAVE_OPHDR_COND (EILObj, ($ExpOpCount == 0), L->getLine());
+
+ if (QId == EFI_QUESTION_ID_INVALID) {
+ EILObj.SetQuestionId (QId, VarIdStr, LineNo);
+ }
+ $ExpOpCount++;
+ }
+ if (VarIdStr != NULL) {
+ delete[] VarIdStr;
+ VarIdStr = NULL;
+ }
+ >>
+ ;
+
+questionref1Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ UINT32 BitMask;
+ CHAR8 *QName = NULL;
+ UINT32 LineNo = 0;
+ >>
+ L:QuestionRef
+ "\("
+ (
+ QN:StringIdentifier <<
+ QName = QN->getText();
+ LineNo = QN->getLine();
+ mCVfrQuestionDB.GetQuestionId (QN->getText(), NULL, QId, BitMask);
+ >>
+ | ID:Number << QId = _STOQID(ID->getText(), ID->getLine()); >>
+ )
+ "\)"
+ <<
+ { CIfrQuestionRef1 QR1Obj(L->getLine()); _SAVE_OPHDR_COND (QR1Obj, ($ExpOpCount == 0), L->getLine()); QR1Obj.SetQuestionId (QId, QName, LineNo); } $ExpOpCount++; >>
+ ;
+
+rulerefExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:RuleRef
+ "\(" RN:StringIdentifier "\)" << { CIfrRuleRef RRObj(L->getLine()); _SAVE_OPHDR_COND (RRObj, ($ExpOpCount == 0), L->getLine()); RRObj.SetRuleId (mCVfrRulesDB.GetRuleId (RN->getText())); } $ExpOpCount++; >>
+ ;
+
+//******************************************************
+// PARSE:
+// stringref (STR_FORM_SET_TITLE)
+//
+stringref1Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_STRING_ID RefStringId = EFI_STRING_ID_INVALID;
+ >>
+ L:StringRef
+ "\("
+ (
+ "STRING_TOKEN"
+ "\("
+ S:Number << RefStringId = _STOSID(S->getText(), S->getLine()); >>
+ "\)"
+ | I:Number << RefStringId = _STOSID(I->getText(), I->getLine()); >>
+ )
+ "\)" << { CIfrStringRef1 SR1Obj(L->getLine()); _SAVE_OPHDR_COND (SR1Obj, ($ExpOpCount == 0), L->getLine()); SR1Obj.SetStringId (RefStringId); $ExpOpCount++; } >>
+ ;
+
+pushthisExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:PushThis << { CIfrThis TObj(L->getLine()); _SAVE_OPHDR_COND (TObj, ($ExpOpCount == 0), L->getLine()); $ExpOpCount++; } >>
+ ;
+
+securityExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_GUID Guid;
+ >>
+ L:Security
+ "\(" guidDefinition[Guid] "\)" << { CIfrSecurity SObj(L->getLine()); _SAVE_OPHDR_COND (SObj, ($ExpOpCount == 0), L->getLine()); SObj.SetPermissions (&Guid); } $ExpOpCount++; >>
+ ;
+
+numericVarStoreType [UINT8 & VarType] :
+ "NUMERIC_SIZE_1" << $VarType = EFI_IFR_NUMERIC_SIZE_1; >>
+ | "NUMERIC_SIZE_2" << $VarType = EFI_IFR_NUMERIC_SIZE_2; >>
+ | "NUMERIC_SIZE_4" << $VarType = EFI_IFR_NUMERIC_SIZE_4; >>
+ | "NUMERIC_SIZE_8" << $VarType = EFI_IFR_NUMERIC_SIZE_8; >>
+ ;
+
+getExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_VARSTORE_INFO Info;
+ CHAR8 *VarIdStr = NULL;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ UINT32 Mask = 0;
+ EFI_QUESION_TYPE QType = QUESTION_NORMAL;
+ UINT8 VarType = EFI_IFR_TYPE_UNDEFINED;
+ UINT32 VarSize = 0;
+ Info.mVarStoreId = 0;
+ >>
+ L:Get
+ "\("
+ vfrStorageVarId[Info, VarIdStr, FALSE]
+ {"\|" FLAGS "=" numericVarStoreType [VarType] }
+ "\)" <<
+ {
+ if (Info.mVarStoreId == 0) {
+ // support Date/Time question
+ mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, QId, Mask, &QType);
+ if (QId == EFI_QUESTION_ID_INVALID || Mask == 0 || QType == QUESTION_NORMAL) {
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode can't get the enough varstore information");
+ }
+ if (QType == QUESTION_DATE) {
+ Info.mVarType = EFI_IFR_TYPE_DATE;
+ } else if (QType == QUESTION_TIME) {
+ Info.mVarType = EFI_IFR_TYPE_TIME;
+ }
+ switch (Mask) {
+ case DATE_YEAR_BITMASK:
+ Info.mInfo.mVarOffset = 0;
+ break;
+ case DATE_DAY_BITMASK:
+ Info.mInfo.mVarOffset = 3;
+ break;
+ case TIME_HOUR_BITMASK:
+ Info.mInfo.mVarOffset = 0;
+ break;
+ case TIME_MINUTE_BITMASK:
+ Info.mInfo.mVarOffset = 1;
+ break;
+ case TIME_SECOND_BITMASK:
+ Info.mInfo.mVarOffset = 2;
+ break;
+ default:
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode can't get the enough varstore information");
+ break;
+ }
+ } else {
+ if ((gCVfrDataStorage.GetVarStoreType(Info.mVarStoreId) == EFI_VFR_VARSTORE_NAME) && (VarType == EFI_IFR_TYPE_UNDEFINED)) {
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode don't support name string");
+ }
+ if (VarType != EFI_IFR_TYPE_UNDEFINED) {
+ Info.mVarType = VarType;
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize (Info.mVarType, &VarSize), L->getLine(), "Get/Set opcode can't get var type size");
+ Info.mVarTotalSize = VarSize;
+ }
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize (Info.mVarType, &VarSize), L->getLine(), "Get/Set opcode can't get var type size");
+ if (VarSize != Info.mVarTotalSize) {
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode don't support data array");
+ }
+ }
+ CIfrGet GObj(L->getLine());
+ _SAVE_OPHDR_COND (GObj, ($ExpOpCount == 0), L->getLine());
+ GObj.SetVarInfo (&Info);
+ delete[] VarIdStr;
+ $ExpOpCount++;
+ }
+ >>
+ ;
+
+vfrExpressionConstant[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L1:True << CIfrTrue TObj(L1->getLine()); _SAVE_OPHDR_COND (TObj, ($ExpOpCount == 0), L1->getLine()); $ExpOpCount++; >>
+ | L2:False << CIfrFalse FObj(L2->getLine()); _SAVE_OPHDR_COND (FObj, ($ExpOpCount == 0), L2->getLine()); $ExpOpCount++; >>
+ | L3:One << CIfrOne OObj(L3->getLine()); _SAVE_OPHDR_COND (OObj, ($ExpOpCount == 0), L3->getLine()); $ExpOpCount++; >>
+ | L4:Ones << CIfrOnes OObj(L4->getLine()); _SAVE_OPHDR_COND (OObj, ($ExpOpCount == 0), L4->getLine()); $ExpOpCount++; >>
+ | L5:Zero << CIfrZero ZObj(L5->getLine()); _SAVE_OPHDR_COND (ZObj, ($ExpOpCount == 0), L5->getLine()); $ExpOpCount++; >>
+ | L6:Undefined << CIfrUndefined UObj(L6->getLine()); _SAVE_OPHDR_COND (UObj, ($ExpOpCount == 0), L6->getLine()); $ExpOpCount++; >>
+ | L7:Version << CIfrVersion VObj(L7->getLine()); _SAVE_OPHDR_COND (VObj, ($ExpOpCount == 0), L7->getLine()); $ExpOpCount++; >>
+ | V:Number << CIfrUint64 U64Obj(V->getLine()); U64Obj.SetValue (_STOU64(V->getText(), V->getLine())); _SAVE_OPHDR_COND (U64Obj, ($ExpOpCount == 0), V->getLine()); $ExpOpCount++; >>
+ ;
+
+vfrExpressionUnaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ lengthExp[$RootLevel, $ExpOpCount]
+ | bitwisenotExp[$RootLevel, $ExpOpCount]
+ | question23refExp[$RootLevel, $ExpOpCount]
+ | stringref2Exp[$RootLevel, $ExpOpCount]
+ | toboolExp[$RootLevel, $ExpOpCount]
+ | tostringExp[$RootLevel, $ExpOpCount]
+ | unintExp[$RootLevel, $ExpOpCount]
+ | toupperExp[$RootLevel, $ExpOpCount]
+ | tolwerExp[$RootLevel, $ExpOpCount]
+ | setExp[$RootLevel, $ExpOpCount]
+ ;
+
+lengthExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:Length
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrLength LObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+bitwisenotExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:BitWiseNot
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrBitWiseNot BWNObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+question23refExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ UINT8 Type = 0x1;
+ EFI_STRING_ID DevPath = EFI_STRING_ID_INVALID;
+ EFI_GUID Guid = {0,};
+ >>
+ L:QuestionRefVal
+ "\("
+ {
+ DevicePath "=" "STRING_TOKEN" "\(" S:Number "\)" "," << Type = 0x2; DevPath = _STOSID(S->getText(), S->getLine()); >>
+ }
+ {
+ Uuid "=" guidDefinition[Guid] "," << Type = 0x3; >>
+ }
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)"
+ <<
+ switch (Type) {
+ case 0x1: {CIfrQuestionRef2 QR2Obj(L->getLine()); _SAVE_OPHDR_COND (QR2Obj, ($ExpOpCount == 0), L->getLine()); break;}
+ case 0x2: {CIfrQuestionRef3_2 QR3_2Obj(L->getLine()); _SAVE_OPHDR_COND (QR3_2Obj, ($ExpOpCount == 0), L->getLine()); QR3_2Obj.SetDevicePath (DevPath); break;}
+ case 0x3: {CIfrQuestionRef3_3 QR3_3Obj(L->getLine()); _SAVE_OPHDR_COND (QR3_3Obj, ($ExpOpCount == 0), L->getLine()); QR3_3Obj.SetDevicePath (DevPath); QR3_3Obj.SetGuid (&Guid); break;}
+ }
+ $ExpOpCount++;
+ >>
+ ;
+
+stringref2Exp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:StringRefVal
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrStringRef2 SR2Obj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+toboolExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:BoolVal
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrToBoolean TBObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+tostringExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ << UINT8 Fmt = 0; >>
+ L:StringVal
+ {
+ Format "=" F:Number "," << Fmt = _STOU8(F->getText(), F->getLine()); >>
+ }
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrToString TSObj(L->getLine()); TSObj.SetFormat (Fmt); $ExpOpCount++; } >>
+ ;
+
+unintExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:UnIntVal
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrToUint TUObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+toupperExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:ToUpper
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrToUpper TUObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+tolwerExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:ToLower
+ "\(" vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount] "\)"
+ << { CIfrToLower TLObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+setExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ <<
+ EFI_VARSTORE_INFO Info;
+ CHAR8 *VarIdStr = NULL;
+ EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
+ UINT32 Mask = 0;
+ EFI_QUESION_TYPE QType = QUESTION_NORMAL;
+ UINT8 VarType = EFI_IFR_TYPE_UNDEFINED;
+ UINT32 VarSize = 0;
+ Info.mVarStoreId = 0;
+ >>
+ L:Set
+ "\("
+ vfrStorageVarId[Info, VarIdStr, FALSE]
+ {"\|" FLAG "=" numericVarStoreType [VarType] }
+ "," vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)"
+ <<
+ {
+ if (Info.mVarStoreId == 0) {
+ // support Date/Time question
+ mCVfrQuestionDB.GetQuestionId (NULL, VarIdStr, QId, Mask, &QType);
+ if (QId == EFI_QUESTION_ID_INVALID || Mask == 0 || QType == QUESTION_NORMAL) {
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode can't get the enough varstore information");
+ }
+ if (QType == QUESTION_DATE) {
+ Info.mVarType = EFI_IFR_TYPE_DATE;
+ } else if (QType == QUESTION_TIME) {
+ Info.mVarType = EFI_IFR_TYPE_TIME;
+ }
+ switch (Mask) {
+ case DATE_YEAR_BITMASK:
+ Info.mInfo.mVarOffset = 0;
+ break;
+ case DATE_DAY_BITMASK:
+ Info.mInfo.mVarOffset = 3;
+ break;
+ case TIME_HOUR_BITMASK:
+ Info.mInfo.mVarOffset = 0;
+ break;
+ case TIME_MINUTE_BITMASK:
+ Info.mInfo.mVarOffset = 1;
+ break;
+ case TIME_SECOND_BITMASK:
+ Info.mInfo.mVarOffset = 2;
+ break;
+ default:
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode can't get the enough varstore information");
+ break;
+ }
+ } else {
+ if ((gCVfrDataStorage.GetVarStoreType(Info.mVarStoreId) == EFI_VFR_VARSTORE_NAME) && (VarType == EFI_IFR_TYPE_UNDEFINED)) {
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode don't support name string");
+ }
+ if (VarType != EFI_IFR_TYPE_UNDEFINED) {
+ Info.mVarType = VarType;
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize (Info.mVarType, &VarSize), L->getLine(), "Get/Set opcode can't get var type size");
+ Info.mVarTotalSize = VarSize;
+ }
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize (Info.mVarType, &VarSize), L->getLine(), "Get/Set opcode can't get var type size");
+ if (VarSize != Info.mVarTotalSize) {
+ _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode don't support data array");
+ }
+ }
+ CIfrSet TSObj(L->getLine());
+ TSObj.SetVarInfo (&Info);
+ delete[] VarIdStr;
+ $ExpOpCount++;
+ }
+ >>
+ ;
+
+vfrExpressionTernaryOp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ conditionalExp[$RootLevel, $ExpOpCount]
+ | findExp[$RootLevel, $ExpOpCount]
+ | midExp[$RootLevel, $ExpOpCount]
+ | tokenExp[$RootLevel, $ExpOpCount]
+ | spanExp[$RootLevel, $ExpOpCount]
+ ;
+
+#token Cond("cond") "cond"
+#token Find("find") "find"
+#token Mid("mid") "mid"
+#token Tok("token") "token"
+#token Span("span") "span"
+
+conditionalExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:Cond "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "?"
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ":"
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrConditional CObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+findExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ << UINT8 Format; >>
+ L:Find "\("
+ findFormat[Format] ( "\|" findFormat[Format] )*
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrFind FObj(L->getLine()); FObj.SetFormat (Format); $ExpOpCount++; } >>
+ ;
+
+findFormat [UINT8 & Format] :
+ "SENSITIVE" << $Format = 0x00; >>
+ | "INSENSITIVE" << $Format = 0x01; >>
+ ;
+
+midExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:Mid "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrMid MObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+tokenExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ L:Tok "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrToken TObj(L->getLine()); $ExpOpCount++; } >>
+ ;
+
+spanExp[UINT32 & RootLevel, UINT32 & ExpOpCount] :
+ << UINT8 Flags = 0; >>
+ S:Span "\("
+ FLAGS "=" spanFlags[Flags] ( "\|" spanFlags[Flags] )*
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ","
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ "\)" << { CIfrSpan SObj(S->getLine()); SObj.SetFlags(Flags); $ExpOpCount++; } >>
+ ;
+
+vfrExpressionMap [UINT32 & RootLevel, UINT32 & ExpOpCount]:
+ L:Map
+ "\("
+ vfrStatementExpressionSub[$RootLevel + 1, $ExpOpCount]
+ ":" << { CIfrMap MObj(L->getLine()); } >>
+ (
+ vfrStatementExpression[0]
+ ","
+ vfrStatementExpression[0]
+ ";"
+ ) *
+ E:"\)" << { CIfrEnd EObj; EObj.SetLineNo(E->getLine()); $ExpOpCount++; } >>
+ ;
+
+spanFlags [UINT8 & Flags] :
+ N:Number << $Flags |= _STOU8(N->getText(), N->getLine()); >>
+ | "LAST_NON_MATCH" << $Flags |= 0x00; >>
+ | "FIRST_NON_MATCH" << $Flags |= 0x01; >>
+ ;
+
+#token StringIdentifier("string identifier") "[A-Za-z_][A-Za-z_0-9]*"
+#token Number("numeric value") "(0x[0-9A-Fa-f]+) | [0-9]+"
+
+//******************************************************************************
+//
+// Parser class definition.
+//
+class EfiVfrParser {
+<<
+private:
+ UINT8 mParserStatus;
+ BOOLEAN mConstantOnlyInExpression;
+
+ CVfrQuestionDB mCVfrQuestionDB;
+ CVfrRulesDB mCVfrRulesDB;
+
+ CIfrOpHeader * mCIfrOpHdr[MAX_IFR_EXPRESSION_DEPTH];
+ UINT32 mCIfrOpHdrLineNo[MAX_IFR_EXPRESSION_DEPTH];
+ UINT8 mCIfrOpHdrIndex;
+ VOID _SAVE_OPHDR_COND (IN CIfrOpHeader &, IN BOOLEAN, UINT32 LineNo = 0);
+ VOID _CLEAR_SAVED_OPHDR (VOID);
+ VOID _INIT_OPHDR_COND (VOID);
+ BOOLEAN _SET_SAVED_OPHDR_SCOPE (VOID);
+
+
+ EFI_VARSTORE_INFO mCurrQestVarInfo;
+ EFI_GUID *mOverrideClassGuid;
+ CHAR8* mLastFormEndAddr;
+
+//
+// Whether the question already has default value.
+//
+ UINT16 mUsedDefaultArray[EFI_IFR_MAX_DEFAULT_TYPE];
+ UINT16 mUsedDefaultCount;
+
+ EFI_GUID mFormsetGuid;
+
+ VOID _CRT_OP (IN BOOLEAN);
+
+ VOID _SAVE_CURRQEST_VARINFO (IN EFI_VARSTORE_INFO &);
+ EFI_VARSTORE_INFO & _GET_CURRQEST_VARTINFO (VOID);
+
+ UINT8 _GET_CURRQEST_DATATYPE ();
+ UINT32 _GET_CURRQEST_VARSIZE ();
+ UINT32 _GET_CURRQEST_ARRAY_SIZE();
+ VOID CheckDuplicateDefaultValue (IN EFI_DEFAULT_ID, IN ANTLRTokenPtr);
+
+public:
+ VOID _PCATCH (IN INTN, IN INTN, IN ANTLRTokenPtr, IN CONST CHAR8 *);
+ VOID _PCATCH (IN EFI_VFR_RETURN_CODE);
+ VOID _PCATCH (IN EFI_VFR_RETURN_CODE, IN ANTLRTokenPtr);
+ VOID _PCATCH (IN EFI_VFR_RETURN_CODE, IN UINT32);
+ VOID _PCATCH (IN EFI_VFR_RETURN_CODE, IN UINT32, IN CONST CHAR8 *);
+
+ VOID syn (ANTLRAbstractToken *, ANTLRChar *, SetWordType *, ANTLRTokenType, INT32);
+
+ CHAR8* TrimHex (IN CHAR8 *, OUT BOOLEAN *);
+ CHAR8* _U32TOS (IN UINT32);
+ UINT8 _STOU8 (IN CHAR8 *, IN UINT32);
+ UINT16 _STOU16 (IN CHAR8 *, IN UINT32);
+ UINT32 _STOU32 (IN CHAR8 *, IN UINT32);
+ UINT64 _STOU64 (IN CHAR8 *, IN UINT32);
+ EFI_HII_DATE _STOD (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *, IN UINT32);
+ EFI_HII_TIME _STOT (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *, IN UINT32);
+ EFI_HII_REF _STOR (IN CHAR8 *, IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *, IN UINT32);
+
+ EFI_STRING_ID _STOSID (IN CHAR8 *, IN UINT32);
+ EFI_FORM_ID _STOFID (IN CHAR8 *, IN UINT32);
+ EFI_QUESTION_ID _STOQID (IN CHAR8 *, IN UINT32);
+
+ VOID _STRCAT (IN OUT CHAR8 **, IN CONST CHAR8 *);
+
+ VOID _DeclareDefaultLinearVarStore (IN UINT32);
+ VOID _DeclareStandardDefaultStorage (IN UINT32);
+
+ VOID AssignQuestionKey (IN CIfrQuestionHeader &, IN ANTLRTokenPtr);
+
+ VOID ConvertIdExpr (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32);
+ VOID IdEqValDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN UINT16, IN EFI_COMPARE_TYPE);
+ VOID IdEqIdDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN EFI_COMPARE_TYPE);
+ VOID IdEqListDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN UINT16, IN UINT16 *);
+ VOID SetOverrideClassGuid (IN EFI_GUID *);
+>>
+}
+
+<<
+VOID
+EfiVfrParser::_SAVE_OPHDR_COND (
+ IN CIfrOpHeader &OpHdr,
+ IN BOOLEAN Cond,
+ IN UINT32 LineNo
+ )
+{
+ if (Cond == TRUE) {
+ if (mCIfrOpHdr[mCIfrOpHdrIndex] != NULL) {
+ return ;
+ }
+ mCIfrOpHdr[mCIfrOpHdrIndex] = new CIfrOpHeader(OpHdr);
+ mCIfrOpHdrLineNo[mCIfrOpHdrIndex] = LineNo;
+ }
+}
+
+VOID
+EfiVfrParser::_INIT_OPHDR_COND (
+ VOID
+ )
+{
+ mCIfrOpHdr[mCIfrOpHdrIndex] = NULL;
+ mCIfrOpHdrLineNo[mCIfrOpHdrIndex] = 0;
+}
+
+VOID
+EfiVfrParser::_CLEAR_SAVED_OPHDR (
+ VOID
+ )
+{
+ if (mCIfrOpHdr[mCIfrOpHdrIndex] != NULL) {
+ delete mCIfrOpHdr[mCIfrOpHdrIndex];
+ mCIfrOpHdr[mCIfrOpHdrIndex] = NULL;
+ }
+}
+
+BOOLEAN
+EfiVfrParser::_SET_SAVED_OPHDR_SCOPE (
+ VOID
+ )
+{
+ if (mCIfrOpHdr[mCIfrOpHdrIndex] != NULL) {
+ mCIfrOpHdr[mCIfrOpHdrIndex]->SetScope (1);
+ return TRUE;
+ }
+
+ //
+ // IfrOpHdr is not set, FALSE is return.
+ //
+ return FALSE;
+}
+
+VOID
+EfiVfrParser::_CRT_OP (
+ IN BOOLEAN Crt
+ )
+{
+ gCreateOp = Crt;
+}
+
+VOID
+EfiVfrParser::_SAVE_CURRQEST_VARINFO (
+ IN EFI_VARSTORE_INFO &Info
+ )
+{
+ mCurrQestVarInfo = Info;
+}
+
+EFI_VARSTORE_INFO &
+EfiVfrParser::_GET_CURRQEST_VARTINFO (
+ VOID
+ )
+{
+ return mCurrQestVarInfo;
+}
+
+UINT32
+EfiVfrParser::_GET_CURRQEST_ARRAY_SIZE (
+ VOID
+ )
+{
+ UINT8 Size = 1;
+
+ switch (mCurrQestVarInfo.mVarType) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Size = 1;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Size = 2;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Size = 4;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Size = 8;
+ break;
+
+ default:
+ break;
+ }
+
+ return (mCurrQestVarInfo.mVarTotalSize / Size);
+}
+
+UINT8
+EfiVfrParser::_GET_CURRQEST_DATATYPE (
+ VOID
+ )
+{
+ return mCurrQestVarInfo.mVarType;
+}
+
+UINT32
+EfiVfrParser::_GET_CURRQEST_VARSIZE (
+ VOID
+ )
+{
+ return mCurrQestVarInfo.mVarTotalSize;
+}
+
+VOID
+EfiVfrParser::_PCATCH (
+ IN INTN ReturnCode,
+ IN INTN ExpectCode,
+ IN ANTLRTokenPtr Tok,
+ IN CONST CHAR8 *ErrorMsg
+ )
+{
+ if (ReturnCode != ExpectCode) {
+ mParserStatus++;
+ gCVfrErrorHandle.PrintMsg (Tok->getLine(), Tok->getText(), "Error", ErrorMsg);
+ }
+}
+
+VOID
+EfiVfrParser::_PCATCH (
+ IN EFI_VFR_RETURN_CODE ReturnCode
+ )
+{
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (ReturnCode);
+}
+
+VOID
+EfiVfrParser::_PCATCH (
+ IN EFI_VFR_RETURN_CODE ReturnCode,
+ IN ANTLRTokenPtr Tok
+ )
+{
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (ReturnCode, Tok->getLine(), Tok->getText());
+}
+
+VOID
+EfiVfrParser::_PCATCH (
+ IN EFI_VFR_RETURN_CODE ReturnCode,
+ IN UINT32 LineNum
+ )
+{
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (ReturnCode, LineNum);
+}
+
+VOID
+EfiVfrParser::_PCATCH (
+ IN EFI_VFR_RETURN_CODE ReturnCode,
+ IN UINT32 LineNum,
+ IN CONST CHAR8 *ErrorMsg
+ )
+{
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (ReturnCode, LineNum, (CHAR8 *) ErrorMsg);
+}
+
+VOID
+EfiVfrParser::syn (
+ ANTLRAbstractToken *Tok,
+ ANTLRChar *Egroup,
+ SetWordType *Eset,
+ ANTLRTokenType ETok,
+ INT32 Huh
+ )
+{
+ gCVfrErrorHandle.HandleError (VFR_RETURN_MISMATCHED, Tok->getLine(), Tok->getText());
+
+ mParserStatus += 1;
+}
+
+CHAR8 *
+EfiVfrParser::TrimHex (
+ IN CHAR8 *Str,
+ OUT BOOLEAN *IsHex
+ )
+{
+ *IsHex = FALSE;
+
+ while (*Str && *Str == ' ') {
+ Str++;
+ }
+ while (*Str && *Str == '0') {
+ Str++;
+ }
+ if (*Str && (*Str == 'x' || *Str == 'X')) {
+ Str++;
+ *IsHex = TRUE;
+ }
+
+ return Str;
+}
+
+CHAR8 *
+EfiVfrParser::_U32TOS (
+ IN UINT32 Value
+ )
+{
+ CHAR8 *Str;
+ Str = new CHAR8[20];
+ sprintf (Str, "%d", Value);
+ return Str;
+}
+
+UINT8
+EfiVfrParser::_STOU8 (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ BOOLEAN IsHex;
+ UINT8 Value;
+ CHAR8 c;
+
+ UINT8 PreviousValue;
+ CHAR8 *OrigString = Str;
+ CHAR8 ErrorMsg[100];
+
+ Str = TrimHex (Str, &IsHex);
+ for (Value = 0; (c = *Str) != '\0'; Str++) {
+ PreviousValue = Value;
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
+
+ if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
+ Value += (c - 'a' + 10);
+ }
+ if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
+ Value += (c - 'A' + 10);
+ }
+ if (c >= '0' && c <= '9') {
+ Value += (c - '0');
+ }
+ if((IsHex && ((Value/16) != PreviousValue)) || (!IsHex && ((Value/10) != PreviousValue))) {
+ sprintf(ErrorMsg, "Overflow: Value %s is too large to store in a UINT8", OrigString);
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (VFR_RETURN_STRING_TO_UINT_OVERFLOW, LineNum, ErrorMsg);
+ }
+ }
+
+ return Value;
+}
+
+UINT16
+EfiVfrParser::_STOU16 (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ BOOLEAN IsHex;
+ UINT16 Value;
+ CHAR8 c;
+
+ UINT16 PreviousValue;
+ CHAR8 *OrigString = Str;
+ CHAR8 ErrorMsg[100];
+
+ Str = TrimHex (Str, &IsHex);
+ for (Value = 0; (c = *Str) != '\0'; Str++) {
+ PreviousValue = Value;
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
+
+ if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
+ Value += (c - 'a' + 10);
+ }
+ if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
+ Value += (c - 'A' + 10);
+ }
+ if (c >= '0' && c <= '9') {
+ Value += (c - '0');
+ }
+ if((IsHex && ((Value/16) != PreviousValue)) || (!IsHex && ((Value/10) != PreviousValue))) {
+ sprintf(ErrorMsg, "Overflow: Value %s is too large to store in a UINT16", OrigString);
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (VFR_RETURN_STRING_TO_UINT_OVERFLOW, LineNum, ErrorMsg);
+ }
+ }
+
+ return Value;
+}
+
+UINT32
+EfiVfrParser::_STOU32 (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ BOOLEAN IsHex;
+ UINT32 Value;
+ CHAR8 c;
+
+ UINT32 PreviousValue;
+ CHAR8 *OrigString = Str;
+ CHAR8 ErrorMsg[100];
+
+ Str = TrimHex (Str, &IsHex);
+ for (Value = 0; (c = *Str) != '\0'; Str++) {
+ PreviousValue = Value;
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
+
+ if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
+ Value += (c - 'a' + 10);
+ }
+ if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
+ Value += (c - 'A' + 10);
+ }
+ if (c >= '0' && c <= '9') {
+ Value += (c - '0');
+ }
+ if((IsHex && ((Value/16) != PreviousValue)) || (!IsHex && ((Value/10) != PreviousValue ))) {
+ sprintf(ErrorMsg, "Overflow: Value %s is too large to store in a UINT32", OrigString);
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (VFR_RETURN_STRING_TO_UINT_OVERFLOW, LineNum, ErrorMsg);
+ }
+ }
+
+ return Value;
+}
+
+UINT64
+EfiVfrParser::_STOU64 (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ BOOLEAN IsHex;
+ UINT64 Value;
+ CHAR8 c;
+ UINT64 PreviousValue;
+ CHAR8 *OrigString = Str;
+ CHAR8 ErrorMsg[100];
+
+ Str = TrimHex (Str, &IsHex);
+ for (Value = 0; (c = *Str) != '\0'; Str++) {
+ PreviousValue = Value;
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
+
+ if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
+ Value += (c - 'a' + 10);
+ }
+ if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
+ Value += (c - 'A' + 10);
+ }
+ if (c >= '0' && c <= '9') {
+ Value += (c - '0');
+ }
+ if((IsHex && ((Value/16) != PreviousValue)) || ((!IsHex && (Value/10) != PreviousValue))) {
+ sprintf(ErrorMsg, "Overflow: Value %s is too large to store in a UINT64", OrigString);
+ mParserStatus = mParserStatus + gCVfrErrorHandle.HandleError (VFR_RETURN_STRING_TO_UINT_OVERFLOW, LineNum, ErrorMsg);
+ }
+ }
+
+ return Value;
+}
+
+EFI_HII_DATE
+EfiVfrParser::_STOD (
+ IN CHAR8 *Year,
+ IN CHAR8 *Month,
+ IN CHAR8 *Day,
+ IN UINT32 LineNum
+ )
+{
+ EFI_HII_DATE Date;
+
+ Date.Year = _STOU16 (Year, LineNum);
+ Date.Month = _STOU8 (Month, LineNum);
+ Date.Day = _STOU8 (Day, LineNum);
+
+ return Date;
+}
+
+EFI_HII_TIME
+EfiVfrParser::_STOT (
+ IN CHAR8 *Hour,
+ IN CHAR8 *Minute,
+ IN CHAR8 *Second,
+ IN UINT32 LineNum
+ )
+{
+ EFI_HII_TIME Time;
+
+ Time.Hour = _STOU8 (Hour, LineNum);
+ Time.Minute = _STOU8 (Minute, LineNum);
+ Time.Second = _STOU8 (Second, LineNum);
+
+ return Time;
+}
+
+EFI_STRING_ID
+EfiVfrParser::_STOSID (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ return (EFI_STRING_ID)_STOU16(Str, LineNum);
+}
+
+EFI_FORM_ID
+EfiVfrParser::_STOFID (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ return (EFI_FORM_ID)_STOU16(Str, LineNum);
+}
+
+EFI_QUESTION_ID
+EfiVfrParser::_STOQID (
+ IN CHAR8 *Str,
+ IN UINT32 LineNum
+ )
+{
+ return (EFI_QUESTION_ID)_STOU16(Str, LineNum);
+}
+
+VOID
+EfiVfrParser::_STRCAT (
+ IN OUT CHAR8 **Dest,
+ IN CONST CHAR8 *Src
+ )
+{
+ CHAR8 *NewStr;
+ UINT32 Len;
+
+ if ((Dest == NULL) || (Src == NULL)) {
+ return;
+ }
+
+ Len = (*Dest == NULL) ? 0 : strlen (*Dest);
+ Len += strlen (Src);
+ if ((NewStr = new CHAR8[Len + 1]) == NULL) {
+ return;
+ }
+ NewStr[0] = '\0';
+ if (*Dest != NULL) {
+ strcpy (NewStr, *Dest);
+ delete[] *Dest;
+ }
+ strcat (NewStr, Src);
+
+ *Dest = NewStr;
+}
+
+EFI_HII_REF
+EfiVfrParser::_STOR (
+ IN CHAR8 *QuestionId,
+ IN CHAR8 *FormId,
+ IN EFI_GUID *FormSetGuid,
+ IN CHAR8 *DevicePath,
+ IN UINT32 LineNum
+ )
+{
+ EFI_HII_REF Ref;
+ UINT32 Index;
+
+ memcpy (&Ref.FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
+ Ref.QuestionId = _STOQID (QuestionId, LineNum);
+ Ref.FormId = _STOFID (FormId, LineNum);
+ Ref.DevicePath = _STOSID (DevicePath, LineNum);
+
+ return Ref;
+}
+
+VOID
+EfiVfrParser::_DeclareDefaultLinearVarStore (
+ IN UINT32 LineNo
+ )
+{
+ UINT32 Index;
+ CHAR8 **TypeNameList;
+ UINT32 ListSize;
+ CONST CHAR8 DateName[] = "Date";
+ CONST CHAR8 TimeName[] = "Time";
+ CONST CHAR8 DateType[] = "EFI_HII_DATE";
+ CONST CHAR8 TimeType[] = "EFI_HII_TIME";
+
+ gCVfrVarDataTypeDB.GetUserDefinedTypeNameList (&TypeNameList, &ListSize);
+
+ for (Index = 0; Index < ListSize; Index++) {
+ UINT32 Size;
+ EFI_VARSTORE_ID VarStoreId;
+ CIfrVarStore VSObj;
+
+ VSObj.SetLineNo (LineNo);
+ gCVfrDataStorage.DeclareBufferVarStore (
+ TypeNameList[Index],
+ &mFormsetGuid,
+ &gCVfrVarDataTypeDB,
+ TypeNameList[Index],
+ EFI_VARSTORE_ID_INVALID,
+ FALSE
+ );
+ gCVfrDataStorage.GetVarStoreId(TypeNameList[Index], &VarStoreId, &mFormsetGuid);
+ VSObj.SetVarStoreId (VarStoreId);
+ gCVfrVarDataTypeDB.GetDataTypeSize(TypeNameList[Index], &Size);
+ VSObj.SetSize ((UINT16) Size);
+ VSObj.SetName (TypeNameList[Index]);
+ VSObj.SetGuid (&mFormsetGuid);
+ }
+
+//
+// not required to declare Date and Time VarStore,
+// because code to support old format Data and Time
+//
+ if (gCVfrVarDataTypeDB.IsTypeNameDefined ((CHAR8 *) DateName) == FALSE) {
+ UINT32 Size;
+ EFI_VARSTORE_ID VarStoreId;
+ CIfrVarStore VSObj;
+
+ VSObj.SetLineNo (LineNo);
+ gCVfrDataStorage.DeclareBufferVarStore (
+ (CHAR8 *) DateName,
+ &mFormsetGuid,
+ &gCVfrVarDataTypeDB,
+ (CHAR8 *) DateType,
+ EFI_VARSTORE_ID_INVALID,
+ FALSE
+ );
+ gCVfrDataStorage.GetVarStoreId((CHAR8 *) DateName, &VarStoreId, &mFormsetGuid);
+ VSObj.SetVarStoreId (VarStoreId);
+ gCVfrVarDataTypeDB.GetDataTypeSize((CHAR8 *) DateType, &Size);
+ VSObj.SetSize ((UINT16) Size);
+ VSObj.SetName ((CHAR8 *) DateName);
+ VSObj.SetGuid (&mFormsetGuid);
+ }
+
+ if (gCVfrVarDataTypeDB.IsTypeNameDefined ((CHAR8 *) TimeName) == FALSE) {
+ UINT32 Size;
+ EFI_VARSTORE_ID VarStoreId;
+ CIfrVarStore VSObj;
+
+ VSObj.SetLineNo (LineNo);
+ gCVfrDataStorage.DeclareBufferVarStore (
+ (CHAR8 *) TimeName,
+ &mFormsetGuid,
+ &gCVfrVarDataTypeDB,
+ (CHAR8 *) TimeType,
+ EFI_VARSTORE_ID_INVALID,
+ FALSE
+ );
+ gCVfrDataStorage.GetVarStoreId((CHAR8 *) TimeName, &VarStoreId, &mFormsetGuid);
+ VSObj.SetVarStoreId (VarStoreId);
+ gCVfrVarDataTypeDB.GetDataTypeSize((CHAR8 *) TimeType, &Size);
+ VSObj.SetSize ((UINT16) Size);
+ VSObj.SetName ((CHAR8 *) TimeName);
+ VSObj.SetGuid (&mFormsetGuid);
+ }
+}
+
+VOID
+EfiVfrParser::_DeclareStandardDefaultStorage (
+ IN UINT32 LineNo
+ )
+{
+ //
+ // Default Store is declared.
+ //
+ CIfrDefaultStore DSObj;
+
+ gCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr<CHAR8>(), (CHAR8 *) "Standard Defaults", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_STANDARD);
+ DSObj.SetLineNo (LineNo);
+ DSObj.SetDefaultName (EFI_STRING_ID_INVALID);
+ DSObj.SetDefaultId (EFI_HII_DEFAULT_CLASS_STANDARD);
+
+ //
+ // Default MANUFACTURING Store is declared.
+ //
+ CIfrDefaultStore DSObjMF;
+
+ gCVfrDefaultStore.RegisterDefaultStore (DSObjMF.GetObjBinAddr<CHAR8>(), (CHAR8 *) "Standard ManuFacturing", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_MANUFACTURING);
+ DSObjMF.SetLineNo (LineNo);
+ DSObjMF.SetDefaultName (EFI_STRING_ID_INVALID);
+ DSObjMF.SetDefaultId (EFI_HII_DEFAULT_CLASS_MANUFACTURING);
+}
+
+VOID
+EfiVfrParser::AssignQuestionKey (
+ IN CIfrQuestionHeader &QHObj,
+ IN ANTLRTokenPtr KeyTok
+ )
+{
+ UINT16 KeyValue;
+
+ if (KeyTok == NULL) {
+ return;
+ }
+
+ KeyValue = _STOU16 (KeyTok->getText(), KeyTok->getLine());
+
+ if (QHObj.FLAGS () & EFI_IFR_FLAG_CALLBACK) {
+ /*
+ * if the question is not CALLBACK ignore the key.
+ */
+ _PCATCH(mCVfrQuestionDB.UpdateQuestionId (QHObj.QUESTION_ID(), KeyValue), KeyTok);
+ QHObj.SetQuestionId (KeyValue);
+ }
+}
+
+VOID
+EfiVfrParser::ConvertIdExpr (
+ IN UINT32 &ExpOpCount,
+ IN UINT32 LineNo,
+ IN EFI_QUESTION_ID QId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 BitMask
+ )
+{
+ CIfrQuestionRef1 QR1Obj(LineNo);
+ QR1Obj.SetQuestionId (QId, VarIdStr, LineNo);
+ _SAVE_OPHDR_COND (QR1Obj, (ExpOpCount == 0));
+
+ if (BitMask != 0) {
+ CIfrUint32 U32Obj(LineNo);
+ U32Obj.SetValue (BitMask);
+
+ CIfrBitWiseAnd BWAObj(LineNo);
+
+ CIfrUint8 U8Obj(LineNo);
+ switch (BitMask) {
+ case DATE_YEAR_BITMASK : U8Obj.SetValue (0); break;
+ case TIME_SECOND_BITMASK : U8Obj.SetValue (0x10); break;
+ case DATE_DAY_BITMASK : U8Obj.SetValue (0x18); break;
+ case TIME_HOUR_BITMASK : U8Obj.SetValue (0); break;
+ case TIME_MINUTE_BITMASK : U8Obj.SetValue (0x8); break;
+ }
+
+ CIfrShiftRight SRObj(LineNo);
+ }
+
+ ExpOpCount += 4;
+}
+
+VOID
+EfiVfrParser::IdEqValDoSpecial (
+ IN UINT32 &ExpOpCount,
+ IN UINT32 LineNo,
+ IN EFI_QUESTION_ID QId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 BitMask,
+ IN UINT16 ConstVal,
+ IN EFI_COMPARE_TYPE CompareType
+ )
+{
+ ConvertIdExpr (ExpOpCount, LineNo, QId, VarIdStr, BitMask);
+
+ if (ConstVal > 0xFF) {
+ CIfrUint16 U16Obj(LineNo);
+ U16Obj.SetValue (ConstVal);
+ } else {
+ CIfrUint8 U8Obj(LineNo);
+ U8Obj.SetValue ((UINT8)ConstVal);
+ }
+
+ switch (CompareType) {
+ case EQUAL :
+ {
+ CIfrEqual EObj(LineNo);
+ break;
+ }
+ case LESS_EQUAL :
+ {
+ CIfrLessEqual LEObj(LineNo);
+ break;
+ }
+ case LESS_THAN :
+ {
+ CIfrLessThan LTObj(LineNo);
+ break;
+ }
+ case GREATER_EQUAL :
+ {
+ CIfrGreaterEqual GEObj(LineNo);
+ break;
+ }
+ case GREATER_THAN :
+ {
+ CIfrGreaterThan GTObj(LineNo);
+ break;
+ }
+ }
+
+ ExpOpCount += 2;
+}
+
+VOID
+EfiVfrParser::IdEqIdDoSpecial (
+ IN UINT32 &ExpOpCount,
+ IN UINT32 LineNo,
+ IN EFI_QUESTION_ID QId1,
+ IN CHAR8 *VarId1Str,
+ IN UINT32 BitMask1,
+ IN EFI_QUESTION_ID QId2,
+ IN CHAR8 *VarId2Str,
+ IN UINT32 BitMask2,
+ IN EFI_COMPARE_TYPE CompareType
+ )
+{
+ ConvertIdExpr (ExpOpCount, LineNo, QId1, VarId1Str, BitMask1);
+ ConvertIdExpr (ExpOpCount, LineNo, QId2, VarId2Str, BitMask2);
+
+ switch (CompareType) {
+ case EQUAL :
+ {
+ CIfrEqual EObj(LineNo);
+ break;
+ }
+ case LESS_EQUAL :
+ {
+ CIfrLessEqual LEObj(LineNo);
+ break;
+ }
+ case LESS_THAN :
+ {
+ CIfrLessThan LTObj(LineNo);
+ break;
+ }
+ case GREATER_EQUAL :
+ {
+ CIfrGreaterEqual GEObj(LineNo);
+ break;
+ }
+ case GREATER_THAN :
+ {
+ CIfrGreaterThan GTObj(LineNo);
+ break;
+ }
+ }
+
+ ExpOpCount++;
+}
+
+VOID
+EfiVfrParser::IdEqListDoSpecial (
+ IN UINT32 &ExpOpCount,
+ IN UINT32 LineNo,
+ IN EFI_QUESTION_ID QId,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 BitMask,
+ IN UINT16 ListLen,
+ IN UINT16 *ValueList
+ )
+{
+ UINT16 Index;
+
+ if (ListLen == 0) {
+ return;
+ }
+
+ IdEqValDoSpecial (ExpOpCount, LineNo, QId, VarIdStr, BitMask, ValueList[0], EQUAL);
+ for (Index = 1; Index < ListLen; Index++) {
+ IdEqValDoSpecial (ExpOpCount, LineNo, QId, VarIdStr, BitMask, ValueList[Index], EQUAL);
+ CIfrOr OObj (LineNo);
+ ExpOpCount++;
+ }
+}
+
+VOID
+EfiVfrParser::SetOverrideClassGuid (IN EFI_GUID *OverrideClassGuid)
+{
+ mOverrideClassGuid = OverrideClassGuid;
+}
+
+VOID
+EfiVfrParser::CheckDuplicateDefaultValue (
+ IN EFI_DEFAULT_ID DefaultId,
+ IN ANTLRTokenPtr Tok
+ )
+{
+ UINT16 Index;
+
+ for(Index = 0; Index < mUsedDefaultCount; Index++) {
+ if (mUsedDefaultArray[Index] == DefaultId) {
+ gCVfrErrorHandle.HandleWarning (VFR_WARNING_DEFAULT_VALUE_REDEFINED, Tok->getLine(), Tok->getText());
+ }
+ }
+
+ if (mUsedDefaultCount >= EFI_IFR_MAX_DEFAULT_TYPE - 1) {
+ gCVfrErrorHandle.HandleError (VFR_RETURN_FATAL_ERROR, Tok->getLine(), Tok->getText());
+ }
+
+ mUsedDefaultArray[mUsedDefaultCount++] = DefaultId;
+}
+>>
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
new file mode 100644
index 00000000..899f7123
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -0,0 +1,3921 @@
+/** @file
+
+ Vfr common library functions.
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "assert.h"
+#include "CommonLib.h"
+#include "VfrUtilityLib.h"
+#include "VfrFormPkg.h"
+
+VOID
+CVfrBinaryOutput::WriteLine (
+ IN FILE *pFile,
+ IN UINT32 LineBytes,
+ IN CONST CHAR8 *LineHeader,
+ IN CHAR8 *BlkBuf,
+ IN UINT32 BlkSize
+ )
+{
+ UINT32 Index;
+
+ if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
+ return;
+ }
+
+ for (Index = 0; Index < BlkSize; Index++) {
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
+ }
+}
+
+VOID
+CVfrBinaryOutput::WriteEnd (
+ IN FILE *pFile,
+ IN UINT32 LineBytes,
+ IN CONST CHAR8 *LineHeader,
+ IN CHAR8 *BlkBuf,
+ IN UINT32 BlkSize
+ )
+{
+ UINT32 Index;
+
+ if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
+ return;
+ }
+
+ for (Index = 0; Index < BlkSize - 1; Index++) {
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
+ }
+
+ if ((Index % LineBytes) == 0) {
+ fprintf (pFile, "\n%s", LineHeader);
+ }
+ fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
+}
+
+SConfigInfo::SConfigInfo (
+ IN UINT8 Type,
+ IN UINT16 Offset,
+ IN UINT32 Width,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ mNext = NULL;
+ mOffset = Offset;
+ mWidth = (UINT16)Width;
+ mValue = new UINT8[mWidth];
+ if (mValue == NULL) {
+ return;
+ }
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8 :
+ memcpy (mValue, &Value.u8, mWidth);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16 :
+ memcpy (mValue, &Value.u16, mWidth);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32 :
+ memcpy (mValue, &Value.u32, mWidth);
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64 :
+ memcpy (mValue, &Value.u64, mWidth);
+ break;
+ case EFI_IFR_TYPE_BOOLEAN :
+ memcpy (mValue, &Value.b, mWidth);
+ break;
+ case EFI_IFR_TYPE_TIME :
+ memcpy (mValue, &Value.time, mWidth);
+ break;
+ case EFI_IFR_TYPE_DATE :
+ memcpy (mValue, &Value.date, mWidth);
+ break;
+ case EFI_IFR_TYPE_STRING :
+ memcpy (mValue, &Value.string, mWidth);
+ break;
+ case EFI_IFR_TYPE_BUFFER :
+ memcpy (mValue, &Value.u8, mWidth);
+ break;
+
+ case EFI_IFR_TYPE_OTHER :
+ return;
+ }
+}
+
+SConfigInfo::~SConfigInfo (
+ VOID
+ )
+{
+ ARRAY_SAFE_FREE (mValue);
+}
+
+SConfigItem::SConfigItem (
+ IN CHAR8 *Name,
+ IN EFI_GUID *Guid,
+ IN CHAR8 *Id
+ )
+{
+ mName = NULL;
+ mGuid = NULL;
+ mId = NULL;
+ mInfoStrList = NULL;
+ mNext = NULL;
+
+ if (Name != NULL) {
+ if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
+ strcpy (mName, Name);
+ }
+ }
+
+ if (Guid != NULL) {
+ if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
+ memcpy (mGuid, Guid, sizeof (EFI_GUID));
+ }
+ }
+
+ if (Id != NULL) {
+ if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
+ strcpy (mId, Id);
+ }
+ }
+}
+
+SConfigItem::SConfigItem (
+ IN CHAR8 *Name,
+ IN EFI_GUID *Guid,
+ IN CHAR8 *Id,
+ IN UINT8 Type,
+ IN UINT16 Offset,
+ IN UINT16 Width,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ mName = NULL;
+ mGuid = NULL;
+ mId = NULL;
+ mInfoStrList = NULL;
+ mNext = NULL;
+
+ if (Name != NULL) {
+ if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
+ strcpy (mName, Name);
+ }
+ }
+
+ if (Guid != NULL) {
+ if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
+ memcpy (mGuid, Guid, sizeof (EFI_GUID));
+ }
+ }
+
+ if (Id != NULL) {
+ if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
+ strcpy (mId, Id);
+ }
+ }
+
+ mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
+}
+
+SConfigItem::~SConfigItem (
+ VOID
+ )
+{
+ SConfigInfo *Info;
+
+ ARRAY_SAFE_FREE (mName);
+ ARRAY_SAFE_FREE (mGuid);
+ ARRAY_SAFE_FREE (mId);
+ while (mInfoStrList != NULL) {
+ Info = mInfoStrList;
+ mInfoStrList = mInfoStrList->mNext;
+
+ BUFFER_SAFE_FREE (Info);
+ }
+}
+
+UINT8
+CVfrBufferConfig::Register (
+ IN CHAR8 *Name,
+ IN EFI_GUID *Guid,
+ IN CHAR8 *Id
+ )
+{
+ SConfigItem *pNew;
+
+ if (Select (Name, Guid) == 0) {
+ return 1;
+ }
+
+ if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {
+ return 2;
+ }
+
+ if (mItemListHead == NULL) {
+ mItemListHead = pNew;
+ mItemListTail = pNew;
+ } else {
+ mItemListTail->mNext = pNew;
+ mItemListTail = pNew;
+ }
+ mItemListPos = pNew;
+
+ return 0;
+}
+
+VOID
+CVfrBufferConfig::Open (
+ VOID
+ )
+{
+ mItemListPos = mItemListHead;
+}
+
+BOOLEAN
+CVfrBufferConfig::Eof(
+ VOID
+ )
+{
+ return (mItemListPos == NULL) ? TRUE : FALSE;
+}
+
+UINT8
+CVfrBufferConfig::Select (
+ IN CHAR8 *Name,
+ IN EFI_GUID *Guid,
+ IN CHAR8 *Id
+ )
+{
+ SConfigItem *p;
+
+ if (Name == NULL || Guid == NULL) {
+ mItemListPos = mItemListHead;
+ return 0;
+ } else {
+ for (p = mItemListHead; p != NULL; p = p->mNext) {
+ if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {
+ continue;
+ }
+
+ if (Id != NULL) {
+ if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
+ continue;
+ }
+ } else if (p->mId != NULL) {
+ continue;
+ }
+
+ mItemListPos = p;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+UINT8
+CVfrBufferConfig::Write (
+ IN CONST CHAR8 Mode,
+ IN CHAR8 *Name,
+ IN EFI_GUID *Guid,
+ IN CHAR8 *Id,
+ IN UINT8 Type,
+ IN UINT16 Offset,
+ IN UINT32 Width,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ UINT8 Ret;
+ SConfigItem *pItem;
+ SConfigInfo *pInfo;
+
+ if ((Ret = Select (Name, Guid)) != 0) {
+ return Ret;
+ }
+
+ switch (Mode) {
+ case 'a' : // add
+ if (Select (Name, Guid, Id) != 0) {
+ if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {
+ return 2;
+ }
+ if (mItemListHead == NULL) {
+ mItemListHead = pItem;
+ mItemListTail = pItem;
+ } else {
+ mItemListTail->mNext = pItem;
+ mItemListTail = pItem;
+ }
+ mItemListPos = pItem;
+ } else {
+ // tranverse the list to find out if there's already the value for the same offset
+ for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {
+ if (pInfo->mOffset == Offset) {
+ return 0;
+ }
+ }
+ if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
+ return 2;
+ }
+ pInfo->mNext = mItemListPos->mInfoStrList;
+ mItemListPos->mInfoStrList = pInfo;
+ }
+ break;
+
+ case 'd' : // delete
+ if (mItemListHead == mItemListPos) {
+ mItemListHead = mItemListPos->mNext;
+ delete mItemListPos;
+ break;
+ }
+
+ for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
+ ;
+
+ pItem->mNext = mItemListPos->mNext;
+ if (mItemListTail == mItemListPos) {
+ mItemListTail = pItem;
+ }
+ delete mItemListPos;
+ mItemListPos = pItem->mNext;
+ break;
+
+ case 'i' : // set info
+ if (mItemListPos->mId != NULL) {
+ delete[] mItemListPos->mId;
+ }
+ mItemListPos->mId = NULL;
+ if (Id != NULL) {
+ if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
+ return 2;
+ }
+ strcpy (mItemListPos->mId, Id);
+ }
+ break;
+
+ default :
+ return 1;
+ }
+
+ return 0;
+}
+
+
+VOID
+CVfrBufferConfig::Close (
+ VOID
+ )
+{
+ mItemListPos = NULL;
+}
+
+#define BYTES_PRE_LINE 0x10
+
+VOID
+CVfrBufferConfig::OutputCFile (
+ IN FILE *pFile,
+ IN CHAR8 *BaseName
+ )
+{
+ CVfrBinaryOutput Output;
+ SConfigItem *Item;
+ SConfigInfo *Info;
+ UINT32 TotalLen;
+
+ if (pFile == NULL) {
+ return;
+ }
+
+ for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
+ if (Item->mId != NULL || Item->mInfoStrList == NULL) {
+ continue;
+ }
+ fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
+
+ TotalLen = sizeof (UINT32);
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ TotalLen += sizeof (UINT16) * 2;
+ }
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
+
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ fprintf (pFile, "\n");
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
+ }
+ fprintf (pFile, "\n};\n");
+ }
+
+ for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
+ if (Item->mId != NULL && Item->mInfoStrList != NULL) {
+ fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);
+
+ TotalLen = sizeof (UINT32);
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ TotalLen += Info->mWidth + sizeof (UINT16) * 2;
+ }
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
+
+ for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
+ fprintf (pFile, "\n");
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
+ if (Info->mNext == NULL) {
+ Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
+ } else {
+ Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
+ }
+ }
+ fprintf (pFile, "\n};\n");
+ }
+ }
+}
+
+CVfrBufferConfig::CVfrBufferConfig (
+ VOID
+ )
+{
+ mItemListHead = NULL;
+ mItemListTail = NULL;
+ mItemListPos = NULL;
+}
+
+CVfrBufferConfig::~CVfrBufferConfig (
+ VOID
+ )
+{
+ SConfigItem *p;
+
+ while (mItemListHead != NULL) {
+ p = mItemListHead;
+ mItemListHead = mItemListHead->mNext;
+ delete p;
+ }
+
+ mItemListHead = NULL;
+ mItemListTail = NULL;
+ mItemListPos = NULL;
+}
+
+CVfrBufferConfig gCVfrBufferConfig;
+
+static struct {
+ CONST CHAR8 *mTypeName;
+ UINT8 mType;
+ UINT32 mSize;
+ UINT32 mAlign;
+} gInternalTypesTable [] = {
+ {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)},
+ {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)},
+ {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)},
+ {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)},
+ {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)},
+ {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},
+ {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
+ {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},
+ {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},
+ {NULL, EFI_IFR_TYPE_OTHER, 0, 0}
+};
+
+STATIC
+BOOLEAN
+_IS_INTERNAL_TYPE (
+ IN CHAR8 *TypeName
+ )
+{
+ UINT32 Index;
+
+ if (TypeName == NULL) {
+ return FALSE;
+ }
+
+ for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
+ if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+STATIC
+CHAR8 *
+TrimHex (
+ IN CHAR8 *Str,
+ OUT bool *IsHex
+ )
+{
+ *IsHex = FALSE;
+
+ while (*Str && *Str == ' ') {
+ Str++;
+ }
+ while (*Str && *Str == '0') {
+ Str++;
+ }
+ if (*Str && (*Str == 'x' || *Str == 'X')) {
+ Str++;
+ *IsHex = TRUE;
+ }
+
+ return Str;
+}
+
+UINT32
+_STR2U32 (
+ IN CHAR8 *Str
+ )
+{
+ bool IsHex;
+ UINT32 Value;
+ CHAR8 c;
+
+ Str = TrimHex (Str, &IsHex);
+ for (Value = 0; (c = *Str) != '\0'; Str++) {
+ //
+ // BUG: does not handle overflow here
+ //
+ (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
+
+ if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
+ Value += (c - 'a' + 10);
+ }
+ if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
+ Value += (c - 'A' + 10);
+ }
+ if (c >= '0' && c <= '9') {
+ Value += (c - '0');
+ }
+ }
+
+ return Value;
+}
+
+VOID
+CVfrVarDataTypeDB::RegisterNewType (
+ IN SVfrDataType *New
+ )
+{
+ New->mNext = mDataTypeList;
+ mDataTypeList = New;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::ExtractStructTypeName (
+ IN CHAR8 *&VarStr,
+ OUT CHAR8 *TName
+ )
+{
+ if (TName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ while((*VarStr != '\0') && (*VarStr != '.')) {
+ *TName = *VarStr;
+ VarStr++;
+ TName++;
+ }
+ *TName = '\0';
+ if (*VarStr == '.') {
+ VarStr++;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+/**
+ Check whether the DataType contain bit field.
+
+ @param TypeName The name of the type.
+
+**/
+BOOLEAN
+CVfrVarDataTypeDB::DataTypeHasBitField (
+ IN CHAR8 *TypeName
+ )
+{
+ SVfrDataType *pType = NULL;
+ SVfrDataField *pTmp;
+
+ GetDataType (TypeName, &pType);
+
+ if (pType == NULL){
+ return FALSE;
+ }
+ for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {
+ if (pTmp->mIsBitField) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Check whether the field is bit field or not.
+
+ @param VarStr Point to the field name which may contain the structure name.
+
+**/
+BOOLEAN
+CVfrVarDataTypeDB::IsThisBitField (
+ IN CHAR8 *VarStr
+ )
+{
+ CHAR8 FName[MAX_NAME_LEN];
+ CHAR8 TName[MAX_NAME_LEN];
+ UINT32 ArrayIdx;
+ SVfrDataType *pType = NULL;
+ SVfrDataField *pField = NULL;
+
+ CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
+ CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
+
+ while (*VarStr != '\0') {
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
+ CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
+ pType = pField->mFieldType;
+ }
+ if (pField != NULL && pField->mIsBitField) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
+ IN CHAR8 *&VarStr,
+ IN CHAR8 *FName,
+ OUT UINT32 &ArrayIdx
+ )
+{
+ UINT32 Idx;
+ CHAR8 ArrayStr[MAX_NAME_LEN + 1];
+
+ ArrayIdx = INVALID_ARRAY_INDEX;
+
+ if (FName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ while((*VarStr != '\0') &&
+ (*VarStr != '.') &&
+ (*VarStr != '[') &&
+ (*VarStr != ']')) {
+ *FName = *VarStr;
+ VarStr++;
+ FName++;
+ }
+ *FName = '\0';
+
+ switch (*VarStr) {
+ case '.' :
+ VarStr++;
+ /* fall through */
+ case '\0':
+ return VFR_RETURN_SUCCESS;
+ case '[' :
+ VarStr++;
+ for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
+ ArrayStr[Idx] = *VarStr;
+ }
+ ArrayStr[Idx] = '\0';
+
+ if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
+ return VFR_RETURN_DATA_STRING_ERROR;
+ }
+ ArrayIdx = _STR2U32 (ArrayStr);
+ if (*VarStr == ']') {
+ VarStr++;
+ }
+ if (*VarStr == '.') {
+ VarStr++;
+ }
+ return VFR_RETURN_SUCCESS;
+ case ']':
+ return VFR_RETURN_DATA_STRING_ERROR;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetTypeField (
+ IN CONST CHAR8 *FName,
+ IN SVfrDataType *Type,
+ OUT SVfrDataField *&Field
+ )
+{
+ SVfrDataField *pField = NULL;
+
+ if ((FName == NULL) || (Type == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
+ //
+ // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
+ // add code to adjust it.
+ //
+ if (Type->mType == EFI_IFR_TYPE_TIME) {
+ if (strcmp (FName, "Hour") == 0) {
+ FName = "Hours";
+ } else if (strcmp (FName, "Minute") == 0) {
+ FName = "Minuts";
+ } else if (strcmp (FName, "Second") == 0) {
+ FName = "Seconds";
+ }
+ }
+
+ if (strcmp (pField->mFieldName, FName) == 0) {
+ Field = pField;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetFieldOffset (
+ IN SVfrDataField *Field,
+ IN UINT32 ArrayIdx,
+ OUT UINT32 &Offset,
+ IN BOOLEAN IsBitField
+ )
+{
+ if (Field == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
+ return VFR_RETURN_ERROR_ARRARY_NUM;
+ }
+
+ //
+ // Be compatible with the current usage
+ // If ArraryIdx is not specified, the first one is used.
+ //
+ // if ArrayNum is larger than zero, ArraryIdx must be specified.
+ //
+ // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
+ // return VFR_RETURN_ERROR_ARRARY_NUM;
+ // }
+ //
+ if (IsBitField) {
+ Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;
+ } else {
+ Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
+ }
+ return VFR_RETURN_SUCCESS;
+}
+
+UINT8
+CVfrVarDataTypeDB::GetFieldWidth (
+ IN SVfrDataField *Field
+ )
+{
+ if (Field == NULL) {
+ return 0;
+ }
+
+ return Field->mFieldType->mType;
+}
+
+UINT32
+CVfrVarDataTypeDB::GetFieldSize (
+ IN SVfrDataField *Field,
+ IN UINT32 ArrayIdx,
+ IN BOOLEAN BitField
+ )
+{
+ if (Field == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
+ return Field->mFieldType->mTotalSize * Field->mArrayNum;
+ } else {
+ if (BitField) {
+ return Field->mBitWidth;
+ } else {
+ return Field->mFieldType->mTotalSize;
+ }
+ }
+}
+
+VOID
+CVfrVarDataTypeDB::InternalTypesListInit (
+ VOID
+ )
+{
+ SVfrDataType *New = NULL;
+ UINT32 Index;
+
+ for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
+ New = new SVfrDataType;
+ if (New != NULL) {
+ assert (strlen (gInternalTypesTable[Index].mTypeName) < MAX_NAME_LEN);
+ strncpy (New->mTypeName, gInternalTypesTable[Index].mTypeName, MAX_NAME_LEN - 1);
+ New->mTypeName[MAX_NAME_LEN - 1] = 0;
+ New->mType = gInternalTypesTable[Index].mType;
+ New->mAlign = gInternalTypesTable[Index].mAlign;
+ New->mTotalSize = gInternalTypesTable[Index].mSize;
+ if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
+ SVfrDataField *pYearField = new SVfrDataField;
+ SVfrDataField *pMonthField = new SVfrDataField;
+ SVfrDataField *pDayField = new SVfrDataField;
+
+ strcpy (pYearField->mFieldName, "Year");
+ GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);
+ pYearField->mOffset = 0;
+ pYearField->mNext = pMonthField;
+ pYearField->mArrayNum = 0;
+ pYearField->mIsBitField = FALSE;
+
+ strcpy (pMonthField->mFieldName, "Month");
+ GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
+ pMonthField->mOffset = 2;
+ pMonthField->mNext = pDayField;
+ pMonthField->mArrayNum = 0;
+ pMonthField->mIsBitField = FALSE;
+
+ strcpy (pDayField->mFieldName, "Day");
+ GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
+ pDayField->mOffset = 3;
+ pDayField->mNext = NULL;
+ pDayField->mArrayNum = 0;
+ pDayField->mIsBitField = FALSE;
+
+ New->mMembers = pYearField;
+ } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
+ SVfrDataField *pHoursField = new SVfrDataField;
+ SVfrDataField *pMinutesField = new SVfrDataField;
+ SVfrDataField *pSecondsField = new SVfrDataField;
+
+ strcpy (pHoursField->mFieldName, "Hours");
+ GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);
+ pHoursField->mOffset = 0;
+ pHoursField->mNext = pMinutesField;
+ pHoursField->mArrayNum = 0;
+ pHoursField->mIsBitField = FALSE;
+
+ strcpy (pMinutesField->mFieldName, "Minutes");
+ GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
+ pMinutesField->mOffset = 1;
+ pMinutesField->mNext = pSecondsField;
+ pMinutesField->mArrayNum = 0;
+ pMinutesField->mIsBitField = FALSE;
+
+ strcpy (pSecondsField->mFieldName, "Seconds");
+ GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
+ pSecondsField->mOffset = 2;
+ pSecondsField->mNext = NULL;
+ pSecondsField->mArrayNum = 0;
+ pSecondsField->mIsBitField = FALSE;
+
+ New->mMembers = pHoursField;
+ } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
+ SVfrDataField *pQuestionIdField = new SVfrDataField;
+ SVfrDataField *pFormIdField = new SVfrDataField;
+ SVfrDataField *pFormSetGuidField = new SVfrDataField;
+ SVfrDataField *pDevicePathField = new SVfrDataField;
+
+ strcpy (pQuestionIdField->mFieldName, "QuestionId");
+ GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);
+ pQuestionIdField->mOffset = 0;
+ pQuestionIdField->mNext = pFormIdField;
+ pQuestionIdField->mArrayNum = 0;
+ pQuestionIdField->mIsBitField = FALSE;
+
+ strcpy (pFormIdField->mFieldName, "FormId");
+ GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
+ pFormIdField->mOffset = 2;
+ pFormIdField->mNext = pFormSetGuidField;
+ pFormIdField->mArrayNum = 0;
+ pFormIdField->mIsBitField = FALSE;
+
+ strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
+ GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
+ pFormSetGuidField->mOffset = 4;
+ pFormSetGuidField->mNext = pDevicePathField;
+ pFormSetGuidField->mArrayNum = 0;
+ pFormSetGuidField->mIsBitField = FALSE;
+
+ strcpy (pDevicePathField->mFieldName, "DevicePath");
+ GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
+ pDevicePathField->mOffset = 20;
+ pDevicePathField->mNext = NULL;
+ pDevicePathField->mArrayNum = 0;
+ pDevicePathField->mIsBitField = FALSE;
+
+ New->mMembers = pQuestionIdField;
+ } else {
+ New->mMembers = NULL;
+ }
+ New->mNext = NULL;
+ RegisterNewType (New);
+ New = NULL;
+ }
+ }
+}
+
+CVfrVarDataTypeDB::CVfrVarDataTypeDB (
+ VOID
+ )
+{
+ mDataTypeList = NULL;
+ mNewDataType = NULL;
+ mCurrDataField = NULL;
+ mPackAlign = DEFAULT_PACK_ALIGN;
+ mPackStack = NULL;
+ mFirstNewDataTypeName = NULL;
+ mCurrDataType = NULL;
+
+ InternalTypesListInit ();
+}
+
+CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
+ VOID
+ )
+{
+ SVfrDataType *pType;
+ SVfrDataField *pField;
+ SVfrPackStackNode *pPack;
+
+ if (mNewDataType != NULL) {
+ delete mNewDataType;
+ }
+
+ while (mDataTypeList != NULL) {
+ pType = mDataTypeList;
+ mDataTypeList = mDataTypeList->mNext;
+ while(pType->mMembers != NULL) {
+ pField = pType->mMembers;
+ pType->mMembers = pType->mMembers->mNext;
+ delete pField;
+ }
+ delete pType;
+ }
+
+ while (mPackStack != NULL) {
+ pPack = mPackStack;
+ mPackStack = mPackStack->mNext;
+ delete pPack;
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::Pack (
+ IN UINT32 LineNum,
+ IN UINT8 Action,
+ IN CHAR8 *Identifier,
+ IN UINT32 Number
+ )
+{
+ UINT32 PackAlign;
+ CHAR8 Msg[MAX_STRING_LEN] = {0, };
+
+ if (Action & VFR_PACK_SHOW) {
+ sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
+ gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);
+ }
+
+ if (Action & VFR_PACK_PUSH) {
+ SVfrPackStackNode *pNew = NULL;
+
+ if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+ pNew->mNext = mPackStack;
+ mPackStack = pNew;
+ }
+
+ if (Action & VFR_PACK_POP) {
+ SVfrPackStackNode *pNode = NULL;
+
+ if (mPackStack == NULL) {
+ gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");
+ }
+
+ for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->Match (Identifier) == TRUE) {
+ mPackAlign = pNode->mNumber;
+ mPackStack = pNode->mNext;
+ }
+ }
+ }
+
+ if (Action & VFR_PACK_ASSIGN) {
+ PackAlign = (Number > 1) ? Number + Number % 2 : Number;
+ if ((PackAlign == 0) || (PackAlign > 16)) {
+ gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
+ } else {
+ mPackAlign = PackAlign;
+ }
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrVarDataTypeDB::DeclareDataTypeBegin (
+ VOID
+ )
+{
+ SVfrDataType *pNewType = NULL;
+
+ pNewType = new SVfrDataType;
+ pNewType->mTypeName[0] = '\0';
+ pNewType->mType = EFI_IFR_TYPE_OTHER;
+ pNewType->mAlign = DEFAULT_ALIGN;
+ pNewType->mTotalSize = 0;
+ pNewType->mMembers = NULL;
+ pNewType->mNext = NULL;
+ pNewType->mHasBitField = FALSE;
+
+ mNewDataType = pNewType;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::SetNewTypeName (
+ IN CHAR8 *TypeName
+ )
+{
+ SVfrDataType *pType;
+
+ if (mNewDataType == NULL) {
+ return VFR_RETURN_ERROR_SKIPED;
+ }
+ if (TypeName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+ if (strlen(TypeName) >= MAX_NAME_LEN) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
+ if (strcmp(pType->mTypeName, TypeName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1);
+ mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0;
+ return VFR_RETURN_SUCCESS;
+}
+
+/**
+ Record the bit field info in the data type.
+
+ @param FieldName Point to the field name.
+ @param TypeName Point to the type name.
+ @param Width The bit width.
+ @param FieldInUnion The filed is in Union type or Structure type.
+
+**/
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::DataTypeAddBitField (
+ IN CHAR8 *FieldName,
+ IN CHAR8 *TypeName,
+ IN UINT32 Width,
+ IN BOOLEAN FieldInUnion
+ )
+{
+ SVfrDataField *pNewField = NULL;
+ SVfrDataType *pFieldType = NULL;
+ SVfrDataField *pTmp;
+ UINT32 Align;
+ UINT32 MaxDataTypeSize;
+ BOOLEAN UpdateTotalSize;
+
+ CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
+
+ if (Width > MAX_BIT_WIDTH) {
+ return VFR_RETURN_BIT_WIDTH_ERROR;
+ }
+
+ if (Width > pFieldType->mTotalSize * 8) {
+ return VFR_RETURN_BIT_WIDTH_ERROR;
+ }
+
+ if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ if (Width == 0 && FieldName != NULL) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
+ if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ Align = MIN (mPackAlign, pFieldType->mAlign);
+ UpdateTotalSize = FALSE;
+
+ if ((pNewField = new SVfrDataField) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ MaxDataTypeSize = mNewDataType->mTotalSize;
+ if (FieldName != NULL) {
+ strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
+ pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
+ }
+ pNewField->mFieldType = pFieldType;
+ pNewField->mIsBitField = TRUE;
+ pNewField->mBitWidth = Width;
+ pNewField->mArrayNum = 0;
+ pNewField->mBitOffset = 0;
+ pNewField->mOffset = 0;
+
+ if (mNewDataType->mMembers == NULL) {
+ mNewDataType->mMembers = pNewField;
+ pNewField->mNext = NULL;
+ } else {
+ for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
+ ;
+ pTmp->mNext = pNewField;
+ pNewField->mNext = NULL;
+ }
+
+ if (FieldInUnion) {
+ pNewField->mOffset = 0;
+ if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
+ mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
+ }
+ } else {
+ //
+ // Check whether the bit fields can be contained within one FieldType.
+ //
+ if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&
+ (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {
+ pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;
+ pNewField->mOffset = pTmp->mOffset;
+ //
+ // If BitWidth=0,used to force alignment at the next word boundary.
+ // So make this bit field occupy the remaing bit width of current field type.
+ //
+ if (pNewField->mBitWidth == 0) {
+ pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);
+ }
+ } else {
+ //
+ // The bit filed start a new memory
+ //
+ pNewField->mBitOffset = mNewDataType->mTotalSize * 8;
+ UpdateTotalSize = TRUE;
+ }
+ }
+
+ if (UpdateTotalSize){
+ if ((mNewDataType->mTotalSize % Align) == 0) {
+ pNewField->mOffset = mNewDataType->mTotalSize;
+ } else {
+ pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
+ }
+ mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);
+ }
+
+ mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
+ mNewDataType->mHasBitField = TRUE;
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::DataTypeAddField (
+ IN CHAR8 *FieldName,
+ IN CHAR8 *TypeName,
+ IN UINT32 ArrayNum,
+ IN BOOLEAN FieldInUnion
+ )
+{
+ SVfrDataField *pNewField = NULL;
+ SVfrDataType *pFieldType = NULL;
+ SVfrDataField *pTmp;
+ UINT32 Align;
+ UINT32 MaxDataTypeSize;
+
+ CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
+ MaxDataTypeSize = mNewDataType->mTotalSize;
+
+ if (strlen (FieldName) >= MAX_NAME_LEN) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
+ if (strcmp (pTmp->mFieldName, FieldName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ Align = MIN (mPackAlign, pFieldType->mAlign);
+
+ if ((pNewField = new SVfrDataField) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
+ pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
+ pNewField->mFieldType = pFieldType;
+ pNewField->mArrayNum = ArrayNum;
+ pNewField->mIsBitField = FALSE;
+ if ((mNewDataType->mTotalSize % Align) == 0) {
+ pNewField->mOffset = mNewDataType->mTotalSize;
+ } else {
+ pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
+ }
+ if (mNewDataType->mMembers == NULL) {
+ mNewDataType->mMembers = pNewField;
+ pNewField->mNext = NULL;
+ } else {
+ for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
+ ;
+ pTmp->mNext = pNewField;
+ pNewField->mNext = NULL;
+ }
+
+ mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
+
+ if (FieldInUnion) {
+ if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
+ mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
+ }
+ pNewField->mOffset = 0;
+ } else {
+ mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrVarDataTypeDB::DeclareDataTypeEnd (
+ VOID
+ )
+{
+ if (mNewDataType->mTypeName[0] == '\0') {
+ return;
+ }
+
+ if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
+ mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
+ }
+
+ RegisterNewType (mNewDataType);
+ if (mFirstNewDataTypeName == NULL) {
+ mFirstNewDataTypeName = mNewDataType->mTypeName;
+ }
+
+ mNewDataType = NULL;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataType (
+ IN CHAR8 *TypeName,
+ OUT SVfrDataType **DataType
+ )
+{
+ SVfrDataType *pDataType = NULL;
+
+ if (TypeName == NULL) {
+ return VFR_RETURN_ERROR_SKIPED;
+ }
+
+ if (DataType == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *DataType = NULL;
+
+ for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
+ if (strcmp (TypeName, pDataType->mTypeName) == 0) {
+ *DataType = pDataType;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataTypeSize (
+ IN UINT8 DataType,
+ OUT UINT32 *Size
+ )
+{
+ SVfrDataType *pDataType = NULL;
+
+ if (Size == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *Size = 0;
+ DataType = DataType & 0x0F;
+
+ //
+ // For user defined data type, the size can't be got by this function.
+ //
+ if (DataType == EFI_IFR_TYPE_OTHER) {
+ return VFR_RETURN_SUCCESS;
+ }
+
+ for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
+ if (DataType == pDataType->mType) {
+ *Size = pDataType->mTotalSize;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataTypeSize (
+ IN CHAR8 *TypeName,
+ OUT UINT32 *Size
+ )
+{
+ SVfrDataType *pDataType = NULL;
+
+ if (Size == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *Size = 0;
+
+ for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
+ if (strcmp (TypeName, pDataType->mTypeName) == 0) {
+ *Size = pDataType->mTotalSize;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetDataFieldInfo (
+ IN CHAR8 *VarStr,
+ OUT UINT16 &Offset,
+ OUT UINT8 &Type,
+ OUT UINT32 &Size,
+ OUT BOOLEAN &BitField
+ )
+{
+ CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
+ UINT32 ArrayIdx, Tmp;
+ SVfrDataType *pType = NULL;
+ SVfrDataField *pField = NULL;
+ CHAR8 *VarStrName;
+
+ Offset = 0;
+ Type = EFI_IFR_TYPE_OTHER;
+ Size = 0;
+ VarStrName = VarStr;
+
+ CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
+ CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
+
+ BitField = IsThisBitField (VarStrName);
+
+ //
+ // if it is not struct data type
+ //
+ Type = pType->mType;
+ Size = pType->mTotalSize;
+
+ while (*VarStr != '\0') {
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
+ CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
+ pType = pField->mFieldType;
+ CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);
+ if (BitField && !pField->mIsBitField) {
+ Offset = (UINT16) (Offset + Tmp * 8);
+ } else {
+ Offset = (UINT16) (Offset + Tmp);
+ }
+ Type = GetFieldWidth (pField);
+ Size = GetFieldSize (pField, ArrayIdx, BitField);
+ }
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
+ OUT CHAR8 ***NameList,
+ OUT UINT32 *ListSize
+ )
+{
+ UINT32 Index;
+ SVfrDataType *pType;
+
+ if ((NameList == NULL) || (ListSize == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ *NameList = NULL;
+ *ListSize = 0;
+
+ for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
+ if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
+ (*ListSize)++;
+ }
+ }
+
+ if (*ListSize == 0) {
+ return VFR_RETURN_SUCCESS;
+ }
+
+ if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
+ *ListSize = 0;
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
+ if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
+ (*NameList)[Index] = pType->mTypeName;
+ }
+ }
+ return VFR_RETURN_SUCCESS;
+}
+
+BOOLEAN
+CVfrVarDataTypeDB::IsTypeNameDefined (
+ IN CHAR8 *TypeName
+ )
+{
+ SVfrDataType *pType;
+
+ if (TypeName == NULL) {
+ return FALSE;
+ }
+
+ for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
+ if (strcmp (pType->mTypeName, TypeName) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID
+CVfrVarDataTypeDB::Dump (
+ IN FILE *File
+ )
+{
+ SVfrDataType *pTNode;
+ SVfrDataField *pFNode;
+
+ fprintf (File, "\n\n***************************************************************\n");
+ fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
+ for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
+ fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
+ fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
+ for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
+ if (pFNode->mArrayNum > 0) {
+ fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
+ pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
+ } else {
+ fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
+ pFNode->mFieldName, pFNode->mFieldType->mTypeName);
+ }
+ }
+ fprintf (File, "\t\t};\n");
+ fprintf (File, "---------------------------------------------------------------\n");
+ }
+ fprintf (File, "***************************************************************\n");
+}
+
+#ifdef CVFR_VARDATATYPEDB_DEBUG
+VOID
+CVfrVarDataTypeDB::ParserDB (
+ VOID
+ )
+{
+ SVfrDataType *pTNode;
+ SVfrDataField *pFNode;
+
+ printf ("***************************************************************\n");
+ printf ("\t\tmPackAlign = %x\n", mPackAlign);
+ for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
+ printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
+ printf ("\t\tstruct %s {\n", pTNode->mTypeName);
+ for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
+ printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
+ }
+ printf ("\t\t};\n");
+ printf ("---------------------------------------------------------------\n");
+ }
+ printf ("***************************************************************\n");
+}
+#endif
+
+SVfrVarStorageNode::SVfrVarStorageNode (
+ IN EFI_GUID *Guid,
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN EFI_STRING_ID VarName,
+ IN UINT32 VarSize,
+ IN BOOLEAN Flag
+ )
+{
+ if (Guid != NULL) {
+ mGuid = *Guid;
+ } else {
+ memset (&mGuid, 0, sizeof (EFI_GUID));
+ }
+ if (StoreName != NULL) {
+ mVarStoreName = new CHAR8[strlen(StoreName) + 1];
+ strcpy (mVarStoreName, StoreName);
+ } else {
+ mVarStoreName = NULL;
+ }
+ mNext = NULL;
+ mVarStoreId = VarStoreId;
+ mVarStoreType = EFI_VFR_VARSTORE_EFI;
+ mStorageInfo.mEfiVar.mEfiVarName = VarName;
+ mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
+ mAssignedFlag = Flag;
+}
+
+SVfrVarStorageNode::SVfrVarStorageNode (
+ IN EFI_GUID *Guid,
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN SVfrDataType *DataType,
+ IN BOOLEAN BitsVarstore,
+ IN BOOLEAN Flag
+ )
+{
+ if (Guid != NULL) {
+ mGuid = *Guid;
+ } else {
+ memset (&mGuid, 0, sizeof (EFI_GUID));
+ }
+ if (StoreName != NULL) {
+ mVarStoreName = new CHAR8[strlen(StoreName) + 1];
+ strcpy (mVarStoreName, StoreName);
+ } else {
+ mVarStoreName = NULL;
+ }
+ mNext = NULL;
+ mVarStoreId = VarStoreId;
+ if (BitsVarstore) {
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;
+ } else {
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
+ }
+ mStorageInfo.mDataType = DataType;
+ mAssignedFlag = Flag;
+}
+
+SVfrVarStorageNode::SVfrVarStorageNode (
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ memset (&mGuid, 0, sizeof (EFI_GUID));
+ if (StoreName != NULL) {
+ mVarStoreName = new CHAR8[strlen(StoreName) + 1];
+ strcpy (mVarStoreName, StoreName);
+ } else {
+ mVarStoreName = NULL;
+ }
+ mNext = NULL;
+ mVarStoreId = VarStoreId;
+ mVarStoreType = EFI_VFR_VARSTORE_NAME;
+ mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
+ mStorageInfo.mNameSpace.mTableSize = 0;
+ mAssignedFlag = FALSE;
+}
+
+SVfrVarStorageNode::~SVfrVarStorageNode (
+ VOID
+ )
+{
+ if (mVarStoreName != NULL) {
+ delete[] mVarStoreName;
+ }
+
+ if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
+ delete[] mStorageInfo.mNameSpace.mNameTable;
+ }
+}
+
+CVfrDataStorage::CVfrDataStorage (
+ VOID
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
+ mFreeVarStoreIdBitMap[Index] = 0;
+ }
+
+ // Question ID 0 is reserved.
+ mFreeVarStoreIdBitMap[0] = 0x80000000;
+
+ mBufferVarStoreList = NULL;
+ mEfiVarStoreList = NULL;
+ mNameVarStoreList = NULL;
+ mCurrVarStorageNode = NULL;
+ mNewVarStorageNode = NULL;
+ mBufferFieldInfoListHead = NULL;
+ mBufferFieldInfoListTail = NULL;
+}
+
+CVfrDataStorage::~CVfrDataStorage (
+ VOID
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ while (mBufferVarStoreList != NULL) {
+ pNode = mBufferVarStoreList;
+ mBufferVarStoreList = mBufferVarStoreList->mNext;
+ delete pNode;
+ }
+ while (mEfiVarStoreList != NULL) {
+ pNode = mEfiVarStoreList;
+ mEfiVarStoreList = mEfiVarStoreList->mNext;
+ delete pNode;
+ }
+ while (mNameVarStoreList != NULL) {
+ pNode = mNameVarStoreList;
+ mNameVarStoreList = mNameVarStoreList->mNext;
+ delete pNode;
+ }
+ if (mNewVarStorageNode != NULL) {
+ delete mNewVarStorageNode;
+ }
+}
+
+EFI_VARSTORE_ID
+CVfrDataStorage::GetFreeVarStoreId (
+ EFI_VFR_VARSTORE_TYPE VarType
+ )
+{
+ UINT32 Index, Mask, Offset;
+
+ Index = 0;
+
+ for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
+ if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
+ break;
+ }
+ }
+
+ if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {
+ return EFI_VARSTORE_ID_INVALID;
+ }
+
+ for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
+ if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
+ mFreeVarStoreIdBitMap[Index] |= Mask;
+ return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
+ }
+ }
+
+ return EFI_VARSTORE_ID_INVALID;
+}
+
+BOOLEAN
+CVfrDataStorage::ChekVarStoreIdFree (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
+
+ return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
+}
+
+VOID
+CVfrDataStorage::MarkVarStoreIdUsed (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
+
+ mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
+}
+
+VOID
+CVfrDataStorage::MarkVarStoreIdUnused (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
+
+ mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareNameVarStoreBegin (
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ SVfrVarStorageNode *pNode = NULL;
+ EFI_VARSTORE_ID TmpVarStoreId;
+
+ if (StoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
+ } else {
+ if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
+ return VFR_RETURN_VARSTOREID_REDEFINED;
+ }
+ MarkVarStoreIdUsed (VarStoreId);
+ }
+
+ if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ mNewVarStorageNode = pNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::NameTableAddItem (
+ IN EFI_STRING_ID Item
+ )
+{
+ EFI_VARSTORE_ID *NewTable, *OldTable;
+ UINT32 TableSize;
+
+ OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
+ TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
+
+ if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
+ if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+ memcpy (NewTable, OldTable, TableSize);
+ mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
+ }
+
+ mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
+ mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareNameVarStoreEnd (
+ IN EFI_GUID *Guid
+ )
+{
+ mNewVarStorageNode->mGuid = *Guid;
+ mNewVarStorageNode->mNext = mNameVarStoreList;
+ mNameVarStoreList = mNewVarStorageNode;
+
+ mNewVarStorageNode = NULL;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareEfiVarStore (
+ IN CHAR8 *StoreName,
+ IN EFI_GUID *Guid,
+ IN EFI_STRING_ID NameStrId,
+ IN UINT32 VarSize,
+ IN BOOLEAN Flag
+ )
+{
+ SVfrVarStorageNode *pNode;
+ EFI_VARSTORE_ID VarStoreId;
+
+ if ((StoreName == NULL) || (Guid == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (VarSize > sizeof (UINT64)) {
+ return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
+ }
+
+ if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
+ if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNode->mNext = mEfiVarStoreList;
+ mEfiVarStoreList = pNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::DeclareBufferVarStore (
+ IN CHAR8 *StoreName,
+ IN EFI_GUID *Guid,
+ IN CVfrVarDataTypeDB *DataTypeDB,
+ IN CHAR8 *TypeName,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN BOOLEAN IsBitVarStore,
+ IN BOOLEAN Flag
+ )
+{
+ SVfrVarStorageNode *pNew = NULL;
+ SVfrDataType *pDataType = NULL;
+ EFI_VARSTORE_ID TempVarStoreId;
+
+ if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
+ } else {
+ if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
+ return VFR_RETURN_VARSTOREID_REDEFINED;
+ }
+ MarkVarStoreIdUsed (VarStoreId);
+ }
+
+ if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNew->mNext = mBufferVarStoreList;
+ mBufferVarStoreList = pNew;
+
+ if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetVarStoreByDataType (
+ IN CHAR8 *DataTypeName,
+ OUT SVfrVarStorageNode **VarNode,
+ IN EFI_GUID *VarGuid
+ )
+{
+ SVfrVarStorageNode *pNode;
+ SVfrVarStorageNode *MatchNode;
+
+ MatchNode = NULL;
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
+ continue;
+ }
+
+ if ((VarGuid != NULL)) {
+ if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
+ *VarNode = pNode;
+ return VFR_RETURN_SUCCESS;
+ }
+ } else {
+ if (MatchNode == NULL) {
+ MatchNode = pNode;
+ } else {
+ //
+ // More than one varstores referred the same data structures.
+ //
+ return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
+ }
+ }
+ }
+
+ if (MatchNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ *VarNode = MatchNode;
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VARSTORE_ID
+CVfrDataStorage::CheckGuidField (
+ IN SVfrVarStorageNode *pNode,
+ IN EFI_GUID *StoreGuid,
+ IN BOOLEAN *HasFoundOne,
+ OUT EFI_VFR_RETURN_CODE *ReturnCode
+ )
+{
+ if (StoreGuid != NULL) {
+ //
+ // If has guid info, compare the guid filed.
+ //
+ if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
+ //
+ // Both name and guid are same, this this varstore.
+ //
+ mCurrVarStorageNode = pNode;
+ *ReturnCode = VFR_RETURN_SUCCESS;
+ return TRUE;
+ }
+ } else {
+ //
+ // Not has Guid field, check whether this name is the only one.
+ //
+ if (*HasFoundOne) {
+ //
+ // The name has conflict, return name redefined.
+ //
+ *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
+ return TRUE;
+ }
+
+ *HasFoundOne = TRUE;
+ mCurrVarStorageNode = pNode;
+ }
+
+ return FALSE;
+}
+
+/**
+ Base on the input store name and guid to find the varstore id.
+
+ If both name and guid are inputed, base on the name and guid to
+ found the varstore. If only name inputed, base on the name to
+ found the varstore and go on to check whether more than one varstore
+ has the same name. If only has found one varstore, return this
+ varstore; if more than one varstore has same name, return varstore
+ name redefined error. If no varstore found by varstore name, call
+ function GetVarStoreByDataType and use inputed varstore name as
+ data type name to search.
+**/
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetVarStoreId (
+ IN CHAR8 *StoreName,
+ OUT EFI_VARSTORE_ID *VarStoreId,
+ IN EFI_GUID *StoreGuid
+ )
+{
+ EFI_VFR_RETURN_CODE ReturnCode;
+ SVfrVarStorageNode *pNode;
+ BOOLEAN HasFoundOne = FALSE;
+
+ mCurrVarStorageNode = NULL;
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;
+ return ReturnCode;
+ }
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;
+ return ReturnCode;
+ }
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
+ if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;
+ return ReturnCode;
+ }
+ }
+ }
+
+ if (HasFoundOne) {
+ *VarStoreId = mCurrVarStorageNode->mVarStoreId;
+ return VFR_RETURN_SUCCESS;
+ }
+
+ *VarStoreId = EFI_VARSTORE_ID_INVALID;
+
+ //
+ // Assume that Data structure name is used as StoreName, and check again.
+ //
+ ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
+ if (pNode != NULL) {
+ mCurrVarStorageNode = pNode;
+ *VarStoreId = pNode->mVarStoreId;
+ }
+
+ return ReturnCode;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetBufferVarStoreDataTypeName (
+ IN EFI_VARSTORE_ID VarStoreId,
+ OUT CHAR8 **DataTypeName
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_VARSTORE_TYPE
+CVfrDataStorage::GetVarStoreType (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ SVfrVarStorageNode *pNode;
+ EFI_VFR_VARSTORE_TYPE VarStoreType;
+
+ VarStoreType = EFI_VFR_VARSTORE_INVALID;
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ return VarStoreType;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarStoreType = pNode->mVarStoreType;
+ return VarStoreType;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarStoreType = pNode->mVarStoreType;
+ return VarStoreType;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarStoreType = pNode->mVarStoreType;
+ return VarStoreType;
+ }
+ }
+
+ return VarStoreType;
+}
+
+EFI_GUID *
+CVfrDataStorage::GetVarStoreGuid (
+ IN EFI_VARSTORE_ID VarStoreId
+ )
+{
+ SVfrVarStorageNode *pNode;
+ EFI_GUID *VarGuid;
+
+ VarGuid = NULL;
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ return VarGuid;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarGuid = &pNode->mGuid;
+ return VarGuid;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarGuid = &pNode->mGuid;
+ return VarGuid;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ VarGuid = &pNode->mGuid;
+ return VarGuid;
+ }
+ }
+
+ return VarGuid;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetVarStoreName (
+ IN EFI_VARSTORE_ID VarStoreId,
+ OUT CHAR8 **VarStoreName
+ )
+{
+ SVfrVarStorageNode *pNode;
+
+ if (VarStoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *VarStoreName = pNode->mVarStoreName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *VarStoreName = pNode->mVarStoreName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mVarStoreId == VarStoreId) {
+ *VarStoreName = pNode->mVarStoreName;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ *VarStoreName = NULL;
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetEfiVarStoreInfo (
+ IN OUT EFI_VARSTORE_INFO *Info
+ )
+{
+ if (Info == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (mCurrVarStorageNode == NULL) {
+ return VFR_RETURN_GET_EFIVARSTORE_ERROR;
+ }
+
+ Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
+ Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
+ switch (Info->mVarTotalSize) {
+ case 1:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
+ break;
+ case 2:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
+ break;
+ case 4:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
+ break;
+ case 8:
+ Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
+ break;
+ default :
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::AddBufferVarStoreFieldInfo (
+ IN EFI_VARSTORE_INFO *Info
+ )
+{
+ BufferVarStoreFieldInfoNode *pNew;
+
+ if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (mBufferFieldInfoListHead == NULL) {
+ mBufferFieldInfoListHead = pNew;
+ mBufferFieldInfoListTail= pNew;
+ } else {
+ mBufferFieldInfoListTail->mNext = pNew;
+ mBufferFieldInfoListTail = pNew;
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetBufferVarStoreFieldInfo (
+ IN OUT EFI_VARSTORE_INFO *Info
+ )
+{
+ BufferVarStoreFieldInfoNode *pNode;
+
+ pNode = mBufferFieldInfoListHead;
+ while (pNode != NULL) {
+ if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
+ Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
+ Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
+ Info->mVarType = pNode->mVarStoreInfo.mVarType;
+ return VFR_RETURN_SUCCESS;
+ }
+ pNode = pNode->mNext;
+ }
+ return VFR_RETURN_FATAL_ERROR;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDataStorage::GetNameVarStoreInfo (
+ OUT EFI_VARSTORE_INFO *Info,
+ IN UINT32 Index
+ )
+{
+ if (Info == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ if (mCurrVarStorageNode == NULL) {
+ return VFR_RETURN_GET_NVVARSTORE_ERROR;
+ }
+
+ Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
+
+ return VFR_RETURN_SUCCESS;
+}
+
+SVfrDefaultStoreNode::SVfrDefaultStoreNode (
+ IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
+ IN CHAR8 *RefName,
+ IN EFI_STRING_ID DefaultStoreNameId,
+ IN UINT16 DefaultId
+ )
+{
+ mObjBinAddr = ObjBinAddr;
+
+ if (RefName != NULL) {
+ mRefName = new CHAR8[strlen (RefName) + 1];
+ strcpy (mRefName, RefName);
+ } else {
+ mRefName = NULL;
+ }
+
+ mNext = NULL;
+ mDefaultId = DefaultId;
+ mDefaultStoreNameId = DefaultStoreNameId;
+}
+
+SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
+ VOID
+ )
+{
+ if (mRefName != NULL) {
+ delete[] mRefName;
+ }
+}
+
+CVfrDefaultStore::CVfrDefaultStore (
+ VOID
+ )
+{
+ mDefaultStoreList = NULL;
+}
+
+CVfrDefaultStore::~CVfrDefaultStore (
+ VOID
+ )
+{
+ SVfrDefaultStoreNode *pTmp = NULL;
+
+ while (mDefaultStoreList != NULL) {
+ pTmp = mDefaultStoreList;
+ mDefaultStoreList = mDefaultStoreList->mNext;
+ delete pTmp;
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::RegisterDefaultStore (
+ IN CHAR8 *ObjBinAddr,
+ IN CHAR8 *RefName,
+ IN EFI_STRING_ID DefaultStoreNameId,
+ IN UINT16 DefaultId
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+
+ if (RefName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mRefName, RefName) == 0) {
+ return VFR_RETURN_REDEFINED;
+ }
+ }
+
+ if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ pNode->mNext = mDefaultStoreList;
+ mDefaultStoreList = pNode;
+
+ return VFR_RETURN_SUCCESS;
+}
+
+/*
+ * assign new reference name or new default store name id only if
+ * the original is invalid
+ */
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::ReRegisterDefaultStoreById (
+ IN UINT16 DefaultId,
+ IN CHAR8 *RefName,
+ IN EFI_STRING_ID DefaultStoreNameId
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mDefaultId == DefaultId) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ } else {
+ if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
+ pNode->mDefaultStoreNameId = DefaultStoreNameId;
+ if (pNode->mObjBinAddr != NULL) {
+ pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
+ }
+ } else {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ if (RefName != NULL) {
+ delete pNode->mRefName;
+ pNode->mRefName = new CHAR8[strlen (RefName) + 1];
+ if (pNode->mRefName != NULL) {
+ strcpy (pNode->mRefName, RefName);
+ }
+ }
+ }
+
+ return VFR_RETURN_SUCCESS;
+}
+
+BOOLEAN
+CVfrDefaultStore::DefaultIdRegistered (
+ IN UINT16 DefaultId
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mDefaultId == DefaultId) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::GetDefaultId (
+ IN CHAR8 *RefName,
+ OUT UINT16 *DefaultId
+ )
+{
+ SVfrDefaultStoreNode *pTmp = NULL;
+
+ if (DefaultId == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
+ if (strcmp (pTmp->mRefName, RefName) == 0) {
+ *DefaultId = pTmp->mDefaultId;
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrDefaultStore::BufferVarStoreAltConfigAdd (
+ IN EFI_VARSTORE_ID DefaultId,
+ IN EFI_VARSTORE_INFO &Info,
+ IN CHAR8 *VarStoreName,
+ IN EFI_GUID *VarStoreGuid,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE Value
+ )
+{
+ SVfrDefaultStoreNode *pNode = NULL;
+ CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
+ INTN Returnvalue = 0;
+
+ if (VarStoreName == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mDefaultId == DefaultId) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ gCVfrBufferConfig.Open ();
+
+ sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
+ if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
+ if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
+ goto WriteError;
+ }
+ }
+
+ gCVfrBufferConfig.Close ();
+
+ return VFR_RETURN_SUCCESS;
+
+WriteError:
+ gCVfrBufferConfig.Close ();
+ return (EFI_VFR_RETURN_CODE)Returnvalue;
+}
+
+SVfrRuleNode::SVfrRuleNode (
+ IN CHAR8 *RuleName,
+ IN UINT8 RuleId
+ )
+{
+ if (RuleName != NULL) {
+ mRuleName = new CHAR8[strlen (RuleName) + 1];
+ strcpy (mRuleName, RuleName);
+ } else {
+ mRuleName = NULL;
+ }
+
+ mNext = NULL;
+ mRuleId = RuleId;
+}
+
+SVfrRuleNode::~SVfrRuleNode (
+ VOID
+ )
+{
+ if (mRuleName != NULL) {
+ delete[] mRuleName;
+ }
+}
+
+CVfrRulesDB::CVfrRulesDB ()
+{
+ mRuleList = NULL;
+ mFreeRuleId = EFI_VARSTORE_ID_START;
+}
+
+CVfrRulesDB::~CVfrRulesDB ()
+{
+ SVfrRuleNode *pNode;
+
+ while(mRuleList != NULL) {
+ pNode = mRuleList;
+ mRuleList = mRuleList->mNext;
+ delete pNode;
+ }
+}
+
+VOID
+CVfrRulesDB::RegisterRule (
+ IN CHAR8 *RuleName
+ )
+{
+ SVfrRuleNode *pNew;
+
+ if (RuleName == NULL) {
+ return ;
+ }
+
+ if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
+ return ;
+ }
+
+ mFreeRuleId++;
+
+ pNew->mNext = mRuleList;
+ mRuleList = pNew;
+}
+
+UINT8
+CVfrRulesDB::GetRuleId (
+ IN CHAR8 *RuleName
+ )
+{
+ SVfrRuleNode *pNode;
+
+ if (RuleName == NULL) {
+ return EFI_RULE_ID_INVALID;
+ }
+
+ for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mRuleName, RuleName) == 0) {
+ return pNode->mRuleId;
+ }
+ }
+
+ return EFI_RULE_ID_INVALID;
+}
+
+CVfrRulesDB gCVfrRulesDB;
+
+EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
+ VOID
+ )
+{
+ mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ mInfo.mVarName = EFI_STRING_ID_INVALID;
+ mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ mVarType = EFI_IFR_TYPE_OTHER;
+ mVarTotalSize = 0;
+ mIsBitVar = FALSE;
+}
+
+EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
+ IN EFI_VARSTORE_INFO &Info
+ )
+{
+ mVarStoreId = Info.mVarStoreId;
+ mInfo.mVarName = Info.mInfo.mVarName;
+ mInfo.mVarOffset = Info.mInfo.mVarOffset;
+ mVarType = Info.mVarType;
+ mVarTotalSize = Info.mVarTotalSize;
+ mIsBitVar = Info.mIsBitVar;
+}
+
+EFI_VARSTORE_INFO&
+EFI_VARSTORE_INFO::operator= (
+ IN CONST EFI_VARSTORE_INFO &Info
+ )
+{
+ if (this != &Info) {
+ mVarStoreId = Info.mVarStoreId;
+ mInfo.mVarName = Info.mInfo.mVarName;
+ mInfo.mVarOffset = Info.mInfo.mVarOffset;
+ mVarType = Info.mVarType;
+ mVarTotalSize = Info.mVarTotalSize;
+ mIsBitVar = Info.mIsBitVar;
+ }
+
+ return *this;
+}
+
+BOOLEAN
+EFI_VARSTORE_INFO::operator == (
+ IN EFI_VARSTORE_INFO *Info
+ )
+{
+ if ((mVarStoreId == Info->mVarStoreId) &&
+ (mInfo.mVarName == Info->mInfo.mVarName) &&
+ (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
+ (mVarType == Info->mVarType) &&
+ (mVarTotalSize == Info->mVarTotalSize) &&
+ (mIsBitVar == Info->mIsBitVar)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
+ IN EFI_VARSTORE_INFO *Info
+ )
+{
+ mVarStoreInfo.mVarType = Info->mVarType;
+ mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;
+ mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;
+ mVarStoreInfo.mVarStoreId = Info->mVarStoreId;
+ mNext = NULL;
+}
+
+BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
+{
+ mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;
+ mVarStoreInfo.mVarTotalSize = 0;
+ mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
+ mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;
+ mNext = NULL;
+}
+
+static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
+
+EFI_QUESTION_ID
+CVfrQuestionDB::GetFreeQuestionId (
+ VOID
+ )
+{
+ UINT32 Index, Mask, Offset;
+
+ for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
+ if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
+ break;
+ }
+ }
+
+ if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {
+ return EFI_QUESTION_ID_INVALID;
+ }
+
+ for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
+ if ((mFreeQIdBitMap[Index] & Mask) == 0) {
+ mFreeQIdBitMap[Index] |= Mask;
+ return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
+ }
+ }
+
+ return EFI_QUESTION_ID_INVALID;
+}
+
+BOOLEAN
+CVfrQuestionDB::ChekQuestionIdFree (
+ IN EFI_QUESTION_ID QId
+ )
+{
+ UINT32 Index = (QId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
+
+ return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
+}
+
+VOID
+CVfrQuestionDB::MarkQuestionIdUsed (
+ IN EFI_QUESTION_ID QId
+ )
+{
+ UINT32 Index = (QId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
+
+ mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
+}
+
+VOID
+CVfrQuestionDB::MarkQuestionIdUnused (
+ IN EFI_QUESTION_ID QId
+ )
+{
+ UINT32 Index = (QId / EFI_BITS_PER_UINT32);
+ UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
+
+ mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
+}
+
+SVfrQuestionNode::SVfrQuestionNode (
+ IN CHAR8 *Name,
+ IN CHAR8 *VarIdStr,
+ IN UINT32 BitMask
+ )
+{
+ mName = NULL;
+ mVarIdStr = NULL;
+ mQuestionId = EFI_QUESTION_ID_INVALID;
+ mBitMask = BitMask;
+ mNext = NULL;
+ mQtype = QUESTION_NORMAL;
+
+ if (Name == NULL) {
+ mName = new CHAR8[strlen ("$DEFAULT") + 1];
+ strcpy (mName, "$DEFAULT");
+ } else {
+ mName = new CHAR8[strlen (Name) + 1];
+ strcpy (mName, Name);
+ }
+
+ if (VarIdStr != NULL) {
+ mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
+ strcpy (mVarIdStr, VarIdStr);
+ } else {
+ mVarIdStr = new CHAR8[strlen ("$") + 1];
+ strcpy (mVarIdStr, "$");
+ }
+}
+
+SVfrQuestionNode::~SVfrQuestionNode (
+ VOID
+ )
+{
+ if (mName != NULL) {
+ delete[] mName;
+ }
+
+ if (mVarIdStr != NULL) {
+ delete[] mVarIdStr;
+ }
+}
+
+CVfrQuestionDB::CVfrQuestionDB ()
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
+ mFreeQIdBitMap[Index] = 0;
+ }
+
+ // Question ID 0 is reserved.
+ mFreeQIdBitMap[0] = 0x80000000;
+ mQuestionList = NULL;
+}
+
+CVfrQuestionDB::~CVfrQuestionDB ()
+{
+ SVfrQuestionNode *pNode;
+
+ while (mQuestionList != NULL) {
+ pNode = mQuestionList;
+ mQuestionList = mQuestionList->mNext;
+ delete pNode;
+ }
+}
+
+//
+// Reset to init state
+//
+VOID
+CVfrQuestionDB::ResetInit(
+ IN VOID
+ )
+{
+ UINT32 Index;
+ SVfrQuestionNode *pNode;
+
+ while (mQuestionList != NULL) {
+ pNode = mQuestionList;
+ mQuestionList = mQuestionList->mNext;
+ delete pNode;
+ }
+
+ for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
+ mFreeQIdBitMap[Index] = 0;
+ }
+
+ // Question ID 0 is reserved.
+ mFreeQIdBitMap[0] = 0x80000000;
+ mQuestionList = NULL;
+}
+
+VOID
+CVfrQuestionDB::PrintAllQuestion (
+ VOID
+ )
+{
+ SVfrQuestionNode *pNode = NULL;
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::RegisterQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *VarIdStr,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode = NULL;
+
+ if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
+ return VFR_RETURN_OUT_FOR_RESOURCES;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ delete pNode;
+ return VFR_RETURN_QUESTIONID_REDEFINED;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+ pNode->mQuestionId = QuestionId;
+
+ pNode->mNext = mQuestionList;
+ mQuestionList = pNode;
+
+ gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrQuestionDB::RegisterOldDateQuestion (
+ IN CHAR8 *YearVarId,
+ IN CHAR8 *MonthVarId,
+ IN CHAR8 *DayVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Index;
+
+ if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
+ return;
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mQtype = QUESTION_DATE;
+ pNode[1]->mQtype = QUESTION_DATE;
+ pNode[2]->mQtype = QUESTION_DATE;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+ }
+ QuestionId = EFI_QUESTION_ID_INVALID;
+}
+
+VOID
+CVfrQuestionDB::RegisterNewDateQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *BaseVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Len;
+ CHAR8 *VarIdStr[3] = {NULL, };
+ CHAR8 Index;
+
+ if (BaseVarId == NULL && Name == NULL) {
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+ return;
+ }
+
+ if (BaseVarId != NULL) {
+ Len = strlen (BaseVarId);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], BaseVarId);
+ strcat (VarIdStr[0], ".Year");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], BaseVarId);
+ strcat (VarIdStr[1], ".Month");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], BaseVarId);
+ strcat (VarIdStr[2], ".Day");
+ }
+ } else {
+ Len = strlen (Name);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], Name);
+ strcat (VarIdStr[0], ".Year");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], Name);
+ strcat (VarIdStr[1], ".Month");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], Name);
+ strcat (VarIdStr[2], ".Day");
+ }
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mQtype = QUESTION_DATE;
+ pNode[1]->mQtype = QUESTION_DATE;
+ pNode[2]->mQtype = QUESTION_DATE;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ for (Index = 0; Index < 3; Index++) {
+ if (VarIdStr[Index] != NULL) {
+ delete[] VarIdStr[Index];
+ VarIdStr[Index] = NULL;
+ }
+ }
+
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+
+ if (VarIdStr[Index] != NULL) {
+ delete[] VarIdStr [Index];
+ VarIdStr [Index] = NULL;
+ }
+ }
+}
+
+VOID
+CVfrQuestionDB::RegisterOldTimeQuestion (
+ IN CHAR8 *HourVarId,
+ IN CHAR8 *MinuteVarId,
+ IN CHAR8 *SecondVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Index;
+
+ if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
+ return;
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mQtype = QUESTION_TIME;
+ pNode[1]->mQtype = QUESTION_TIME;
+ pNode[2]->mQtype = QUESTION_TIME;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+ }
+ QuestionId = EFI_QUESTION_ID_INVALID;
+}
+
+VOID
+CVfrQuestionDB::RegisterNewTimeQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *BaseVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[3] = {NULL, };
+ UINT32 Len;
+ CHAR8 *VarIdStr[3] = {NULL, };
+ CHAR8 Index;
+
+ if (BaseVarId == NULL && Name == NULL) {
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+ return;
+ }
+
+ if (BaseVarId != NULL) {
+ Len = strlen (BaseVarId);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], BaseVarId);
+ strcat (VarIdStr[0], ".Hour");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], BaseVarId);
+ strcat (VarIdStr[1], ".Minute");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], BaseVarId);
+ strcat (VarIdStr[2], ".Second");
+ }
+ } else {
+ Len = strlen (Name);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], Name);
+ strcat (VarIdStr[0], ".Hour");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], Name);
+ strcat (VarIdStr[1], ".Minute");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], Name);
+ strcat (VarIdStr[2], ".Second");
+ }
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[0]->mQtype = QUESTION_TIME;
+ pNode[1]->mQtype = QUESTION_TIME;
+ pNode[2]->mQtype = QUESTION_TIME;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ for (Index = 0; Index < 3; Index++) {
+ if (VarIdStr[Index] != NULL) {
+ delete[] VarIdStr[Index];
+ VarIdStr[Index] = NULL;
+ }
+ }
+
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+Err:
+ for (Index = 0; Index < 3; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+
+ if (VarIdStr[Index] != NULL) {
+ delete[] VarIdStr[Index];
+ VarIdStr[Index] = NULL;
+ }
+ }
+}
+
+VOID
+CVfrQuestionDB::RegisterRefQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *BaseVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[4] = {NULL, };
+ UINT32 Len;
+ CHAR8 *VarIdStr[4] = {NULL, };
+ CHAR8 Index;
+
+ if (BaseVarId == NULL && Name == NULL) {
+ return;
+ }
+
+ if (BaseVarId != NULL) {
+ Len = strlen (BaseVarId);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], BaseVarId);
+ strcat (VarIdStr[0], ".QuestionId");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], BaseVarId);
+ strcat (VarIdStr[1], ".FormId");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], BaseVarId);
+ strcat (VarIdStr[2], ".FormSetGuid");
+ }
+ VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
+ if (VarIdStr[3] != NULL) {
+ strcpy (VarIdStr[3], BaseVarId);
+ strcat (VarIdStr[3], ".DevicePath");
+ }
+ } else {
+ Len = strlen (Name);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], Name);
+ strcat (VarIdStr[0], ".QuestionId");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], Name);
+ strcat (VarIdStr[1], ".FormId");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], Name);
+ strcat (VarIdStr[2], ".FormSetGuid");
+ }
+ VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
+ if (VarIdStr[3] != NULL) {
+ strcpy (VarIdStr[3], Name);
+ strcat (VarIdStr[3], ".DevicePath");
+ }
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
+ goto Err;
+ }
+ if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[3]->mQuestionId = QuestionId;
+ pNode[0]->mQtype = QUESTION_REF;
+ pNode[1]->mQtype = QUESTION_REF;
+ pNode[2]->mQtype = QUESTION_REF;
+ pNode[3]->mQtype = QUESTION_REF;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = pNode[3];
+ pNode[3]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+ Err:
+ for (Index = 0; Index < 4; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+
+ if (VarIdStr[Index] != NULL) {
+ delete VarIdStr[Index];
+ }
+ }
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::UpdateQuestionId (
+ IN EFI_QUESTION_ID QId,
+ IN EFI_QUESTION_ID NewQId
+ )
+{
+ SVfrQuestionNode *pNode = NULL;
+
+ if (QId == NewQId) {
+ // don't update
+ return VFR_RETURN_SUCCESS;
+ }
+
+ if (ChekQuestionIdFree (NewQId) == FALSE) {
+ return VFR_RETURN_REDEFINED;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mQuestionId == QId) {
+ break;
+ }
+ }
+
+ if (pNode == NULL) {
+ return VFR_RETURN_UNDEFINED;
+ }
+
+ MarkQuestionIdUnused (QId);
+ pNode->mQuestionId = NewQId;
+ MarkQuestionIdUsed (NewQId);
+
+ gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
+
+ return VFR_RETURN_SUCCESS;
+}
+
+VOID
+CVfrQuestionDB::GetQuestionId (
+ IN CHAR8 *Name,
+ IN CHAR8 *VarIdStr,
+ OUT EFI_QUESTION_ID &QuestionId,
+ OUT UINT32 &BitMask,
+ OUT EFI_QUESION_TYPE *QType
+ )
+{
+ SVfrQuestionNode *pNode;
+
+ QuestionId = EFI_QUESTION_ID_INVALID;
+ BitMask = 0x00000000;
+ if (QType != NULL) {
+ *QType = QUESTION_NORMAL;
+ }
+
+ if ((Name == NULL) && (VarIdStr == NULL)) {
+ return ;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (Name != NULL) {
+ if (strcmp (pNode->mName, Name) != 0) {
+ continue;
+ }
+ }
+
+ if (VarIdStr != NULL) {
+ if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
+ continue;
+ }
+ }
+
+ QuestionId = pNode->mQuestionId;
+ BitMask = pNode->mBitMask;
+ if (QType != NULL) {
+ *QType = pNode->mQtype;
+ }
+ break;
+ }
+
+ return ;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::FindQuestion (
+ IN EFI_QUESTION_ID QuestionId
+ )
+{
+ SVfrQuestionNode *pNode;
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ return VFR_RETURN_INVALID_PARAMETER;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (pNode->mQuestionId == QuestionId) {
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+EFI_VFR_RETURN_CODE
+CVfrQuestionDB::FindQuestion (
+ IN CHAR8 *Name
+ )
+{
+ SVfrQuestionNode *pNode;
+
+ if (Name == NULL) {
+ return VFR_RETURN_FATAL_ERROR;
+ }
+
+ for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
+ if (strcmp (pNode->mName, Name) == 0) {
+ return VFR_RETURN_SUCCESS;
+ }
+ }
+
+ return VFR_RETURN_UNDEFINED;
+}
+
+CVfrStringDB::CVfrStringDB ()
+{
+ mStringFileName = NULL;
+}
+
+CVfrStringDB::~CVfrStringDB ()
+{
+ if (mStringFileName != NULL) {
+ delete[] mStringFileName;
+ }
+ mStringFileName = NULL;
+}
+
+
+VOID
+CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
+{
+ UINT32 FileLen = 0;
+
+ if (StringFileName == NULL) {
+ return;
+ }
+
+ if (mStringFileName != NULL) {
+ delete[] mStringFileName;
+ }
+
+ FileLen = strlen (StringFileName) + 1;
+ mStringFileName = new CHAR8[FileLen];
+ if (mStringFileName == NULL) {
+ return;
+ }
+
+ strcpy (mStringFileName, StringFileName);
+ mStringFileName[FileLen - 1] = '\0';
+}
+
+
+/**
+ Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
+ from a set of supported languages.
+
+ @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
+ contains a set of language codes.
+ @param[in] Language A variable that contains pointers to Null-terminated
+ ASCII strings that contain one language codes.
+
+ @retval FALSE The best matching language could not be found in SupportedLanguages.
+ @retval TRUE The best matching language could be found in SupportedLanguages.
+
+**/
+BOOLEAN
+CVfrStringDB::GetBestLanguage (
+ IN CONST CHAR8 *SupportedLanguages,
+ IN CHAR8 *Language
+ )
+{
+ UINTN CompareLength;
+ UINTN LanguageLength;
+ CONST CHAR8 *Supported;
+
+ if (SupportedLanguages == NULL || Language == NULL){
+ return FALSE;
+ }
+
+ //
+ // Determine the length of the first RFC 4646 language code in Language
+ //
+ for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
+
+ //
+ // Trim back the length of Language used until it is empty
+ //
+ while (LanguageLength > 0) {
+ //
+ // Loop through all language codes in SupportedLanguages
+ //
+ for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
+ //
+ // Skip ';' characters in Supported
+ //
+ for (; *Supported != '\0' && *Supported == ';'; Supported++);
+ //
+ // Determine the length of the next language code in Supported
+ //
+ for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
+ //
+ // If Language is longer than the Supported, then skip to the next language
+ //
+ if (LanguageLength > CompareLength) {
+ continue;
+ }
+
+ //
+ // See if the first LanguageLength characters in Supported match Language
+ //
+ if (strncmp (Supported, Language, LanguageLength) == 0) {
+ return TRUE;
+ }
+ }
+
+ //
+ // Trim Language from the right to the next '-' character
+ //
+ for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
+ }
+
+ //
+ // No matches were found
+ //
+ return FALSE;
+}
+
+
+CHAR8 *
+CVfrStringDB::GetVarStoreNameFormStringId (
+ IN EFI_STRING_ID StringId
+ )
+{
+ FILE *pInFile = NULL;
+ UINT32 NameOffset;
+ INT32 Length;
+ UINT8 *StringPtr;
+ CHAR8 *StringName;
+ CHAR16 *UnicodeString;
+ CHAR8 *VarStoreName = NULL;
+ CHAR8 *DestTmp;
+ UINT8 *Current;
+ EFI_STATUS Status;
+ CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
+ UINT8 BlockType;
+ EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
+
+ if (mStringFileName == NULL) {
+ return NULL;
+ }
+
+ if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
+ return NULL;
+ }
+
+ //
+ // Get file length.
+ //
+ fseek (pInFile, 0, SEEK_END);
+ Length = ftell (pInFile);
+ fseek (pInFile, 0, SEEK_SET);
+
+ //
+ // Get file data.
+ //
+ StringPtr = new UINT8[Length];
+ if (StringPtr == NULL) {
+ fclose (pInFile);
+ return NULL;
+ }
+ fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
+ fclose (pInFile);
+
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
+ //
+ // Check the String package.
+ //
+ if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
+ delete[] StringPtr;
+ return NULL;
+ }
+
+ //
+ // Search the language, get best language base on RFC 4647 matching algorithm.
+ //
+ Current = StringPtr;
+ while (!GetBestLanguage ("en", PkgHeader->Language)) {
+ Current += PkgHeader->Header.Length;
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
+ //
+ // If can't find string package base on language, just return the first string package.
+ //
+ if (Current - StringPtr >= Length) {
+ Current = StringPtr;
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
+ break;
+ }
+ }
+
+ Current += PkgHeader->HdrSize;
+ //
+ // Find the string block according the stringId.
+ //
+ Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
+ if (Status != EFI_SUCCESS) {
+ delete[] StringPtr;
+ return NULL;
+ }
+
+ //
+ // Get varstore name according the string type.
+ //
+ switch (BlockType) {
+ case EFI_HII_SIBT_STRING_SCSU:
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ StringName = (CHAR8*)(Current + NameOffset);
+ VarStoreName = new CHAR8[strlen(StringName) + 1];
+ strcpy (VarStoreName, StringName);
+ break;
+ case EFI_HII_SIBT_STRING_UCS2:
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ UnicodeString = (CHAR16*)(Current + NameOffset);
+ Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
+ DestTmp = new CHAR8[Length / 2 + 1];
+ VarStoreName = DestTmp;
+ while (*UnicodeString != '\0') {
+ *(DestTmp++) = (CHAR8) *(UnicodeString++);
+ }
+ *DestTmp = '\0';
+ break;
+ default:
+ break;
+ }
+
+ delete[] StringPtr;
+
+ return VarStoreName;
+}
+
+EFI_STATUS
+CVfrStringDB::FindStringBlock (
+ IN UINT8 *StringData,
+ IN EFI_STRING_ID StringId,
+ OUT UINT32 *StringTextOffset,
+ OUT UINT8 *BlockType
+ )
+{
+ UINT8 *BlockHdr;
+ EFI_STRING_ID CurrentStringId;
+ UINT32 BlockSize;
+ UINT32 Index;
+ UINT8 *StringTextPtr;
+ UINT32 Offset;
+ UINT16 StringCount;
+ UINT16 SkipCount;
+ UINT8 Length8;
+ EFI_HII_SIBT_EXT2_BLOCK Ext2;
+ UINT32 Length32;
+ UINT32 StringSize;
+
+ CurrentStringId = 1;
+
+ //
+ // Parse the string blocks to get the string text and font.
+ //
+ BlockHdr = StringData;
+ BlockSize = 0;
+ Offset = 0;
+ while (*BlockHdr != EFI_HII_SIBT_END) {
+ switch (*BlockHdr) {
+ case EFI_HII_SIBT_STRING_SCSU:
+ Offset = sizeof (EFI_HII_STRING_BLOCK);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
+ BlockSize += StringTextPtr - BlockHdr;
+
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ memcpy (
+ &StringCount,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT16)
+ );
+ StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
+ BlockSize += StringTextPtr - BlockHdr;
+
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_STRING_UCS2:
+ Offset = sizeof (EFI_HII_STRING_BLOCK);
+ StringTextPtr = BlockHdr + Offset;
+ //
+ // Use StringSize to store the size of the specified string, including the NULL
+ // terminator.
+ //
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += Offset + StringSize;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ //
+ // Use StrSize to store the size of the specified string, including the NULL
+ // terminator.
+ //
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += Offset + StringSize;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset;
+ memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ for (Index = 0; Index < StringCount; Index++) {
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += StringSize;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + StringSize;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset;
+ memcpy (
+ &StringCount,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT16)
+ );
+ for (Index = 0; Index < StringCount; Index++) {
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += StringSize;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + StringSize;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_DUPLICATE:
+ if (CurrentStringId == StringId) {
+ //
+ // Incoming StringId is an id of a duplicate string block.
+ // Update the StringId to be the previous string block.
+ // Go back to the header of string block to search.
+ //
+ memcpy (
+ &StringId,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
+ sizeof (EFI_STRING_ID)
+ );
+ CurrentStringId = 1;
+ BlockSize = 0;
+ } else {
+ BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_SKIP1:
+ SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
+ CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
+ break;
+
+ case EFI_HII_SIBT_SKIP2:
+ memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
+ break;
+
+ case EFI_HII_SIBT_EXT1:
+ memcpy (
+ &Length8,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT8)
+ );
+ BlockSize += Length8;
+ break;
+
+ case EFI_HII_SIBT_EXT2:
+ memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
+ BlockSize += Ext2.Length;
+ break;
+
+ case EFI_HII_SIBT_EXT4:
+ memcpy (
+ &Length32,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT32)
+ );
+
+ BlockSize += Length32;
+ break;
+
+ default:
+ break;
+ }
+
+ if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
+ *StringTextOffset = BlockHdr - StringData + Offset;
+ *BlockType = *BlockHdr;
+
+ if (StringId == CurrentStringId - 1) {
+ //
+ // if only one skip item, return EFI_NOT_FOUND.
+ //
+ if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_SUCCESS;
+ }
+ }
+
+ if (StringId < CurrentStringId - 1) {
+ return EFI_NOT_FOUND;
+ }
+ }
+ BlockHdr = StringData + BlockSize;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+UINT32
+CVfrStringDB::GetUnicodeStringTextSize (
+ IN UINT8 *StringSrc
+ )
+{
+ UINT32 StringSize;
+ CHAR16 *StringPtr;
+
+ StringSize = sizeof (CHAR16);
+ StringPtr = (UINT16*)StringSrc;
+ while (*StringPtr++ != L'\0') {
+ StringSize += sizeof (CHAR16);
+ }
+
+ return StringSize;
+}
+
+CVfrVarDataTypeDB gCVfrVarDataTypeDB;
+CVfrDefaultStore gCVfrDefaultStore;
+CVfrDataStorage gCVfrDataStorage;
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
new file mode 100644
index 00000000..bb91653f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
@@ -0,0 +1,538 @@
+/** @file
+
+ Vfr common library functions.
+
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _VFRUTILITYLIB_H_
+#define _VFRUTILITYLIB_H_
+
+#include "string.h"
+#include "Common/UefiBaseTypes.h"
+#include "EfiVfr.h"
+#include "VfrError.h"
+
+static EFI_GUID gEdkiiIfrBitVarGuid = EDKII_IFR_BIT_VARSTORE_GUID;
+
+#define MAX_BIT_WIDTH 32
+#define MAX_NAME_LEN 64
+#define MAX_STRING_LEN 0x100
+#define DEFAULT_ALIGN 1
+#define DEFAULT_PACK_ALIGN 0x8
+#define DEFAULT_NAME_TABLE_ITEMS 1024
+
+#define EFI_BITS_SHIFT_PER_UINT32 0x5
+#define EFI_BITS_PER_UINT32 (1 << EFI_BITS_SHIFT_PER_UINT32)
+
+#define BUFFER_SAFE_FREE(Buf) do { if ((Buf) != NULL) { delete (Buf); } } while (0);
+#define ARRAY_SAFE_FREE(Buf) do { if ((Buf) != NULL) { delete[] (Buf); } } while (0);
+
+
+class CVfrBinaryOutput {
+public:
+ virtual VOID WriteLine (IN FILE *, IN UINT32, IN CONST CHAR8 *, IN CHAR8 *, IN UINT32);
+ virtual VOID WriteEnd (IN FILE *, IN UINT32, IN CONST CHAR8 *, IN CHAR8 *, IN UINT32);
+};
+
+UINT32
+_STR2U32 (
+ IN CHAR8 *Str
+ );
+
+struct SConfigInfo {
+ UINT16 mOffset;
+ UINT16 mWidth;
+ UINT8 *mValue;
+ SConfigInfo *mNext;
+
+ SConfigInfo (IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE);
+ ~SConfigInfo (VOID);
+
+private:
+ SConfigInfo (IN CONST SConfigInfo&); // Prevent copy-construction
+ SConfigInfo& operator= (IN CONST SConfigInfo&); // Prevent assignment
+};
+
+struct SConfigItem {
+ CHAR8 *mName; // varstore name
+ EFI_GUID *mGuid; // varstore guid, varstore name + guid deside one varstore
+ CHAR8 *mId; // default ID
+ SConfigInfo *mInfoStrList; // list of Offset/Value in the varstore
+ SConfigItem *mNext;
+
+public:
+ SConfigItem (IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *);
+ SConfigItem (IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *, IN UINT8, IN UINT16, IN UINT16, IN EFI_IFR_TYPE_VALUE);
+ virtual ~SConfigItem ();
+
+private:
+ SConfigItem (IN CONST SConfigItem&); // Prevent copy-construction
+ SConfigItem& operator= (IN CONST SConfigItem&); // Prevent assignment
+};
+
+class CVfrBufferConfig {
+private:
+ SConfigItem *mItemListHead;
+ SConfigItem *mItemListTail;
+ SConfigItem *mItemListPos;
+
+public:
+ CVfrBufferConfig (VOID);
+ virtual ~CVfrBufferConfig (VOID);
+
+ virtual UINT8 Register (IN CHAR8 *, IN EFI_GUID *,IN CHAR8 *Info = NULL);
+ virtual VOID Open (VOID);
+ virtual BOOLEAN Eof(VOID);
+ virtual UINT8 Select (IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *Info = NULL);
+ virtual UINT8 Write (IN CONST CHAR8, IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *, IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE);
+#if 0
+ virtual UINT8 Read (OUT CHAR8 **, OUT CHAR8 **, OUT CHAR8 **, OUT CHAR8 **, OUT CHAR8 **);
+#endif
+ virtual VOID Close (VOID);
+ virtual VOID OutputCFile (IN FILE *, IN CHAR8 *);
+
+private:
+ CVfrBufferConfig (IN CONST CVfrBufferConfig&); // Prevent copy-construction
+ CVfrBufferConfig& operator= (IN CONST CVfrBufferConfig&); // Prevent assignment
+};
+
+extern CVfrBufferConfig gCVfrBufferConfig;
+
+#define ALIGN_STUFF(Size, Align) ((Align) - (Size) % (Align))
+#define INVALID_ARRAY_INDEX 0xFFFFFFFF
+
+struct SVfrDataType;
+
+struct SVfrDataField {
+ CHAR8 mFieldName[MAX_NAME_LEN];
+ SVfrDataType *mFieldType;
+ UINT32 mOffset;
+ UINT32 mArrayNum;
+ BOOLEAN mIsBitField;
+ UINT8 mBitWidth;
+ UINT32 mBitOffset;
+ SVfrDataField *mNext;
+};
+
+struct SVfrDataType {
+ CHAR8 mTypeName[MAX_NAME_LEN];
+ UINT8 mType;
+ UINT32 mAlign;
+ UINT32 mTotalSize;
+ BOOLEAN mHasBitField;
+ SVfrDataField *mMembers;
+ SVfrDataType *mNext;
+};
+
+#define VFR_PACK_ASSIGN 0x01
+#define VFR_PACK_SHOW 0x02
+#define VFR_PACK_PUSH 0x04
+#define VFR_PACK_POP 0x08
+
+#define PACKSTACK_MAX_SIZE 0x400
+
+struct SVfrPackStackNode {
+ CHAR8 *mIdentifier;
+ UINT32 mNumber;
+ SVfrPackStackNode *mNext;
+
+ SVfrPackStackNode (IN CHAR8 *Identifier, IN UINT32 Number) {
+ mIdentifier = NULL;
+ mNumber = Number;
+ mNext = NULL;
+
+ if (Identifier != NULL) {
+ mIdentifier = new CHAR8[strlen (Identifier) + 1];
+ strcpy (mIdentifier, Identifier);
+ }
+ }
+
+ ~SVfrPackStackNode (VOID) {
+ if (mIdentifier != NULL) {
+ delete[] mIdentifier;
+ }
+ mNext = NULL;
+ }
+
+ bool Match (IN CHAR8 *Identifier) {
+ if (Identifier == NULL) {
+ return TRUE;
+ } else if (mIdentifier == NULL) {
+ return FALSE;
+ } else if (strcmp (Identifier, mIdentifier) == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+
+private:
+ SVfrPackStackNode (IN CONST SVfrPackStackNode&); // Prevent copy-construction
+ SVfrPackStackNode& operator= (IN CONST SVfrPackStackNode&); // Prevent assignment
+};
+
+class CVfrVarDataTypeDB {
+private:
+ UINT32 mPackAlign;
+ SVfrPackStackNode *mPackStack;
+
+public:
+ EFI_VFR_RETURN_CODE Pack (IN UINT32, IN UINT8, IN CHAR8 *Identifier = NULL, IN UINT32 Number = DEFAULT_PACK_ALIGN);
+
+private:
+ SVfrDataType *mDataTypeList;
+
+ SVfrDataType *mNewDataType;
+ SVfrDataType *mCurrDataType;
+ SVfrDataField *mCurrDataField;
+
+ VOID InternalTypesListInit (VOID);
+ VOID RegisterNewType (IN SVfrDataType *);
+
+ EFI_VFR_RETURN_CODE ExtractStructTypeName (IN CHAR8 *&, OUT CHAR8 *);
+ EFI_VFR_RETURN_CODE GetTypeField (IN CONST CHAR8 *, IN SVfrDataType *, IN SVfrDataField *&);
+ EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &, IN BOOLEAN);
+ UINT8 GetFieldWidth (IN SVfrDataField *);
+ UINT32 GetFieldSize (IN SVfrDataField *, IN UINT32, IN BOOLEAN);
+
+public:
+ CVfrVarDataTypeDB (VOID);
+ ~CVfrVarDataTypeDB (VOID);
+
+ VOID DeclareDataTypeBegin (VOID);
+ EFI_VFR_RETURN_CODE SetNewTypeName (IN CHAR8 *);
+ EFI_VFR_RETURN_CODE DataTypeAddField (IN CHAR8 *, IN CHAR8 *, IN UINT32, IN BOOLEAN);
+ EFI_VFR_RETURN_CODE DataTypeAddBitField (IN CHAR8 *, IN CHAR8 *, IN UINT32, IN BOOLEAN);
+ VOID DeclareDataTypeEnd (VOID);
+
+ EFI_VFR_RETURN_CODE GetDataType (IN CHAR8 *, OUT SVfrDataType **);
+ EFI_VFR_RETURN_CODE GetDataTypeSize (IN CHAR8 *, OUT UINT32 *);
+ EFI_VFR_RETURN_CODE GetDataTypeSize (IN UINT8, OUT UINT32 *);
+ EFI_VFR_RETURN_CODE GetDataFieldInfo (IN CHAR8 *, OUT UINT16 &, OUT UINT8 &, OUT UINT32 &, OUT BOOLEAN &);
+
+ EFI_VFR_RETURN_CODE GetUserDefinedTypeNameList (OUT CHAR8 ***, OUT UINT32 *);
+ EFI_VFR_RETURN_CODE ExtractFieldNameAndArrary (IN CHAR8 *&, OUT CHAR8 *, OUT UINT32 &);
+ BOOLEAN DataTypeHasBitField (IN CHAR8 *);
+ BOOLEAN IsThisBitField (IN CHAR8 *);
+
+ BOOLEAN IsTypeNameDefined (IN CHAR8 *);
+
+ VOID Dump(IN FILE *);
+ //
+ // First the declared
+ //
+ CHAR8 *mFirstNewDataTypeName;
+#ifdef CVFR_VARDATATYPEDB_DEBUG
+ VOID ParserDB ();
+#endif
+
+private:
+ CVfrVarDataTypeDB (IN CONST CVfrVarDataTypeDB&); // Prevent copy-construction
+ CVfrVarDataTypeDB& operator= (IN CONST CVfrVarDataTypeDB&); // Prevent assignment
+};
+
+extern CVfrVarDataTypeDB gCVfrVarDataTypeDB;
+
+typedef enum {
+ EFI_VFR_VARSTORE_INVALID,
+ EFI_VFR_VARSTORE_BUFFER,
+ EFI_VFR_VARSTORE_EFI,
+ EFI_VFR_VARSTORE_NAME,
+ EFI_VFR_VARSTORE_BUFFER_BITS
+} EFI_VFR_VARSTORE_TYPE;
+
+struct SVfrVarStorageNode {
+ EFI_GUID mGuid;
+ CHAR8 *mVarStoreName;
+ EFI_VARSTORE_ID mVarStoreId;
+ BOOLEAN mAssignedFlag; //Create varstore opcode
+ struct SVfrVarStorageNode *mNext;
+
+ EFI_VFR_VARSTORE_TYPE mVarStoreType;
+ union {
+ // EFI Variable
+ struct {
+ EFI_STRING_ID mEfiVarName;
+ UINT32 mEfiVarSize;
+ } mEfiVar;
+
+ // Buffer Storage
+ SVfrDataType *mDataType;
+
+ // NameValue Storage
+ struct {
+ EFI_STRING_ID *mNameTable;
+ UINT32 mTableSize;
+ } mNameSpace;
+ } mStorageInfo;
+
+public:
+ SVfrVarStorageNode (IN EFI_GUID *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN EFI_STRING_ID, IN UINT32, IN BOOLEAN Flag = TRUE);
+ SVfrVarStorageNode (IN EFI_GUID *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *,IN BOOLEAN, IN BOOLEAN Flag = TRUE);
+ SVfrVarStorageNode (IN CHAR8 *, IN EFI_VARSTORE_ID);
+ ~SVfrVarStorageNode (VOID);
+
+private:
+ SVfrVarStorageNode (IN CONST SVfrVarStorageNode&); // Prevent copy-construction
+ SVfrVarStorageNode& operator= (IN CONST SVfrVarStorageNode&); // Prevent assignment
+};
+
+struct EFI_VARSTORE_INFO {
+ EFI_VARSTORE_ID mVarStoreId;
+ union {
+ EFI_STRING_ID mVarName;
+ UINT16 mVarOffset;
+ } mInfo;
+ UINT8 mVarType;
+ UINT32 mVarTotalSize;
+ BOOLEAN mIsBitVar;
+
+ EFI_VARSTORE_INFO (VOID);
+ EFI_VARSTORE_INFO (IN EFI_VARSTORE_INFO &);
+ EFI_VARSTORE_INFO& operator=(IN CONST EFI_VARSTORE_INFO &);
+ BOOLEAN operator == (IN EFI_VARSTORE_INFO *);
+};
+
+struct BufferVarStoreFieldInfoNode {
+ EFI_VARSTORE_INFO mVarStoreInfo;
+ struct BufferVarStoreFieldInfoNode *mNext;
+
+ BufferVarStoreFieldInfoNode( IN EFI_VARSTORE_INFO *Info );
+ ~BufferVarStoreFieldInfoNode ();
+};
+
+#define EFI_VARSTORE_ID_MAX 0xFFFF
+#define EFI_FREE_VARSTORE_ID_BITMAP_SIZE ((EFI_VARSTORE_ID_MAX + 1) / EFI_BITS_PER_UINT32)
+
+class CVfrDataStorage {
+private:
+ UINT32 mFreeVarStoreIdBitMap[EFI_FREE_VARSTORE_ID_BITMAP_SIZE];
+
+ struct SVfrVarStorageNode *mBufferVarStoreList;
+ struct SVfrVarStorageNode *mEfiVarStoreList;
+ struct SVfrVarStorageNode *mNameVarStoreList;
+
+ struct SVfrVarStorageNode *mCurrVarStorageNode;
+ struct SVfrVarStorageNode *mNewVarStorageNode;
+ BufferVarStoreFieldInfoNode *mBufferFieldInfoListHead;
+ BufferVarStoreFieldInfoNode *mBufferFieldInfoListTail;
+
+private:
+
+ EFI_VARSTORE_ID GetFreeVarStoreId (EFI_VFR_VARSTORE_TYPE VarType = EFI_VFR_VARSTORE_BUFFER);
+ BOOLEAN ChekVarStoreIdFree (IN EFI_VARSTORE_ID);
+ VOID MarkVarStoreIdUsed (IN EFI_VARSTORE_ID);
+ VOID MarkVarStoreIdUnused (IN EFI_VARSTORE_ID);
+ EFI_VARSTORE_ID CheckGuidField (IN SVfrVarStorageNode *,
+ IN EFI_GUID *,
+ IN BOOLEAN *,
+ OUT EFI_VFR_RETURN_CODE *);
+
+public:
+ CVfrDataStorage ();
+ ~CVfrDataStorage ();
+
+ SVfrVarStorageNode * GetBufferVarStoreList () {
+ return mBufferVarStoreList;
+ }
+ SVfrVarStorageNode * GetEfiVarStoreList () {
+ return mEfiVarStoreList;
+ }
+ EFI_VFR_RETURN_CODE DeclareNameVarStoreBegin (CHAR8 *, EFI_VARSTORE_ID);
+ EFI_VFR_RETURN_CODE NameTableAddItem (EFI_STRING_ID);
+ EFI_VFR_RETURN_CODE DeclareNameVarStoreEnd (EFI_GUID *);
+
+ EFI_VFR_RETURN_CODE DeclareEfiVarStore (IN CHAR8 *, IN EFI_GUID *, IN EFI_STRING_ID, IN UINT32, IN BOOLEAN Flag = TRUE);
+
+ EFI_VFR_RETURN_CODE DeclareBufferVarStore (IN CHAR8 *, IN EFI_GUID *, IN CVfrVarDataTypeDB *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN BOOLEAN, IN BOOLEAN Flag = TRUE);
+
+ EFI_VFR_RETURN_CODE GetVarStoreId (IN CHAR8 *, OUT EFI_VARSTORE_ID *, IN EFI_GUID *VarGuid = NULL);
+ EFI_VFR_VARSTORE_TYPE GetVarStoreType (IN EFI_VARSTORE_ID);
+ EFI_GUID * GetVarStoreGuid (IN EFI_VARSTORE_ID);
+ EFI_VFR_RETURN_CODE GetVarStoreName (IN EFI_VARSTORE_ID, OUT CHAR8 **);
+ EFI_VFR_RETURN_CODE GetVarStoreByDataType (IN CHAR8 *, OUT SVfrVarStorageNode **, IN EFI_GUID *VarGuid = NULL);
+
+ EFI_VFR_RETURN_CODE GetBufferVarStoreDataTypeName (IN EFI_VARSTORE_ID, OUT CHAR8 **);
+ EFI_VFR_RETURN_CODE GetEfiVarStoreInfo (IN EFI_VARSTORE_INFO *);
+ EFI_VFR_RETURN_CODE GetNameVarStoreInfo (IN EFI_VARSTORE_INFO *, IN UINT32);
+ EFI_VFR_RETURN_CODE AddBufferVarStoreFieldInfo (IN EFI_VARSTORE_INFO *);
+ EFI_VFR_RETURN_CODE GetBufferVarStoreFieldInfo (IN OUT EFI_VARSTORE_INFO *);
+
+private:
+ CVfrDataStorage (IN CONST CVfrDataStorage&); // Prevent copy-construction
+ CVfrDataStorage& operator= (IN CONST CVfrDataStorage&); // Prevent assignment
+};
+
+extern CVfrDataStorage gCVfrDataStorage;
+
+#define EFI_QUESTION_ID_MAX 0xFFFF
+#define EFI_FREE_QUESTION_ID_BITMAP_SIZE ((EFI_QUESTION_ID_MAX + 1) / EFI_BITS_PER_UINT32)
+#define EFI_QUESTION_ID_INVALID 0x0
+
+#define DATE_YEAR_BITMASK 0x0000FFFF
+#define DATE_MONTH_BITMASK 0x00FF0000
+#define DATE_DAY_BITMASK 0xFF000000
+#define TIME_HOUR_BITMASK 0x000000FF
+#define TIME_MINUTE_BITMASK 0x0000FF00
+#define TIME_SECOND_BITMASK 0x00FF0000
+
+struct SVfrQuestionNode {
+ CHAR8 *mName;
+ CHAR8 *mVarIdStr;
+ EFI_QUESTION_ID mQuestionId;
+ UINT32 mBitMask;
+ SVfrQuestionNode *mNext;
+ EFI_QUESION_TYPE mQtype;
+
+ SVfrQuestionNode (IN CHAR8 *, IN CHAR8 *, IN UINT32 BitMask = 0);
+ ~SVfrQuestionNode ();
+
+private:
+ SVfrQuestionNode (IN CONST SVfrQuestionNode&); // Prevent copy-construction
+ SVfrQuestionNode& operator= (IN CONST SVfrQuestionNode&); // Prevent assignment
+};
+
+class CVfrQuestionDB {
+private:
+ SVfrQuestionNode *mQuestionList;
+ UINT32 mFreeQIdBitMap[EFI_FREE_QUESTION_ID_BITMAP_SIZE];
+
+private:
+ EFI_QUESTION_ID GetFreeQuestionId (VOID);
+ BOOLEAN ChekQuestionIdFree (IN EFI_QUESTION_ID);
+ VOID MarkQuestionIdUsed (IN EFI_QUESTION_ID);
+ VOID MarkQuestionIdUnused (IN EFI_QUESTION_ID);
+
+public:
+ CVfrQuestionDB ();
+ ~CVfrQuestionDB();
+
+ EFI_VFR_RETURN_CODE RegisterQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ VOID RegisterOldDateQuestion (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ VOID RegisterNewDateQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ VOID RegisterOldTimeQuestion (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ VOID RegisterNewTimeQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ VOID RegisterRefQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ EFI_VFR_RETURN_CODE UpdateQuestionId (IN EFI_QUESTION_ID, IN EFI_QUESTION_ID);
+ VOID GetQuestionId (IN CHAR8 *, IN CHAR8 *, OUT EFI_QUESTION_ID &, OUT UINT32 &, OUT EFI_QUESION_TYPE *QType = NULL);
+ EFI_VFR_RETURN_CODE FindQuestion (IN EFI_QUESTION_ID);
+ EFI_VFR_RETURN_CODE FindQuestion (IN CHAR8 *);
+ VOID PrintAllQuestion (IN VOID);
+ VOID ResetInit (IN VOID);
+
+private:
+ CVfrQuestionDB (IN CONST CVfrQuestionDB&); // Prevent copy-construction
+ CVfrQuestionDB& operator= (IN CONST CVfrQuestionDB&); // Prevent assignment
+};
+
+struct SVfrDefaultStoreNode {
+ EFI_IFR_DEFAULTSTORE *mObjBinAddr;
+ CHAR8 *mRefName;
+ EFI_STRING_ID mDefaultStoreNameId;
+ UINT16 mDefaultId;
+
+ SVfrDefaultStoreNode *mNext;
+
+ SVfrDefaultStoreNode (IN EFI_IFR_DEFAULTSTORE *, IN CHAR8 *, IN EFI_STRING_ID, IN UINT16);
+ ~SVfrDefaultStoreNode();
+
+private:
+ SVfrDefaultStoreNode (IN CONST SVfrDefaultStoreNode&); // Prevent copy-construction
+ SVfrDefaultStoreNode& operator= (IN CONST SVfrDefaultStoreNode&); // Prevent assignment
+};
+
+class CVfrDefaultStore {
+private:
+ SVfrDefaultStoreNode *mDefaultStoreList;
+
+public:
+ CVfrDefaultStore ();
+ ~CVfrDefaultStore ();
+
+ EFI_VFR_RETURN_CODE RegisterDefaultStore (IN CHAR8 *, IN CHAR8 *, IN EFI_STRING_ID, IN UINT16);
+ EFI_VFR_RETURN_CODE ReRegisterDefaultStoreById (IN UINT16, IN CHAR8 *, IN EFI_STRING_ID);
+ BOOLEAN DefaultIdRegistered (IN UINT16);
+ EFI_VFR_RETURN_CODE GetDefaultId (IN CHAR8 *, OUT UINT16 *);
+ EFI_VFR_RETURN_CODE BufferVarStoreAltConfigAdd (IN EFI_VARSTORE_ID, IN EFI_VARSTORE_INFO &, IN CHAR8 *, IN EFI_GUID *, IN UINT8, IN EFI_IFR_TYPE_VALUE);
+
+private:
+ CVfrDefaultStore (IN CONST CVfrDefaultStore&); // Prevent copy-construction
+ CVfrDefaultStore& operator= (IN CONST CVfrDefaultStore&); // Prevent assignment
+};
+
+extern CVfrDefaultStore gCVfrDefaultStore;
+
+#define EFI_RULE_ID_START 0x01
+#define EFI_RULE_ID_INVALID 0x00
+
+struct SVfrRuleNode {
+ UINT8 mRuleId;
+ CHAR8 *mRuleName;
+ SVfrRuleNode *mNext;
+
+ SVfrRuleNode(IN CHAR8 *, IN UINT8);
+ ~SVfrRuleNode();
+
+private:
+ SVfrRuleNode (IN CONST SVfrRuleNode&); // Prevent copy-construction
+ SVfrRuleNode& operator= (IN CONST SVfrRuleNode&); // Prevent assignment
+};
+
+class CVfrRulesDB {
+private:
+ SVfrRuleNode *mRuleList;
+ UINT8 mFreeRuleId;
+
+public:
+ CVfrRulesDB ();
+ ~CVfrRulesDB();
+
+ VOID RegisterRule (IN CHAR8 *);
+ UINT8 GetRuleId (IN CHAR8 *);
+
+private:
+ CVfrRulesDB (IN CONST CVfrRulesDB&); // Prevent copy-construction
+ CVfrRulesDB& operator= (IN CONST CVfrRulesDB&); // Prevent assignment
+};
+
+class CVfrStringDB {
+private:
+ CHAR8 *mStringFileName;
+
+ EFI_STATUS FindStringBlock (
+ IN UINT8 *StringData,
+ IN EFI_STRING_ID StringId,
+ OUT UINT32 *StringTextOffset,
+ OUT UINT8 *BlockType
+ );
+
+ UINT32 GetUnicodeStringTextSize (
+ IN UINT8 *StringSrc
+ );
+
+ BOOLEAN GetBestLanguage (
+ IN CONST CHAR8 *SupportedLanguages,
+ IN CHAR8 *Language
+ );
+
+public:
+ CVfrStringDB ();
+ ~CVfrStringDB ();
+
+ VOID SetStringFileName (
+ IN CHAR8 *StringFileName
+ );
+
+ CHAR8 * GetVarStoreNameFormStringId (
+ IN EFI_STRING_ID StringId
+ );
+
+private:
+ CVfrStringDB (IN CONST CVfrStringDB&); // Prevent copy-construction
+ CVfrStringDB& operator= (IN CONST CVfrStringDB&); // Prevent assignment
+};
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/GNUmakefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/GNUmakefile
new file mode 100644
index 00000000..8d6fa7bc
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/GNUmakefile
@@ -0,0 +1,17 @@
+## @file
+# GNU/Linux makefile for 'VolInfo' module build.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+MAKEROOT ?= ..
+
+APPNAME = VolInfo
+
+OBJECTS = VolInfo.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
+
+LIBS = -lCommon
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile
new file mode 100644
index 00000000..09611c6d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile
@@ -0,0 +1,16 @@
+## @file
+# Windows makefile for 'VolInfo' module build.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = VolInfo
+
+LIBS = $(LIB_PATH)\Common.lib
+
+OBJECTS = VolInfo.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile.kmk
new file mode 100644
index 00000000..2e2f8015
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/Makefile.kmk
@@ -0,0 +1,45 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-makefile for the EFI VolInfo build tool.
+#
+
+#
+# Copyright (C) 2013-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# The contents of this file may alternatively be used under the terms
+# of the Common Development and Distribution License Version 1.0
+# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+# in the VirtualBox distribution, in which case the provisions of the
+# CDDL are applicable instead of those of the GPL.
+#
+# You may elect to license modified versions of this file under the
+# terms and conditions of either the GPL or the CDDL or both.
+#
+# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+#
+
+SUB_DEPTH = ../../../../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+BLDPROGS += VolInfo
+VolInfo_TEMPLATE = VBoxEfiBldProg
+VolInfo_SOURCES = VolInfo.c
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.c b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.c
new file mode 100644
index 00000000..9f9d92f4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.c
@@ -0,0 +1,2440 @@
+/** @file
+The tool dumps the contents of a firmware volume
+
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#ifdef __GNUC__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+
+#include <FvLib.h>
+#include <Common/UefiBaseTypes.h>
+#include <Common/UefiCapsule.h>
+#include <Common/PiFirmwareFile.h>
+#include <Common/PiFirmwareVolume.h>
+#include <Guid/PiFirmwareFileSystem.h>
+#include <IndustryStandard/PeImage.h>
+#include <Protocol/GuidedSectionExtraction.h>
+
+#include "Compress.h"
+#include "Decompress.h"
+#include "VolInfo.h"
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "FirmwareVolumeBufferLib.h"
+#include "OsPath.h"
+#include "ParseGuidedSectionTools.h"
+#include "StringFuncs.h"
+#include "ParseInf.h"
+#include "PeCoffLib.h"
+
+#ifdef VBOX
+# include <iprt/cdefs.h>
+#endif
+/*
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+*/
+//
+// Utility global variables
+//
+
+EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
+
+#define UTILITY_MAJOR_VERSION 1
+#define UTILITY_MINOR_VERSION 0
+
+#define UTILITY_NAME "VolInfo"
+
+#define EFI_SECTION_ERROR EFIERR (100)
+
+#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable
+
+//
+// Structure to keep a list of guid-to-basenames
+//
+typedef struct _GUID_TO_BASENAME {
+ struct _GUID_TO_BASENAME *Next;
+ INT8 Guid[PRINTED_GUID_BUFFER_SIZE];
+ INT8 BaseName[MAX_BASENAME_LEN];
+} GUID_TO_BASENAME;
+
+static GUID_TO_BASENAME *mGuidBaseNameList = NULL;
+
+//
+// Store GUIDed Section guid->tool mapping
+//
+EFI_HANDLE mParsedGuidedSectionTools = NULL;
+
+CHAR8* mUtilityFilename = NULL;
+
+BOOLEAN EnableHash = FALSE;
+CHAR8 *OpenSslPath = NULL;
+
+EFI_STATUS
+ParseGuidBaseNameFile (
+ CHAR8 *FileName
+ );
+
+EFI_STATUS
+FreeGuidBaseNameList (
+ VOID
+ );
+
+EFI_STATUS
+PrintGuidName (
+ IN UINT8 *GuidStr
+ );
+
+EFI_STATUS
+ParseSection (
+ IN UINT8 *SectionBuffer,
+ IN UINT32 BufferLength
+ );
+
+EFI_STATUS
+DumpDepexSection (
+ IN UINT8 *Ptr,
+ IN UINT32 SectionLength
+ );
+
+STATIC
+EFI_STATUS
+ReadHeader (
+ IN FILE *InputFile,
+ OUT UINT32 *FvSize,
+ OUT BOOLEAN *ErasePolarity
+ );
+
+STATIC
+EFI_STATUS
+PrintFileInfo (
+ EFI_FIRMWARE_VOLUME_HEADER *FvImage,
+ EFI_FFS_FILE_HEADER *FileHeader,
+ BOOLEAN ErasePolarity
+ );
+
+static
+EFI_STATUS
+PrintFvInfo (
+ IN VOID *Fv,
+ IN BOOLEAN IsChildFv
+ );
+
+static
+VOID
+LoadGuidedSectionToolsTxt (
+ IN CHAR8* FirmwareVolumeFilename
+ );
+
+EFI_STATUS
+CombinePath (
+ IN CHAR8* DefaultPath,
+ IN CHAR8* AppendPath,
+ OUT CHAR8* NewPath
+);
+
+void
+Usage (
+ VOID
+ );
+
+UINT32
+UnicodeStrLen (
+ IN CHAR16 *String
+ )
+ /*++
+
+ Routine Description:
+
+ Returns the length of a null-terminated unicode string.
+
+ Arguments:
+
+ String - The pointer to a null-terminated unicode string.
+
+ Returns:
+
+ N/A
+
+ --*/
+{
+ UINT32 Length;
+
+ for (Length = 0; *String != L'\0'; String++, Length++) {
+ ;
+ }
+ return Length;
+}
+
+VOID
+Unicode2AsciiString (
+ IN CHAR16 *Source,
+ OUT CHAR8 *Destination
+ )
+ /*++
+
+ Routine Description:
+
+ Convert a null-terminated unicode string to a null-terminated ascii string.
+
+ Arguments:
+
+ Source - The pointer to the null-terminated input unicode string.
+ Destination - The pointer to the null-terminated output ascii string.
+
+ Returns:
+
+ N/A
+
+ --*/
+{
+ while (*Source != '\0') {
+ *(Destination++) = (CHAR8) *(Source++);
+ }
+ //
+ // End the ascii with a NULL.
+ //
+ *Destination = '\0';
+}
+
+int
+main (
+ int argc,
+ char *argv[]
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ argc - GC_TODO: add argument description
+ ] - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ FILE *InputFile;
+ int BytesRead;
+ EFI_FIRMWARE_VOLUME_HEADER *FvImage;
+ UINT32 FvSize;
+ EFI_STATUS Status;
+ int Offset;
+ BOOLEAN ErasePolarity;
+ UINT64 LogLevel;
+ CHAR8 *OpenSslEnv;
+ CHAR8 *OpenSslCommand;
+
+ SetUtilityName (UTILITY_NAME);
+ //
+ // Print utility header
+ //
+ printf ("%s Version %d.%d Build %s\n",
+ UTILITY_NAME,
+ UTILITY_MAJOR_VERSION,
+ UTILITY_MINOR_VERSION,
+ __BUILD_VERSION
+ );
+
+ if (argc == 1) {
+ Usage ();
+ return -1;
+ }
+
+ argc--;
+ argv++;
+ LogLevel = 0;
+ Offset = 0;
+
+ //
+ // Look for help options
+ //
+ if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) ||
+ (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {
+ Usage();
+ return STATUS_SUCCESS;
+ }
+ //
+ // Version has already be printed, so just return success
+ //
+ if (strcmp(argv[0], "--version") == 0) {
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // If they specified -x xref guid/basename cross-reference files, process it.
+ // This will print the basename beside each file guid. To use it, specify
+ // -x xref_filename to processdsc, then use xref_filename as a parameter
+ // here.
+ //
+ while (argc > 0) {
+ if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {
+ ParseGuidBaseNameFile (argv[1]);
+ printf("ParseGuidBaseNameFile: %s\n", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ if (strcmp(argv[0], "--offset") == 0) {
+ //
+ // Hex or decimal?
+ //
+ if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {
+ if (sscanf (argv[1], "%x", &Offset) != 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);
+ return GetUtilityStatus ();
+ }
+ } else {
+ if (sscanf (argv[1], "%d", &Offset) != 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);
+ return GetUtilityStatus ();
+ }
+ //
+ // See if they said something like "64K"
+ //
+ if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {
+ Offset *= 1024;
+ }
+ }
+
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ if ((stricmp (argv[0], "--hash") == 0)) {
+ if (EnableHash == TRUE) {
+ //
+ // --hash already given in the option, ignore this one
+ //
+ argc --;
+ argv ++;
+ continue;
+ }
+ EnableHash = TRUE;
+ OpenSslCommand = "openssl";
+ OpenSslEnv = getenv("OPENSSL_PATH");
+ if (OpenSslEnv == NULL) {
+ OpenSslPath = OpenSslCommand;
+ } else {
+ //
+ // We add quotes to the Openssl Path in case it has space characters
+ //
+ OpenSslPath = malloc(2+strlen(OpenSslEnv)+strlen(OpenSslCommand)+1);
+ if (OpenSslPath == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return GetUtilityStatus ();
+ }
+ CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath);
+ }
+ if (OpenSslPath == NULL){
+ Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);
+ return GetUtilityStatus ();
+ }
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
+ SetPrintLevel (VERBOSE_LOG_LEVEL);
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ SetPrintLevel (KEY_LOG_LEVEL);
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
+ Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ return -1;
+ }
+ if (LogLevel > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
+ return -1;
+ }
+ SetPrintLevel (LogLevel);
+ DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ mUtilityFilename = argv[0];
+ argc --;
+ argv ++;
+ }
+
+ //
+ // Open the file containing the FV
+ //
+ if (mUtilityFilename == NULL) {
+ Error (NULL, 0, 1001, "Missing option", "Input files are not specified");
+ return GetUtilityStatus ();
+ }
+ InputFile = fopen (LongFilePath (mUtilityFilename), "rb");
+ if (InputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);
+ return GetUtilityStatus ();
+ }
+ //
+ // Skip over pad bytes if specified. This is used if they prepend 0xff
+ // data to the FV image binary.
+ //
+ if (Offset != 0) {
+ fseek (InputFile, Offset, SEEK_SET);
+ }
+ //
+ // Determine size of FV
+ //
+ Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename);
+ fclose (InputFile);
+ return GetUtilityStatus ();
+ }
+ //
+ // Allocate a buffer for the FV image
+ //
+ FvImage = malloc (FvSize);
+ if (FvImage == NULL) {
+ Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
+ fclose (InputFile);
+ return GetUtilityStatus ();
+ }
+ //
+ // Seek to the start of the image, then read the entire FV to the buffer
+ //
+ fseek (InputFile, Offset, SEEK_SET);
+ BytesRead = fread (FvImage, 1, FvSize, InputFile);
+ fclose (InputFile);
+ if ((unsigned int) BytesRead != FvSize) {
+ Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename);
+ free (FvImage);
+ return GetUtilityStatus ();
+ }
+
+ LoadGuidedSectionToolsTxt (mUtilityFilename);
+
+ PrintFvInfo (FvImage, FALSE);
+
+ //
+ // Clean up
+ //
+ free (FvImage);
+ FreeGuidBaseNameList ();
+ return GetUtilityStatus ();
+}
+
+
+static
+EFI_STATUS
+PrintFvInfo (
+ IN VOID *Fv,
+ IN BOOLEAN IsChildFv
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ Fv - Firmware Volume to print information about
+ IsChildFv - Flag specifies whether the input FV is a child FV.
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN NumberOfFiles;
+ BOOLEAN ErasePolarity;
+ UINTN FvSize;
+ EFI_FFS_FILE_HEADER *CurrentFile;
+ UINTN Key;
+
+ Status = FvBufGetSize (Fv, &FvSize);
+
+ NumberOfFiles = 0;
+ ErasePolarity =
+ (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?
+ TRUE : FALSE;
+
+ //
+ // Get the first file
+ //
+ Key = 0;
+ Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
+ return GetUtilityStatus ();
+ }
+ //
+ // Display information about files found
+ //
+ while (CurrentFile != NULL) {
+ //
+ // Increment the number of files counter
+ //
+ NumberOfFiles++;
+
+ //
+ // Display info about this file
+ //
+ Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
+ return GetUtilityStatus ();
+ }
+ //
+ // Get the next file
+ //
+ Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
+ if (Status == EFI_NOT_FOUND) {
+ CurrentFile = NULL;
+ } else if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
+ return GetUtilityStatus ();
+ }
+ }
+
+ if (IsChildFv) {
+ printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);
+ } else {
+ printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT32
+GetOccupiedSize (
+ IN UINT32 ActualSize,
+ IN UINT32 Alignment
+ )
+/*++
+
+Routine Description:
+
+ This function returns the next larger size that meets the alignment
+ requirement specified.
+
+Arguments:
+
+ ActualSize The size.
+ Alignment The desired alignment.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_ABORTED The function encountered an error.
+
+--*/
+{
+ UINT32 OccupiedSize;
+
+ OccupiedSize = ActualSize;
+ while ((OccupiedSize & (Alignment - 1)) != 0) {
+ OccupiedSize++;
+ }
+
+ return OccupiedSize;
+}
+
+static
+CHAR8 *
+SectionNameToStr (
+ IN EFI_SECTION_TYPE Type
+ )
+/*++
+
+Routine Description:
+
+ Converts EFI Section names to Strings
+
+Arguments:
+
+ Type - The EFI Section type
+
+Returns:
+
+ CHAR8* - Pointer to the String containing the section name.
+
+--*/
+{
+ CHAR8 *SectionStr;
+ CHAR8 *SectionTypeStringTable[] = {
+ //
+ // 0X00
+ //
+ "EFI_SECTION_ALL",
+ //
+ // 0x01
+ //
+ "EFI_SECTION_COMPRESSION",
+ //
+ // 0x02
+ //
+ "EFI_SECTION_GUID_DEFINED",
+ //
+ // 0x03
+ //
+ "Unknown section type - Reserved 0x03",
+ //
+ // 0x04
+ //
+ "Unknown section type - Reserved 0x04",
+ //
+ // 0x05
+ //
+ "Unknown section type - Reserved 0x05",
+ //
+ // 0x06
+ //
+ "Unknown section type - Reserved 0x06",
+ //
+ // 0x07
+ //
+ "Unknown section type - Reserved 0x07",
+ //
+ // 0x08
+ //
+ "Unknown section type - Reserved 0x08",
+ //
+ // 0x09
+ //
+ "Unknown section type - Reserved 0x09",
+ //
+ // 0x0A
+ //
+ "Unknown section type - Reserved 0x0A",
+ //
+ // 0x0B
+ //
+ "Unknown section type - Reserved 0x0B",
+ //
+ // 0x0C
+ //
+ "Unknown section type - Reserved 0x0C",
+ //
+ // 0x0D
+ //
+ "Unknown section type - Reserved 0x0D",
+ //
+ // 0x0E
+ //
+ "Unknown section type - Reserved 0x0E",
+ //
+ // 0x0F
+ //
+ "Unknown section type - Reserved 0x0E",
+ //
+ // 0x10
+ //
+ "EFI_SECTION_PE32",
+ //
+ // 0x11
+ //
+ "EFI_SECTION_PIC",
+ //
+ // 0x12
+ //
+ "EFI_SECTION_TE",
+ //
+ // 0x13
+ //
+ "EFI_SECTION_DXE_DEPEX",
+ //
+ // 0x14
+ //
+ "EFI_SECTION_VERSION",
+ //
+ // 0x15
+ //
+ "EFI_SECTION_USER_INTERFACE",
+ //
+ // 0x16
+ //
+ "EFI_SECTION_COMPATIBILITY16",
+ //
+ // 0x17
+ //
+ "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
+ //
+ // 0x18
+ //
+ "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
+ //
+ // 0x19
+ //
+ "EFI_SECTION_RAW",
+ //
+ // 0x1A
+ //
+ "Unknown section type - 0x1A",
+ //
+ // 0x1B
+ //
+ "EFI_SECTION_PEI_DEPEX",
+ //
+ // 0x1C
+ //
+ "EFI_SECTION_SMM_DEPEX",
+ //
+ // 0x1C+
+ //
+ "Unknown section type - Reserved - beyond last defined section"
+ };
+
+ if (Type > EFI_SECTION_LAST_SECTION_TYPE) {
+ Type = EFI_SECTION_LAST_SECTION_TYPE + 1;
+ }
+
+ SectionStr = malloc (100);
+ if (SectionStr == NULL) {
+ printf ("Error: Out of memory resources.\n");
+ return SectionStr;
+ }
+ strcpy (SectionStr, SectionTypeStringTable[Type]);
+ return SectionStr;
+}
+
+STATIC
+EFI_STATUS
+ReadHeader (
+ IN FILE *InputFile,
+ OUT UINT32 *FvSize,
+ OUT BOOLEAN *ErasePolarity
+ )
+/*++
+
+Routine Description:
+
+ This function determines the size of the FV and the erase polarity. The
+ erase polarity is the FALSE value for file state.
+
+Arguments:
+
+ InputFile The file that contains the FV image.
+ FvSize The size of the FV.
+ ErasePolarity The FV erase polarity.
+
+Returns:
+
+ EFI_SUCCESS Function completed successfully.
+ EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
+ EFI_ABORTED The function encountered an error.
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
+ EFI_FV_BLOCK_MAP_ENTRY BlockMap;
+ UINTN Signature[2];
+ UINTN BytesRead;
+ UINT32 Size;
+ size_t ReadSize;
+
+ BytesRead = 0;
+ Size = 0;
+ //
+ // Check input parameters
+ //
+ if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {
+ Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Read the header
+ //
+ ReadSize = fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
+ if (ReadSize != 1) {
+ return EFI_ABORTED;
+ }
+ BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+ Signature[0] = VolumeHeader.Signature;
+ Signature[1] = 0;
+
+ //
+ // Print FV header information
+ //
+ printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);
+ printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);
+
+ if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {
+ printf (" EFI_FVB2_READ_DISABLED_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {
+ printf (" EFI_FVB2_READ_ENABLED_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {
+ printf (" EFI_FVB2_READ_STATUS\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {
+ printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {
+ printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {
+ printf (" EFI_FVB2_WRITE_STATUS\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {
+ printf (" EFI_FVB2_LOCK_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {
+ printf (" EFI_FVB2_LOCK_STATUS\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {
+ printf (" EFI_FVB2_STICKY_WRITE\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {
+ printf (" EFI_FVB2_MEMORY_MAPPED\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {
+ printf (" EFI_FVB2_ERASE_POLARITY\n");
+ *ErasePolarity = TRUE;
+ }
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {
+ printf (" EFI_FVB2_ALIGNMENT\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
+ printf (" EFI_FVB2_ALIGNMENT_2\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
+ printf (" EFI_FVB2_ALIGNMENT_4\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
+ printf (" EFI_FVB2_ALIGNMENT_8\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
+ printf (" EFI_FVB2_ALIGNMENT_16\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
+ printf (" EFI_FVB2_ALIGNMENT_32\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
+ printf (" EFI_FVB2_ALIGNMENT_64\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
+ printf (" EFI_FVB2_ALIGNMENT_128\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
+ printf (" EFI_FVB2_ALIGNMENT_256\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
+ printf (" EFI_FVB2_ALIGNMENT_512\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
+ printf (" EFI_FVB2_ALIGNMENT_1K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
+ printf (" EFI_FVB2_ALIGNMENT_2K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
+ printf (" EFI_FVB2_ALIGNMENT_4K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
+ printf (" EFI_FVB2_ALIGNMENT_8K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
+ printf (" EFI_FVB2_ALIGNMENT_16K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
+ printf (" EFI_FVB2_ALIGNMENT_32K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
+ printf (" EFI_FVB2_ALIGNMENT_64K\n");
+ }
+
+#else
+
+ if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {
+ printf (" EFI_FVB2_READ_LOCK_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {
+ printf (" EFI_FVB2_READ_LOCK_STATUS\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {
+ printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {
+ printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {
+ printf (" EFI_FVB2_ALIGNMENT_1\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
+ printf (" EFI_FVB2_ALIGNMENT_2\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
+ printf (" EFI_FVB2_ALIGNMENT_4\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
+ printf (" EFI_FVB2_ALIGNMENT_8\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
+ printf (" EFI_FVB2_ALIGNMENT_16\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
+ printf (" EFI_FVB2_ALIGNMENT_32\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
+ printf (" EFI_FVB2_ALIGNMENT_64\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
+ printf (" EFI_FVB2_ALIGNMENT_128\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
+ printf (" EFI_FVB2_ALIGNMENT_256\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
+ printf (" EFI_FVB2_ALIGNMENT_512\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
+ printf (" EFI_FVB2_ALIGNMENT_1K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
+ printf (" EFI_FVB2_ALIGNMENT_2K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
+ printf (" EFI_FVB2_ALIGNMENT_4K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
+ printf (" EFI_FVB2_ALIGNMENT_8K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
+ printf (" EFI_FVB2_ALIGNMENT_16K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
+ printf (" EFI_FVB2_ALIGNMENT_32K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
+ printf (" EFI_FVB2_ALIGNMENT_64K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {
+ printf (" EFI_FVB2_ALIGNMENT_128K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {
+ printf (" EFI_FVB2_ALIGNMENT_256K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {
+ printf (" EFI_FVB2_ALIGNMENT_512K\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {
+ printf (" EFI_FVB2_ALIGNMENT_1M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {
+ printf (" EFI_FVB2_ALIGNMENT_2M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {
+ printf (" EFI_FVB2_ALIGNMENT_4M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {
+ printf (" EFI_FVB2_ALIGNMENT_8M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {
+ printf (" EFI_FVB2_ALIGNMENT_16M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {
+ printf (" EFI_FVB2_ALIGNMENT_32M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
+ printf (" EFI_FVB2_ALIGNMENT_64M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
+ printf (" EFI_FVB2_ALIGNMENT_128M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
+ printf (" EFI_FVB2_ALIGNMENT_64M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
+ printf (" EFI_FVB2_ALIGNMENT_128M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {
+ printf (" EFI_FVB2_ALIGNMENT_256M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {
+ printf (" EFI_FVB2_ALIGNMENT_512M\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {
+ printf (" EFI_FVB2_ALIGNMENT_1G\n");
+ }
+
+ if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {
+ printf (" EFI_FVB2_ALIGNMENT_2G\n");
+ }
+
+#endif
+ printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);
+ printf ("File System ID: ");
+ PrintGuid (&VolumeHeader.FileSystemGuid);
+ //
+ // printf ("\n");
+ //
+ printf ("Revision: 0x%04X\n", VolumeHeader.Revision);
+
+ do {
+ ReadSize = fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
+ if (ReadSize != 1) {
+ return EFI_ABORTED;
+ }
+ BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+
+ if (BlockMap.NumBlocks != 0) {
+ printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);
+ printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);
+ Size += BlockMap.NumBlocks * BlockMap.Length;
+ }
+
+ } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));
+
+ if (BytesRead != VolumeHeader.HeaderLength) {
+ printf ("ERROR: Header length not consistent with Block Maps!\n");
+ return EFI_ABORTED;
+ }
+
+ if (VolumeHeader.FvLength != Size) {
+ printf ("ERROR: Volume Size not consistent with Block Maps!\n");
+ return EFI_ABORTED;
+ }
+
+ printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);
+
+ *FvSize = Size;
+
+ //
+ // rewind (InputFile);
+ //
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+PrintFileInfo (
+ EFI_FIRMWARE_VOLUME_HEADER *FvImage,
+ EFI_FFS_FILE_HEADER *FileHeader,
+ BOOLEAN ErasePolarity
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FvImage - GC_TODO: add argument description
+ FileHeader - GC_TODO: add argument description
+ ErasePolarity - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+ EFI_ABORTED - GC_TODO: Add description for return value
+
+--*/
+{
+ UINT32 FileLength;
+ UINT8 FileState;
+ UINT8 Checksum;
+ EFI_FFS_FILE_HEADER2 BlankHeader;
+ EFI_STATUS Status;
+ UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
+ UINT32 HeaderSize;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ UINT16 *Tail;
+#endif
+ //
+ // Check if we have free space
+ //
+ HeaderSize = FvBufGetFfsHeaderSize(FileHeader);
+ if (ErasePolarity) {
+ memset (&BlankHeader, -1, HeaderSize);
+ } else {
+ memset (&BlankHeader, 0, HeaderSize);
+ }
+
+ if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {
+ return EFI_SUCCESS;
+ }
+ //
+ // Print file information.
+ //
+ printf ("============================================================\n");
+
+ printf ("File Name: ");
+ PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);
+ printf ("%s ", GuidBuffer);
+ PrintGuidName (GuidBuffer);
+ printf ("\n");
+
+ //
+ // PrintGuid (&FileHeader->Name);
+ // printf ("\n");
+ //
+ FileLength = FvBufGetFfsFileSize (FileHeader);
+ printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));
+ printf ("File Length: 0x%08X\n", (unsigned) FileLength);
+ printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);
+ printf ("File State: 0x%02X\n", FileHeader->State);
+
+ //
+ // Print file state
+ //
+ FileState = GetFileState (ErasePolarity, FileHeader);
+
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_CONSTRUCTION:
+ printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
+ return EFI_SUCCESS;
+
+ case EFI_FILE_HEADER_INVALID:
+ printf (" EFI_FILE_HEADER_INVALID\n");
+ return EFI_SUCCESS;
+
+ case EFI_FILE_HEADER_VALID:
+ printf (" EFI_FILE_HEADER_VALID\n");
+ Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);
+ Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ printf ("ERROR: Header checksum invalid.\n");
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+
+ case EFI_FILE_DELETED:
+ printf (" EFI_FILE_DELETED\n");
+#ifdef VBOX
+ RT_FALL_THRU();
+#endif
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
+#ifdef VBOX
+ RT_FALL_THRU();
+#endif
+ case EFI_FILE_DATA_VALID:
+ printf (" EFI_FILE_DATA_VALID\n");
+
+ //
+ // Calculate header checksum
+ //
+ Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);
+ Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
+ Checksum = (UINT8) (Checksum - FileHeader->State);
+ if (Checksum != 0) {
+ Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);
+ return EFI_ABORTED;
+ }
+
+ FileLength = FvBufGetFfsFileSize (FileHeader);
+
+ if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
+ //
+ // Calculate file checksum
+ //
+ Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);
+ Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;
+ if (Checksum != 0) {
+ Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);
+ return EFI_ABORTED;
+ }
+ } else {
+ if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
+ Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer);
+ return EFI_ABORTED;
+ }
+ }
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ //
+ // Verify tail if present
+ //
+ if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
+ //
+ // Verify tail is complement of integrity check field in the header.
+ //
+ Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));
+ if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {
+ Error (NULL, 0, 0003, "error parsing FFS file", \
+ "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);
+ return EFI_ABORTED;
+ }
+ }
+ #endif
+ break;
+
+ default:
+ Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);
+ return EFI_ABORTED;
+ }
+
+ printf ("File Type: 0x%02X ", FileHeader->Type);
+
+ switch (FileHeader->Type) {
+
+ case EFI_FV_FILETYPE_RAW:
+ printf ("EFI_FV_FILETYPE_RAW\n");
+ break;
+
+ case EFI_FV_FILETYPE_FREEFORM:
+ printf ("EFI_FV_FILETYPE_FREEFORM\n");
+ break;
+
+ case EFI_FV_FILETYPE_SECURITY_CORE:
+ printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
+ break;
+
+ case EFI_FV_FILETYPE_PEI_CORE:
+ printf ("EFI_FV_FILETYPE_PEI_CORE\n");
+ break;
+
+ case EFI_FV_FILETYPE_DXE_CORE:
+ printf ("EFI_FV_FILETYPE_DXE_CORE\n");
+ break;
+
+ case EFI_FV_FILETYPE_PEIM:
+ printf ("EFI_FV_FILETYPE_PEIM\n");
+ break;
+
+ case EFI_FV_FILETYPE_DRIVER:
+ printf ("EFI_FV_FILETYPE_DRIVER\n");
+ break;
+
+ case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
+ printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
+ break;
+
+ case EFI_FV_FILETYPE_APPLICATION:
+ printf ("EFI_FV_FILETYPE_APPLICATION\n");
+ break;
+
+ case EFI_FV_FILETYPE_SMM:
+ printf ("EFI_FV_FILETYPE_SMM\n");
+ break;
+
+ case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
+ printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
+ break;
+
+ case EFI_FV_FILETYPE_COMBINED_SMM_DXE:
+ printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
+ break;
+
+ case EFI_FV_FILETYPE_SMM_CORE:
+ printf ("EFI_FV_FILETYPE_SMM_CORE\n");
+ break;
+
+ case EFI_FV_FILETYPE_MM_STANDALONE:
+ printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");
+ break;
+
+ case EFI_FV_FILETYPE_MM_CORE_STANDALONE:
+ printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");
+ break;
+
+ case EFI_FV_FILETYPE_FFS_PAD:
+ printf ("EFI_FV_FILETYPE_FFS_PAD\n");
+ break;
+
+ default:
+ printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);
+ return EFI_ABORTED;
+ break;
+ }
+
+ switch (FileHeader->Type) {
+
+ case EFI_FV_FILETYPE_ALL:
+ case EFI_FV_FILETYPE_RAW:
+ case EFI_FV_FILETYPE_FFS_PAD:
+ break;
+
+ default:
+ //
+ // All other files have sections
+ //
+ Status = ParseSection (
+ (UINT8 *) ((UINTN) FileHeader + HeaderSize),
+ FvBufGetFfsFileSize (FileHeader) - HeaderSize
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // printf ("ERROR: Parsing the FFS file.\n");
+ //
+ return EFI_ABORTED;
+ }
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RebaseImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINT32 *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+
+ FileOffset - The offset, in bytes, into the file to read
+
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+
+ Buffer - A pointer to the buffer to read the data into.
+
+Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINT32 Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SetAddressToSectionHeader (
+ IN CHAR8 *FileName,
+ IN OUT UINT8 *FileBuffer,
+ IN UINT64 NewPe32BaseAddress
+ )
+/*++
+
+Routine Description:
+
+ Set new base address into the section header of PeImage
+
+Arguments:
+
+ FileName - Name of file
+ FileBuffer - Pointer to PeImage.
+ NewPe32BaseAddress - New Base Address for PE image.
+
+Returns:
+
+ EFI_SUCCESS Set new base address into this image successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
+ return Status;
+ }
+
+ if (ImageContext.RelocationsStripped) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
+ return Status;
+ }
+
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Get section header list
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ //
+ // Set base address into the first section header that doesn't point to code section.
+ //
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
+ *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;
+ break;
+ }
+ }
+
+ //
+ // BaseAddress is set to section header.
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RebaseImage (
+ IN CHAR8 *FileName,
+ IN OUT UINT8 *FileBuffer,
+ IN UINT64 NewPe32BaseAddress
+ )
+/*++
+
+Routine Description:
+
+ Set new base address into PeImage, and fix up PeImage based on new address.
+
+Arguments:
+
+ FileName - Name of file
+ FileBuffer - Pointer to PeImage.
+ NewPe32BaseAddress - New Base Address for PE image.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - BaseAddress is not valid.
+ EFI_SUCCESS - Update PeImage is correctly.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ UINT8 *MemoryImagePointer;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
+ return Status;
+ }
+
+ if (ImageContext.RelocationsStripped) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
+ return Status;
+ }
+
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy Relocated data to raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ CopyMem (
+ FileBuffer + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ }
+
+ free ((VOID *) MemoryImagePointer);
+
+ //
+ // Update Image Base Address
+ //
+ if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
+ } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
+ ImgHdr->Pe32.OptionalHeader.Magic,
+ FileName
+ );
+ return EFI_ABORTED;
+ }
+
+ //
+ // Set new base address into section header
+ //
+ Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);
+
+ return Status;
+}
+
+EFI_STATUS
+CombinePath (
+ IN CHAR8* DefaultPath,
+ IN CHAR8* AppendPath,
+ OUT CHAR8* NewPath
+)
+{
+ UINT32 DefaultPathLen;
+ UINT64 Index;
+ CHAR8 QuotesStr[] = "\"";
+ strcpy(NewPath, QuotesStr);
+ DefaultPathLen = strlen(DefaultPath);
+ strcat(NewPath, DefaultPath);
+ Index = 0;
+ for (; Index < DefaultPathLen + 1; Index ++) {
+ if (NewPath[Index] == '\\' || NewPath[Index] == '/') {
+ if (NewPath[Index + 1] != '\0') {
+ NewPath[Index] = '/';
+ }
+ }
+ }
+ if (NewPath[Index -1] != '/') {
+ NewPath[Index] = '/';
+ NewPath[Index + 1] = '\0';
+ }
+ strcat(NewPath, AppendPath);
+ strcat(NewPath, QuotesStr);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ParseSection (
+ IN UINT8 *SectionBuffer,
+ IN UINT32 BufferLength
+ )
+/*++
+
+Routine Description:
+
+ Parses EFI Sections
+
+Arguments:
+
+ SectionBuffer - Buffer containing the section to parse.
+ BufferLength - Length of SectionBuffer
+
+Returns:
+
+ EFI_SECTION_ERROR - Problem with section parsing.
+ (a) compression errors
+ (b) unrecognized section
+ EFI_UNSUPPORTED - Do not know how to parse the section.
+ EFI_SUCCESS - Section successfully parsed.
+ EFI_OUT_OF_RESOURCES - Memory allocation failed.
+
+--*/
+{
+ EFI_SECTION_TYPE Type;
+ UINT8 *Ptr;
+ UINT32 SectionLength;
+ UINT32 SectionHeaderLen;
+ CHAR8 *SectionName;
+ EFI_STATUS Status;
+ UINT32 ParsedLength;
+ UINT8 *CompressedBuffer;
+ UINT32 CompressedLength;
+ UINT8 *UncompressedBuffer;
+ UINT32 UncompressedLength;
+ UINT8 *ToolOutputBuffer;
+ UINT32 ToolOutputLength;
+ UINT8 CompressionType;
+ UINT32 DstSize;
+ UINT32 ScratchSize;
+ UINT8 *ScratchBuffer;
+ DECOMPRESS_FUNCTION DecompressFunction;
+ GETINFO_FUNCTION GetInfoFunction;
+ // CHAR16 *name;
+ CHAR8 *ExtractionTool;
+ CHAR8 *ToolInputFile;
+ CHAR8 *ToolOutputFile;
+ CHAR8 *SystemCommand;
+ EFI_GUID *EfiGuid;
+ UINT16 DataOffset;
+ UINT16 Attributes;
+ UINT32 RealHdrLen;
+ CHAR8 *ToolInputFileName;
+ CHAR8 *ToolOutputFileName;
+ CHAR8 *UIFileName;
+
+ ParsedLength = 0;
+ ToolInputFileName = NULL;
+ ToolOutputFileName = NULL;
+
+ while (ParsedLength < BufferLength) {
+ Ptr = SectionBuffer + ParsedLength;
+
+ SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);
+ Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;
+
+ //
+ // This is sort of an odd check, but is necessary because FFS files are
+ // padded to a QWORD boundary, meaning there is potentially a whole section
+ // header worth of 0xFF bytes.
+ //
+ if (SectionLength == 0xffffff && Type == 0xff) {
+ ParsedLength += 4;
+ continue;
+ }
+
+ //
+ // Get real section file size
+ //
+ SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);
+ SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
+
+ SectionName = SectionNameToStr (Type);
+ if (SectionName != NULL) {
+ printf ("------------------------------------------------------------\n");
+ printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);
+ free (SectionName);
+ }
+
+ switch (Type) {
+ case EFI_SECTION_RAW:
+ case EFI_SECTION_PIC:
+ case EFI_SECTION_TE:
+ // default is no more information
+ break;
+
+ case EFI_SECTION_PE32:
+ if (EnableHash) {
+ ToolInputFileName = "edk2Temp_InputEfi.tmp";
+ ToolOutputFileName = "edk2Temp_OutputHash.tmp";
+ RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);
+ PutFileImage (
+ ToolInputFileName,
+ (CHAR8*)Ptr + SectionHeaderLen,
+ SectionLength - SectionHeaderLen
+ );
+
+ SystemCommand = malloc (
+ strlen (OPENSSL_COMMAND_FORMAT_STRING) +
+ strlen (OpenSslPath) +
+ strlen (ToolInputFileName) +
+ strlen (ToolOutputFileName) +
+ 1
+ );
+ if (SystemCommand == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ sprintf (
+ SystemCommand,
+ OPENSSL_COMMAND_FORMAT_STRING,
+ OpenSslPath,
+ ToolOutputFileName,
+ ToolInputFileName
+ );
+
+ if (system (SystemCommand) != EFI_SUCCESS) {
+ Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);
+ }
+ else {
+ FILE *fp;
+ CHAR8 *StrLine;
+ CHAR8 *NewStr;
+ UINT32 nFileLen;
+ if((fp = fopen(ToolOutputFileName,"r")) == NULL) {
+ Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);
+ }
+ else {
+ fseek(fp,0,SEEK_SET);
+ fseek(fp,0,SEEK_END);
+ nFileLen = ftell(fp);
+ fseek(fp,0,SEEK_SET);
+ StrLine = malloc(nFileLen);
+ if (StrLine == NULL) {
+ fclose(fp);
+ free (SystemCommand);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ fgets(StrLine, nFileLen, fp);
+ NewStr = strrchr (StrLine, '=');
+ printf (" SHA1: %s\n", NewStr + 1);
+ free (StrLine);
+ fclose(fp);
+ }
+ }
+ remove(ToolInputFileName);
+ remove(ToolOutputFileName);
+ free (SystemCommand);
+ }
+ break;
+
+ case EFI_SECTION_USER_INTERFACE:
+ UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1);
+ if (UIFileName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName);
+ printf (" String: %s\n", UIFileName);
+ free (UIFileName);
+ break;
+
+ case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
+ Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);
+ return EFI_SECTION_ERROR;
+ }
+ break;
+
+ case EFI_SECTION_COMPATIBILITY16:
+ case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
+ //
+ // Section does not contain any further header information.
+ //
+ break;
+
+ case EFI_SECTION_PEI_DEPEX:
+ case EFI_SECTION_DXE_DEPEX:
+ case EFI_SECTION_SMM_DEPEX:
+ DumpDepexSection (Ptr, SectionLength);
+ break;
+
+ case EFI_SECTION_VERSION:
+ printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));
+ printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));
+ break;
+
+ case EFI_SECTION_COMPRESSION:
+ UncompressedBuffer = NULL;
+ if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {
+ RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);
+ UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;
+ CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;
+ } else {
+ RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);
+ UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;
+ CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;
+ }
+ CompressedLength = SectionLength - RealHdrLen;
+ printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);
+
+ if (CompressionType == EFI_NOT_COMPRESSED) {
+ printf (" Compression Type: EFI_NOT_COMPRESSED\n");
+ if (CompressedLength != UncompressedLength) {
+ Error (
+ NULL,
+ 0,
+ 0,
+ "file is not compressed, but the compressed length does not match the uncompressed length",
+ NULL
+ );
+ return EFI_SECTION_ERROR;
+ }
+
+ UncompressedBuffer = Ptr + RealHdrLen;
+ } else if (CompressionType == EFI_STANDARD_COMPRESSION) {
+ GetInfoFunction = EfiGetInfo;
+ DecompressFunction = EfiDecompress;
+ printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
+
+ CompressedBuffer = Ptr + RealHdrLen;
+
+ Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);
+ return EFI_SECTION_ERROR;
+ }
+
+ if (DstSize != UncompressedLength) {
+ Error (NULL, 0, 0003, "compression error in the compression section", NULL);
+ return EFI_SECTION_ERROR;
+ }
+
+ ScratchBuffer = malloc (ScratchSize);
+ if (ScratchBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ UncompressedBuffer = malloc (UncompressedLength);
+ if (UncompressedBuffer == NULL) {
+ free (ScratchBuffer);
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Status = DecompressFunction (
+ CompressedBuffer,
+ CompressedLength,
+ UncompressedBuffer,
+ UncompressedLength,
+ ScratchBuffer,
+ ScratchSize
+ );
+ free (ScratchBuffer);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "decompress failed", NULL);
+ free (UncompressedBuffer);
+ return EFI_SECTION_ERROR;
+ }
+ } else {
+ Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);
+ return EFI_SECTION_ERROR;
+ }
+
+ Status = ParseSection (UncompressedBuffer, UncompressedLength);
+
+ if (CompressionType == EFI_STANDARD_COMPRESSION) {
+ //
+ // We need to deallocate Buffer
+ //
+ free (UncompressedBuffer);
+ }
+
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "failed to parse section", NULL);
+ return EFI_SECTION_ERROR;
+ }
+ break;
+
+ case EFI_SECTION_GUID_DEFINED:
+ if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {
+ EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;
+ DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;
+ Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;
+ } else {
+ EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;
+ DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;
+ Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;
+ }
+ printf (" SectionDefinitionGuid: ");
+ PrintGuid (EfiGuid);
+ printf ("\n");
+ printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);
+ printf (" Attributes: 0x%04X\n", (unsigned) Attributes);
+
+ ExtractionTool =
+ LookupGuidedSectionToolPath (
+ mParsedGuidedSectionTools,
+ EfiGuid
+ );
+
+ if (ExtractionTool != NULL) {
+ #ifndef __GNUC__
+ ToolInputFile = CloneString (tmpnam (NULL));
+ ToolOutputFile = CloneString (tmpnam (NULL));
+ #else
+ char tmp1[] = "/tmp/fileXXXXXX";
+ char tmp2[] = "/tmp/fileXXXXXX";
+ int fd1;
+ int fd2;
+ fd1 = mkstemp(tmp1);
+ fd2 = mkstemp(tmp2);
+ ToolInputFile = CloneString(tmp1);
+ ToolOutputFile = CloneString(tmp2);
+ close(fd1);
+ close(fd2);
+ #endif
+
+ if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {
+ if (ToolInputFile != NULL) {
+ free (ToolInputFile);
+ }
+ if (ToolOutputFile != NULL) {
+ free (ToolOutputFile);
+ }
+ free (ExtractionTool);
+
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Construction 'system' command string
+ //
+ SystemCommand = malloc (
+ strlen (EXTRACT_COMMAND_FORMAT_STRING) +
+ strlen (ExtractionTool) +
+ strlen (ToolInputFile) +
+ strlen (ToolOutputFile) +
+ 1
+ );
+ if (SystemCommand == NULL) {
+ free (ToolInputFile);
+ free (ToolOutputFile);
+ free (ExtractionTool);
+
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ sprintf (
+ SystemCommand,
+ EXTRACT_COMMAND_FORMAT_STRING,
+ ExtractionTool,
+ ToolOutputFile,
+ ToolInputFile
+ );
+ free (ExtractionTool);
+
+ Status =
+ PutFileImage (
+ ToolInputFile,
+ (CHAR8*) SectionBuffer + DataOffset,
+ BufferLength - DataOffset
+ );
+
+ system (SystemCommand);
+ remove (ToolInputFile);
+ free (ToolInputFile);
+
+ Status =
+ GetFileImage (
+ ToolOutputFile,
+ (CHAR8 **)&ToolOutputBuffer,
+ &ToolOutputLength
+ );
+ remove (ToolOutputFile);
+ free (ToolOutputFile);
+ free (SystemCommand);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);
+ return EFI_SECTION_ERROR;
+ }
+
+ Status = ParseSection (
+ ToolOutputBuffer,
+ ToolOutputLength
+ );
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
+ return EFI_SECTION_ERROR;
+ }
+
+ //
+ // Check for CRC32 sections which we can handle internally if needed.
+ //
+ } else if (!CompareGuid (
+ EfiGuid,
+ &gEfiCrc32GuidedSectionExtractionProtocolGuid
+ )
+ ) {
+ //
+ // CRC32 guided section
+ //
+ Status = ParseSection (
+ SectionBuffer + DataOffset,
+ BufferLength - DataOffset
+ );
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);
+ return EFI_SECTION_ERROR;
+ }
+ } else {
+ //
+ // We don't know how to parse it now.
+ //
+ Error (NULL, 0, 0003, "Error parsing section", \
+ "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in GuidedSectionTools.txt (built in the FV directory).");
+ return EFI_UNSUPPORTED;
+ }
+ break;
+
+ default:
+ //
+ // Unknown section, return error
+ //
+ Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);
+ return EFI_SECTION_ERROR;
+ }
+
+ ParsedLength += SectionLength;
+ //
+ // We make then next section begin on a 4-byte boundary
+ //
+ ParsedLength = GetOccupiedSize (ParsedLength, 4);
+ }
+
+ if (ParsedLength < BufferLength) {
+ Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);
+ return EFI_SECTION_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DumpDepexSection (
+ IN UINT8 *Ptr,
+ IN UINT32 SectionLength
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ Ptr - GC_TODO: add argument description
+ SectionLength - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
+
+ //
+ // Need at least a section header + data
+ //
+ if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {
+ return EFI_SUCCESS;
+ }
+
+ Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
+ SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
+ while (SectionLength > 0) {
+ printf (" ");
+ switch (*Ptr) {
+ case EFI_DEP_BEFORE:
+ printf ("BEFORE\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_AFTER:
+ printf ("AFTER\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_PUSH:
+ printf ("PUSH\n ");
+ PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);
+ printf ("%s ", GuidBuffer);
+ PrintGuidName (GuidBuffer);
+ printf ("\n");
+ //
+ // PrintGuid ((EFI_GUID *)(Ptr + 1));
+ //
+ Ptr += 17;
+ SectionLength -= 17;
+ break;
+
+ case EFI_DEP_AND:
+ printf ("AND\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_OR:
+ printf ("OR\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_NOT:
+ printf ("NOT\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_TRUE:
+ printf ("TRUE\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_FALSE:
+ printf ("FALSE\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_END:
+ printf ("END DEPEX\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ case EFI_DEP_SOR:
+ printf ("SOR\n");
+ Ptr++;
+ SectionLength--;
+ break;
+
+ default:
+ printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PrintGuidName (
+ IN UINT8 *GuidStr
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ GuidStr - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+ EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
+
+--*/
+{
+ GUID_TO_BASENAME *GPtr;
+ //
+ // If we have a list of guid-to-basenames, then go through the list to
+ // look for a guid string match. If found, print the basename to stdout,
+ // otherwise return a failure.
+ //
+ GPtr = mGuidBaseNameList;
+ while (GPtr != NULL) {
+ if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {
+ printf ("%s", GPtr->BaseName);
+ return EFI_SUCCESS;
+ }
+
+ GPtr = GPtr->Next;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+ParseGuidBaseNameFile (
+ CHAR8 *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - GC_TODO: Add description for return value
+ EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ FILE *Fptr;
+ CHAR8 Line[MAX_LINE_LEN];
+ CHAR8 FormatString[MAX_LINE_LEN];
+ GUID_TO_BASENAME *GPtr;
+
+ if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {
+ printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Generate the format string for fscanf
+ //
+ sprintf (
+ FormatString,
+ "%%%us %%%us",
+ (unsigned) sizeof (GPtr->Guid) - 1,
+ (unsigned) sizeof (GPtr->BaseName) - 1
+ );
+
+ while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+ //
+ // Allocate space for another guid/basename element
+ //
+ GPtr = malloc (sizeof (GUID_TO_BASENAME));
+ if (GPtr == NULL) {
+ fclose (Fptr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));
+ if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) {
+ GPtr->Next = mGuidBaseNameList;
+ mGuidBaseNameList = GPtr;
+ } else {
+ //
+ // Some sort of error. Just continue.
+ //
+ free (GPtr);
+ }
+ }
+
+ fclose (Fptr);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FreeGuidBaseNameList (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ GUID_TO_BASENAME *Next;
+
+ while (mGuidBaseNameList != NULL) {
+ Next = mGuidBaseNameList->Next;
+ free (mGuidBaseNameList);
+ mGuidBaseNameList = Next;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+static
+VOID
+LoadGuidedSectionToolsTxt (
+ IN CHAR8* FirmwareVolumeFilename
+ )
+{
+ CHAR8* PeerFilename;
+ CHAR8* Places[] = {
+ NULL,
+ //NULL,
+ };
+ UINTN Index;
+
+ Places[0] = FirmwareVolumeFilename;
+ //Places[1] = mUtilityFilename;
+
+ mParsedGuidedSectionTools = NULL;
+
+ for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {
+ PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");
+ //printf("Loading %s...\n", PeerFilename);
+ if (OsPathExists (PeerFilename)) {
+ mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);
+ }
+ free (PeerFilename);
+ if (mParsedGuidedSectionTools != NULL) {
+ return;
+ }
+ }
+}
+
+
+void
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ //
+ // Summary usage
+ //
+ fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);
+
+ //
+ // Copyright declaration
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
+ fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");
+
+ //
+ // Details Option
+ //
+ fprintf (stdout, "optional arguments:\n");
+ fprintf (stdout, " -h, --help\n\
+ Show this help message and exit\n");
+ fprintf (stdout, " --version\n\
+ Show program's version number and exit\n");
+ fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\
+ Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
+ fprintf (stdout, " -v, --verbose\n\
+ Print informational statements\n");
+ fprintf (stdout, " -q, --quiet\n\
+ Returns the exit code, error messages will be displayed\n");
+ fprintf (stdout, " -s, --silent\n\
+ Returns only the exit code; informational and error\n\
+ messages are not displayed\n");
+ fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
+ Parse the basename to file-guid cross reference file(s)\n");
+ fprintf (stdout, " -f OFFSET, --offset OFFSET\n\
+ The offset from the start of the input file to start \n\
+ processing an FV\n");
+ fprintf (stdout, " --hash\n\
+ Generate HASH value of the entire PE image\n");
+ fprintf (stdout, " --sfo\n\
+ Reserved for future use\n");
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.h b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.h
new file mode 100644
index 00000000..5ae388f8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/VolInfo/VolInfo.h
@@ -0,0 +1,31 @@
+/** @file
+Local Definitions for the VolInfo utility
+
+Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _VOLINFO_H_
+#define _VOLINFO_H_ 1
+
+#define PI_SPECIFICATION_VERSION 0x00010000
+
+#define EFI_DEP_BEFORE 0x00
+#define EFI_DEP_AFTER 0x01
+#define EFI_DEP_PUSH 0x02
+#define EFI_DEP_AND 0x03
+#define EFI_DEP_OR 0x04
+#define EFI_DEP_NOT 0x05
+#define EFI_DEP_TRUE 0x06
+#define EFI_DEP_FALSE 0x07
+#define EFI_DEP_END 0x08
+#define EFI_DEP_SOR 0x09
+
+#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1B
+#define EFI_SECTION_LAST_SECTION_TYPE 0x1B
+
+#define OPENSSL_COMMAND_FORMAT_STRING "%s sha1 -out %s %s"
+#define EXTRACT_COMMAND_FORMAT_STRING "%s -d -o %s %s"
+
+#endif