Index: lld/COFF/Config.h =================================================================== --- lld/COFF/Config.h +++ lld/COFF/Config.h @@ -104,7 +104,7 @@ struct Configuration { enum ManifestKind { Default, SideBySide, Embed, No }; bool is64() const { - return machine == AMD64 || llvm::COFF::isAnyArm64(machine); + return llvm::COFF::is64Bit(machine); } llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN; Index: llvm/docs/yaml2obj.rst =================================================================== --- llvm/docs/yaml2obj.rst +++ llvm/docs/yaml2obj.rst @@ -34,6 +34,56 @@ StructuredData: - Binary: {type: str} - Int32: {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 Int32; 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 (Int32) Size += sizeof(int32_t); + 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 (Int32) OS << binary_le(*Int32); 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("Int32", E.Int32); 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-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,33 @@ +# 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_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: + MaximumAllocationSize: 0x100000 + VirtualMemoryThreshold: 0x2000000 + CodeIntegrity: + Flags: 0x100 +symbols: [] +...