Index: llvm/docs/yaml2obj.rst =================================================================== --- llvm/docs/yaml2obj.rst +++ llvm/docs/yaml2obj.rst @@ -34,6 +34,56 @@ StructuredData: - Binary: {type: str} - Uint32: {type: int} + - LoadConfig: + Size: {type: int} + TimeDateStamp: {type: int} + MajorVersion: {type: int} + MinorVersion: {type: int} + GlobalFlagsClear: {type: int} + GlobalFlagsSet: {type: int} + CriticalSectionDefaultTimeout: {type: int} + DeCommitFreeBlockThreshold: {type: int} + DeCommitTotalFreeThreshold: {type: int} + LockPrefixTable: {type: int} + MaximumAllocationSize: {type: int} + VirtualMemoryThreshold: {type: int} + ProcessAffinityMask: {type: int} + ProcessHeapFlags: {type: int} + CSDVersion: {type: int} + DependentLoadFlags: {type: int} + EditList: {type: int} + SecurityCookie: {type: int} + SEHandlerTable: {type: int} + SEHandlerCount: {type: int} + GuardCFCheckFunction: {type: int} + GuardCFCheckDispatch: {type: int} + GuardCFFunctionTable: {type: int} + GuardCFFunctionCount: {type: int} + GuardFlags: {type: int} + CodeIntegrity: + Flags: {type: int} + Catalog: {type: int} + CatalogOffset: {type: int} + GuardAddressTakenIatEntryTable: {type: int} + GuardAddressTakenIatEntryCount: {type: int} + GuardLongJumpTargetTable: {type: int} + GuardLongJumpTargetCount: {type: int} + DynamicValueRelocTable: {type: int} + CHPEMetadataPointer: {type: int} + GuardRFFailureRoutine: {type: int} + GuardRFFailureRoutineFunctionPointer: {type: int} + DynamicValueRelocTableOffset: {type: int} + DynamicValueRelocTableSection: {type: int} + GuardRFVerifyStackPointerFunctionPointer: {type: int} + HotPatchTableOffset: {type: int} + EnclaveConfigurationPointer: {type: int} + VolatileMetadataPointer: {type: int} + GuardEHContinuationTable: {type: int} + GuardEHContinuationCount: {type: int} + GuardXFGCheckFunctionPointer: {type: int} + GuardXFGDispatchFunctionPointer: {type: int} + GuardXFGTableDispatchFunctionPointer: {type: int} + CastGuardOsDeterminedFailureMode: {type: int} symbols: - Name: .text Index: llvm/include/llvm/BinaryFormat/COFF.h =================================================================== --- llvm/include/llvm/BinaryFormat/COFF.h +++ llvm/include/llvm/BinaryFormat/COFF.h @@ -130,6 +130,10 @@ return Machine == IMAGE_FILE_MACHINE_ARM64 || isArm64EC(Machine); } +template bool is64Bit(T Machine) { + return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine); +} + enum Characteristics : unsigned { C_Invalid = 0, Index: llvm/include/llvm/ObjectYAML/COFFYAML.h =================================================================== --- llvm/include/llvm/ObjectYAML/COFFYAML.h +++ llvm/include/llvm/ObjectYAML/COFFYAML.h @@ -15,6 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/COFF.h" +#include "llvm/Object/COFF.h" #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" #include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h" #include "llvm/ObjectYAML/CodeViewYAMLTypes.h" @@ -69,6 +70,8 @@ struct SectionDataEntry { std::optional Uint32; yaml::BinaryRef Binary; + std::optional LoadConfig32; + std::optional LoadConfig64; size_t size() const; void writeAsBinary(raw_ostream &OS) const; @@ -246,6 +249,18 @@ static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT); }; +template <> struct MappingTraits { + static void mapping(IO &IO, object::coff_load_configuration32 &ACT); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, object::coff_load_configuration64 &ACT); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, object::coff_load_config_code_integrity &ACT); +}; + template <> struct MappingTraits { static void mapping(IO &IO, COFFYAML::Symbol &S); Index: llvm/lib/ObjectYAML/COFFEmitter.cpp =================================================================== --- llvm/lib/ObjectYAML/COFFEmitter.cpp +++ llvm/lib/ObjectYAML/COFFEmitter.cpp @@ -16,7 +16,6 @@ #include "llvm/ADT/StringMap.h" #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" -#include "llvm/Object/COFF.h" #include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/BinaryStreamWriter.h" @@ -48,10 +47,7 @@ } bool isPE() const { return Obj.OptionalHeader.has_value(); } - bool is64Bit() const { - return Obj.Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 || - COFF::isAnyArm64(Obj.Header.Machine); - } + bool is64Bit() const { return COFF::is64Bit(Obj.Header.Machine); } uint32_t getFileAlignment() const { return Obj.OptionalHeader->Header.FileAlignment; @@ -598,13 +594,28 @@ size_t Size = Binary.binary_size(); if (Uint32) Size += sizeof(*Uint32); + if (LoadConfig32) + Size += LoadConfig32->Size; + if (LoadConfig64) + Size += LoadConfig64->Size; return Size; } +template static void writeLoadConfig(T &S, raw_ostream &OS) { + OS.write(reinterpret_cast(&S), + std::min(sizeof(S), size_t(S.Size))); + if (sizeof(S) < S.Size) + OS.write_zeros(S.Size - sizeof(S)); +} + void COFFYAML::SectionDataEntry::writeAsBinary(raw_ostream &OS) const { if (Uint32) OS << binary_le(*Uint32); Binary.writeAsBinary(OS); + if (LoadConfig32) + writeLoadConfig(*LoadConfig32, OS); + if (LoadConfig64) + writeLoadConfig(*LoadConfig64, OS); } namespace llvm { Index: llvm/lib/ObjectYAML/COFFYAML.cpp =================================================================== --- llvm/lib/ObjectYAML/COFFYAML.cpp +++ llvm/lib/ObjectYAML/COFFYAML.cpp @@ -547,10 +547,93 @@ IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex); } +void MappingTraits::mapping( + IO &IO, object::coff_load_config_code_integrity &S) { + IO.mapOptional("Flags", S.Flags); + IO.mapOptional("Catalog", S.Catalog); + IO.mapOptional("CatalogOffset", S.CatalogOffset); +} + +template void mapLoadConfig(IO &IO, T &S) { + IO.mapOptional("Size", S.Size, support::ulittle32_t(sizeof(S))); + IO.mapOptional("TimeDateStamp", S.TimeDateStamp); + IO.mapOptional("MajorVersion", S.MajorVersion); + IO.mapOptional("MinorVersion", S.MinorVersion); + IO.mapOptional("GlobalFlagsClear", S.GlobalFlagsClear); + IO.mapOptional("GlobalFlagsSet", S.GlobalFlagsSet); + IO.mapOptional("CriticalSectionDefaultTimeout", + S.CriticalSectionDefaultTimeout); + IO.mapOptional("DeCommitFreeBlockThreshold", S.DeCommitFreeBlockThreshold); + IO.mapOptional("DeCommitTotalFreeThreshold", S.DeCommitTotalFreeThreshold); + IO.mapOptional("LockPrefixTable", S.LockPrefixTable); + IO.mapOptional("MaximumAllocationSize", S.MaximumAllocationSize); + IO.mapOptional("VirtualMemoryThreshold", S.VirtualMemoryThreshold); + IO.mapOptional("ProcessAffinityMask", S.ProcessAffinityMask); + IO.mapOptional("ProcessHeapFlags", S.ProcessHeapFlags); + IO.mapOptional("CSDVersion", S.CSDVersion); + IO.mapOptional("DependentLoadFlags", S.DependentLoadFlags); + IO.mapOptional("EditList", S.EditList); + IO.mapOptional("SecurityCookie", S.SecurityCookie); + IO.mapOptional("SEHandlerTable", S.SEHandlerTable); + IO.mapOptional("SEHandlerCount", S.SEHandlerCount); + IO.mapOptional("GuardCFCheckFunction", S.GuardCFCheckFunction); + IO.mapOptional("GuardCFCheckDispatch", S.GuardCFCheckDispatch); + IO.mapOptional("GuardCFFunctionTable", S.GuardCFFunctionTable); + IO.mapOptional("GuardCFFunctionCount", S.GuardCFFunctionCount); + IO.mapOptional("GuardFlags", S.GuardFlags); + IO.mapOptional("CodeIntegrity", S.CodeIntegrity); + IO.mapOptional("GuardAddressTakenIatEntryTable", + S.GuardAddressTakenIatEntryTable); + IO.mapOptional("GuardAddressTakenIatEntryCount", + S.GuardAddressTakenIatEntryCount); + IO.mapOptional("GuardLongJumpTargetTable", S.GuardLongJumpTargetTable); + IO.mapOptional("GuardLongJumpTargetCount", S.GuardLongJumpTargetCount); + IO.mapOptional("DynamicValueRelocTable", S.DynamicValueRelocTable); + IO.mapOptional("CHPEMetadataPointer", S.CHPEMetadataPointer); + IO.mapOptional("GuardRFFailureRoutine", S.GuardRFFailureRoutine); + IO.mapOptional("GuardRFFailureRoutineFunctionPointer", + S.GuardRFFailureRoutineFunctionPointer); + IO.mapOptional("DynamicValueRelocTableOffset", + S.DynamicValueRelocTableOffset); + IO.mapOptional("DynamicValueRelocTableSection", + S.DynamicValueRelocTableSection); + IO.mapOptional("GuardRFVerifyStackPointerFunctionPointer", + S.GuardRFVerifyStackPointerFunctionPointer); + IO.mapOptional("HotPatchTableOffset", S.HotPatchTableOffset); + IO.mapOptional("EnclaveConfigurationPointer", S.EnclaveConfigurationPointer); + IO.mapOptional("VolatileMetadataPointer", S.VolatileMetadataPointer); + IO.mapOptional("GuardEHContinuationTable", S.GuardEHContinuationTable); + IO.mapOptional("GuardEHContinuationCount", S.GuardEHContinuationCount); + IO.mapOptional("GuardXFGCheckFunctionPointer", + S.GuardXFGCheckFunctionPointer); + IO.mapOptional("GuardXFGDispatchFunctionPointer", + S.GuardXFGDispatchFunctionPointer); + IO.mapOptional("GuardXFGTableDispatchFunctionPointer", + S.GuardXFGTableDispatchFunctionPointer); + IO.mapOptional("CastGuardOsDeterminedFailureMode", + S.CastGuardOsDeterminedFailureMode); +} + +void MappingTraits::mapping( + IO &IO, object::coff_load_configuration32 &S) { + mapLoadConfig(IO, S); +} + +void MappingTraits::mapping( + IO &IO, object::coff_load_configuration64 &S) { + mapLoadConfig(IO, S); +} + void MappingTraits::mapping( IO &IO, COFFYAML::SectionDataEntry &E) { IO.mapOptional("Uint32", E.Uint32); IO.mapOptional("Binary", E.Binary); + + COFF::header &H = *static_cast(IO.getContext()); + if (COFF::is64Bit(H.Machine)) + IO.mapOptional("LoadConfig", E.LoadConfig64); + else + IO.mapOptional("LoadConfig", E.LoadConfig32); } void MappingTraits::mapping(IO &IO, COFFYAML::Symbol &S) { Index: llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml =================================================================== --- llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml +++ llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml @@ -39,7 +39,9 @@ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] VirtualAddress: 0x4000 VirtualSize: 328 - SectionData: '40010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050008001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + StructuredData: + - LoadConfig: + CHPEMetadataPointer: 0x180005000 - Name: .data Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] VirtualAddress: 0x5000 Index: llvm/test/tools/yaml2obj/COFF/load-config-empty.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/COFF/load-config-empty.yaml @@ -0,0 +1,34 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --coff-load-config %t | FileCheck %s + +# CHECK: Format: COFF-x86-64 +# CHECK: Arch: x86_64 +# CHECK: AddressSize: 64bit +# CHECK: LoadConfig [ +# CHECK: Size: 0x138 +# CHECK: MajorVersion: 0x0 +# CHECK: MinorVersion: 0x0 +# CHECK: GuardEHContinuationCount: 0 +# CHECK: ] + +--- !COFF +OptionalHeader: + ImageBase: 0x180000000 + SectionAlignment: 4096 + FileAlignment: 512 + DLLCharacteristics: [ ] + LoadConfigTable: + RelativeVirtualAddress: 0x1000 + Size: 320 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 0x1000 + VirtualSize: 320 + StructuredData: + - LoadConfig: +symbols: [] +... Index: llvm/test/tools/yaml2obj/COFF/load-config32-large.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/COFF/load-config32-large.yaml @@ -0,0 +1,42 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --hex-dump=.rdata %t | FileCheck %s + +# CHECK: 0x00401000 d0000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401010 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401020 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401030 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401040 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401050 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401060 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401070 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401080 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x00401090 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x004010a0 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x004010b0 00000000 00000000 ff000000 00000000 ................ +# CHECK-NEXT: 0x004010c0 00000000 00000000 00000000 00000000 ................ +# CHECK-NEXT: 0x004010d0 aabbccdd .... + +--- !COFF +OptionalHeader: + ImageBase: 0x400000 + SectionAlignment: 4096 + FileAlignment: 512 + DLLCharacteristics: [ ] + LoadConfigTable: + RelativeVirtualAddress: 0x1000 + Size: 320 +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 0x1000 + VirtualSize: 0xd4 + StructuredData: + - LoadConfig: + Size: 0xd0 + CastGuardOsDeterminedFailureMode: 0xff + - Uint32: 0xddccbbaa +symbols: [] +... Index: llvm/test/tools/yaml2obj/COFF/load-config32.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/COFF/load-config32.yaml @@ -0,0 +1,31 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --coff-load-config %t | FileCheck %s + +# CHECK: LoadConfig [ +# CHECK: MaximumAllocationSize: 0x100000 +# CHECK: VirtualMemoryThreshold: 0x2000000 +# CHECK: CHPEMetadataPointer: 0 + +--- !COFF +OptionalHeader: + ImageBase: 0x180000000 + SectionAlignment: 4096 + FileAlignment: 512 + DLLCharacteristics: [ ] + LoadConfigTable: + RelativeVirtualAddress: 0x1000 + Size: 320 +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 0x1000 + VirtualSize: 320 + StructuredData: + - LoadConfig: + MaximumAllocationSize: 0x100000 + VirtualMemoryThreshold: 0x2000000 +symbols: [] +... Index: llvm/test/tools/yaml2obj/COFF/load-config64.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/COFF/load-config64.yaml @@ -0,0 +1,121 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --coff-load-config %t | FileCheck %s + +# CHECK: Format: COFF-x86-64 +# CHECK: Arch: x86_64 +# CHECK: AddressSize: 64bit +# CHECK: LoadConfig [ +# CHECK: Size: 0x150 +# CHECK: TimeDateStamp: 1970-01-01 00:00:01 (0x1) +# CHECK: MajorVersion: 0x2 +# CHECK: MinorVersion: 0x3 +# CHECK: GlobalFlagsClear: 0x4 +# CHECK: GlobalFlagsSet: 0x5 +# CHECK: CriticalSectionDefaultTimeout: 0x6 +# CHECK: DeCommitFreeBlockThreshold: 0x7 +# CHECK: DeCommitTotalFreeThreshold: 0x8 +# CHECK: LockPrefixTable: 0x9 +# CHECK: MaximumAllocationSize: 0x100000 +# CHECK: VirtualMemoryThreshold: 0x2000000 +# CHECK: ProcessHeapFlags: 0x2 +# CHECK: ProcessAffinityMask: 0x1 +# CHECK: CSDVersion: 0x3 +# CHECK: DependentLoadFlags: 0x4 +# CHECK: EditList: 0x5 +# CHECK: SecurityCookie: 0x6 +# CHECK: SEHandlerTable: 0x0 +# CHECK: SEHandlerCount: 0 +# CHECK: GuardCFCheckFunction: 0x9 +# CHECK: GuardCFCheckDispatch: 0x1 +# CHECK: GuardCFFunctionTable: 0x0 +# CHECK: GuardCFFunctionCount: 0 +# CHECK: GuardFlags [ (0x4) +# CHECK: ] +# CHECK: GuardAddressTakenIatEntryTable: 0x0 +# CHECK: GuardAddressTakenIatEntryCount: 0 +# CHECK: GuardLongJumpTargetTable: 0x0 +# CHECK: GuardLongJumpTargetCount: 0 +# CHECK: DynamicValueRelocTable: 0x2 +# CHECK: CHPEMetadataPointer: 0x0 +# CHECK: GuardRFFailureRoutine: 0x4 +# CHECK: GuardRFFailureRoutineFunctionPointer: 0x5 +# CHECK: DynamicValueRelocTableOffset: 0x6 +# CHECK: DynamicValueRelocTableSection: 7 +# CHECK: GuardRFVerifyStackPointerFunctionPointer: 0x8 +# CHECK: HotPatchTableOffset: 0x9 +# CHECK: EnclaveConfigurationPointer: 0x1 +# CHECK: VolatileMetadataPointer: 0x2 +# CHECK: GuardEHContinuationTable: 0x0 +# CHECK: GuardEHContinuationCount: 0 +# CHECK: ] + +--- !COFF +OptionalHeader: + ImageBase: 0x180000000 + SectionAlignment: 4096 + FileAlignment: 512 + DLLCharacteristics: [ ] + LoadConfigTable: + RelativeVirtualAddress: 0x1000 + Size: 320 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 0x1000 + VirtualSize: 320 + StructuredData: + - LoadConfig: + Size: 0x150 + TimeDateStamp: 1 + MajorVersion: 2 + MinorVersion: 3 + GlobalFlagsClear: 4 + GlobalFlagsSet: 5 + CriticalSectionDefaultTimeout: 6 + DeCommitFreeBlockThreshold: 7 + DeCommitTotalFreeThreshold: 8 + LockPrefixTable: 9 + MaximumAllocationSize: 0x100000 + VirtualMemoryThreshold: 0x2000000 + ProcessAffinityMask: 1 + ProcessHeapFlags: 2 + CSDVersion: 3 + DependentLoadFlags: 4 + EditList: 5 + SecurityCookie: 6 + SEHandlerTable: 0 + SEHandlerCount: 0 + GuardCFCheckFunction: 9 + GuardCFCheckDispatch: 1 + GuardCFFunctionTable: 0 + GuardCFFunctionCount: 0 + GuardFlags: 4 + CodeIntegrity: + Flags: 0x100 + Catalog: 5 + CatalogOffset: 6 + GuardAddressTakenIatEntryTable: 0 + GuardAddressTakenIatEntryCount: 0 + GuardLongJumpTargetTable: 0 + GuardLongJumpTargetCount: 0 + DynamicValueRelocTable: 2 + CHPEMetadataPointer: 0 + GuardRFFailureRoutine: 4 + GuardRFFailureRoutineFunctionPointer: 5 + DynamicValueRelocTableOffset: 6 + DynamicValueRelocTableSection: 7 + GuardRFVerifyStackPointerFunctionPointer: 8 + HotPatchTableOffset: 9 + EnclaveConfigurationPointer: 1 + VolatileMetadataPointer: 2 + GuardEHContinuationTable: 0 + GuardEHContinuationCount: 0 + GuardXFGCheckFunctionPointer: 5 + GuardXFGDispatchFunctionPointer: 6 + GuardXFGTableDispatchFunctionPointer: 7 + CastGuardOsDeterminedFailureMode: 8 +symbols: [] +...