[yaml2obj] Add support for load config section data.

Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D149440
This commit is contained in:
Jacek Caban
2023-04-28 14:35:38 +02:00
parent 20b93abca6
commit 7450e0c1d3
7 changed files with 498 additions and 6 deletions

View File

@@ -34,6 +34,56 @@ Here's a sample COFF file.
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

View File

@@ -130,6 +130,10 @@ template <typename T> bool isAnyArm64(T Machine) {
return Machine == IMAGE_FILE_MACHINE_ARM64 || isArm64EC(Machine);
}
template <typename T> bool is64Bit(T Machine) {
return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine);
}
enum Characteristics : unsigned {
C_Invalid = 0,

View File

@@ -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 Relocation {
struct SectionDataEntry {
std::optional<uint32_t> UInt32;
yaml::BinaryRef Binary;
std::optional<object::coff_load_configuration32> LoadConfig32;
std::optional<object::coff_load_configuration64> LoadConfig64;
size_t size() const;
void writeAsBinary(raw_ostream &OS) const;
@@ -246,6 +249,18 @@ template <> struct MappingTraits<COFF::AuxiliaryCLRToken> {
static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT);
};
template <> struct MappingTraits<object::coff_load_configuration32> {
static void mapping(IO &IO, object::coff_load_configuration32 &ACT);
};
template <> struct MappingTraits<object::coff_load_configuration64> {
static void mapping(IO &IO, object::coff_load_configuration64 &ACT);
};
template <> struct MappingTraits<object::coff_load_config_code_integrity> {
static void mapping(IO &IO, object::coff_load_config_code_integrity &ACT);
};
template <>
struct MappingTraits<COFFYAML::Symbol> {
static void mapping(IO &IO, COFFYAML::Symbol &S);

View File

@@ -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 @@ struct COFFParser {
}
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 COFFYAML::SectionDataEntry::size() const {
size_t Size = Binary.binary_size();
if (UInt32)
Size += sizeof(*UInt32);
if (LoadConfig32)
Size += LoadConfig32->Size;
if (LoadConfig64)
Size += LoadConfig64->Size;
return Size;
}
template <typename T> static void writeLoadConfig(T &S, raw_ostream &OS) {
OS.write(reinterpret_cast<const char *>(&S),
std::min(sizeof(S), static_cast<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 {

View File

@@ -547,10 +547,100 @@ void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
}
void MappingTraits<object::coff_load_config_code_integrity>::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 <typename T, typename M>
void mapLoadConfigMember(IO &IO, T &LoadConfig, const char *Name, M &Member) {
// Map only members that match a specified size.
if (reinterpret_cast<char *>(&Member) -
reinterpret_cast<char *>(&LoadConfig) <
LoadConfig.Size)
IO.mapOptional(Name, Member);
}
template <typename T> void mapLoadConfig(IO &IO, T &LoadConfig) {
IO.mapOptional("Size", LoadConfig.Size,
support::ulittle32_t(sizeof(LoadConfig)));
// The size must be large enough to fit at least the size member itself.
if (LoadConfig.Size < sizeof(LoadConfig.Size)) {
IO.setError("Size must be at least " + Twine(sizeof(LoadConfig.Size)));
return;
}
#define MCase(X) mapLoadConfigMember(IO, LoadConfig, #X, LoadConfig.X)
MCase(TimeDateStamp);
MCase(MajorVersion);
MCase(MinorVersion);
MCase(GlobalFlagsClear);
MCase(GlobalFlagsSet);
MCase(CriticalSectionDefaultTimeout);
MCase(DeCommitFreeBlockThreshold);
MCase(DeCommitTotalFreeThreshold);
MCase(LockPrefixTable);
MCase(MaximumAllocationSize);
MCase(VirtualMemoryThreshold);
MCase(ProcessAffinityMask);
MCase(ProcessHeapFlags);
MCase(CSDVersion);
MCase(DependentLoadFlags);
MCase(EditList);
MCase(SecurityCookie);
MCase(SEHandlerTable);
MCase(SEHandlerCount);
MCase(GuardCFCheckFunction);
MCase(GuardCFCheckDispatch);
MCase(GuardCFFunctionTable);
MCase(GuardCFFunctionCount);
MCase(GuardFlags);
MCase(CodeIntegrity);
MCase(GuardAddressTakenIatEntryTable);
MCase(GuardAddressTakenIatEntryCount);
MCase(GuardLongJumpTargetTable);
MCase(GuardLongJumpTargetCount);
MCase(DynamicValueRelocTable);
MCase(CHPEMetadataPointer);
MCase(GuardRFFailureRoutine);
MCase(GuardRFFailureRoutineFunctionPointer);
MCase(DynamicValueRelocTableOffset);
MCase(DynamicValueRelocTableSection);
MCase(GuardRFVerifyStackPointerFunctionPointer);
MCase(HotPatchTableOffset);
MCase(EnclaveConfigurationPointer);
MCase(VolatileMetadataPointer);
MCase(GuardEHContinuationTable);
MCase(GuardEHContinuationCount);
MCase(GuardXFGCheckFunctionPointer);
MCase(GuardXFGDispatchFunctionPointer);
MCase(GuardXFGTableDispatchFunctionPointer);
MCase(CastGuardOsDeterminedFailureMode);
#undef MCase
}
void MappingTraits<object::coff_load_configuration32>::mapping(
IO &IO, object::coff_load_configuration32 &S) {
mapLoadConfig(IO, S);
}
void MappingTraits<object::coff_load_configuration64>::mapping(
IO &IO, object::coff_load_configuration64 &S) {
mapLoadConfig(IO, S);
}
void MappingTraits<COFFYAML::SectionDataEntry>::mapping(
IO &IO, COFFYAML::SectionDataEntry &E) {
IO.mapOptional("UInt32", E.UInt32);
IO.mapOptional("Binary", E.Binary);
COFF::header &H = *static_cast<COFF::header *>(IO.getContext());
if (COFF::is64Bit(H.Machine))
IO.mapOptional("LoadConfig", E.LoadConfig64);
else
IO.mapOptional("LoadConfig", E.LoadConfig32);
}
void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {

View File

@@ -39,7 +39,9 @@ sections:
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

View File

@@ -0,0 +1,320 @@
## Test all members of 64-bit load config.
# RUN: yaml2obj --docnum=1 %s -o %t
# RUN: llvm-readobj --coff-load-config %t | FileCheck %s --check-prefix=ALL
# ALL: Format: COFF-x86-64
# ALL-NEXT: Arch: x86_64
# ALL-NEXT: AddressSize: 64bit
# ALL-NEXT: LoadConfig [
# ALL-NEXT: Size: 0x150
# ALL-NEXT: TimeDateStamp: 1970-01-01 00:00:01 (0x1)
# ALL-NEXT: MajorVersion: 0x2
# ALL-NEXT: MinorVersion: 0x3
# ALL-NEXT: GlobalFlagsClear: 0x4
# ALL-NEXT: GlobalFlagsSet: 0x5
# ALL-NEXT: CriticalSectionDefaultTimeout: 0x6
# ALL-NEXT: DeCommitFreeBlockThreshold: 0x7
# ALL-NEXT: DeCommitTotalFreeThreshold: 0x8
# ALL-NEXT: LockPrefixTable: 0x9
# ALL-NEXT: MaximumAllocationSize: 0x100000
# ALL-NEXT: VirtualMemoryThreshold: 0x2000000
# ALL-NEXT: ProcessHeapFlags: 0x2
# ALL-NEXT: ProcessAffinityMask: 0x1
# ALL-NEXT: CSDVersion: 0x3
# ALL-NEXT: DependentLoadFlags: 0x4
# ALL-NEXT: EditList: 0x5
# ALL-NEXT: SecurityCookie: 0x6
# ALL-NEXT: SEHandlerTable: 0x0
# ALL-NEXT: SEHandlerCount: 0
# ALL-NEXT: GuardCFCheckFunction: 0x9
# ALL-NEXT: GuardCFCheckDispatch: 0x1
# ALL-NEXT: GuardCFFunctionTable: 0x0
# ALL-NEXT: GuardCFFunctionCount: 0
# ALL-NEXT: GuardFlags [ (0x4)
# ALL-NEXT: ]
# ALL-NEXT: GuardAddressTakenIatEntryTable: 0x0
# ALL-NEXT: GuardAddressTakenIatEntryCount: 0
# ALL-NEXT: GuardLongJumpTargetTable: 0x0
# ALL-NEXT: GuardLongJumpTargetCount: 0
# ALL-NEXT: DynamicValueRelocTable: 0x2
# ALL-NEXT: CHPEMetadataPointer: 0x0
# ALL-NEXT: GuardRFFailureRoutine: 0x4
# ALL-NEXT: GuardRFFailureRoutineFunctionPointer: 0x5
# ALL-NEXT: DynamicValueRelocTableOffset: 0x6
# ALL-NEXT: DynamicValueRelocTableSection: 7
# ALL-NEXT: GuardRFVerifyStackPointerFunctionPointer: 0x8
# ALL-NEXT: HotPatchTableOffset: 0x9
# ALL-NEXT: EnclaveConfigurationPointer: 0x1
# ALL-NEXT: VolatileMetadataPointer: 0x2
# ALL-NEXT: GuardEHContinuationTable: 0x0
# ALL-NEXT: GuardEHContinuationCount: 0
# ALL-NEXT: ]
--- !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: []
...
## Simple 32-bit load config.
# RUN: yaml2obj --docnum=2 %s -o %t
# RUN: llvm-readobj --coff-load-config %t | FileCheck %s --check-prefix=LOADCFG32
# LOADCFG32: LoadConfig [
# LOADCFG32: MaximumAllocationSize: 0x100000
# LOADCFG32: VirtualMemoryThreshold: 0x2000000
# LOADCFG32: 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: []
...
## Create load config with all fields using default values.
# RUN: yaml2obj --docnum=3 %s -o %t
# RUN: llvm-readobj --coff-load-config %t | FileCheck %s --check-prefix=DEF
# DEF: Format: COFF-x86-64
# DEF: Arch: x86_64
# DEF: AddressSize: 64bit
# DEF: LoadConfig [
# DEF: Size: 0x138
# DEF: MajorVersion: 0x0
# DEF: MinorVersion: 0x0
# DEF: GuardEHContinuationCount: 0
# DEF: ]
--- !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: []
...
## Create laod config larger than coff_load_configuration32 struct.
# RUN: yaml2obj --docnum=4 %s -o %t
# RUN: llvm-readobj --hex-dump=.rdata %t | FileCheck %s --check-prefix=LARGE
# LARGE: 0x00401000 d0000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401010 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401020 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401030 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401040 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401050 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401060 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401070 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401080 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x00401090 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x004010a0 00000000 00000000 00000000 00000000 ................
# LARGE-NEXT: 0x004010b0 00000000 00000000 ff000000 00000000 ................
# LARGE-NEXT: 0x004010c0 00000000 00000000 00000000 00000000 ................
# LARGE-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: []
...
## Try to specify load config field that barely fits the specified size.
# RUN: yaml2obj --docnum=5 %s -o %t
# RUN: llvm-readobj --hex-dump=.rdata %t | FileCheck %s --check-prefix=SMALL
# SMALL: 0x180001000 09000000 00000000 aaffffff ff
--- !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: 13
StructuredData:
- LoadConfig:
Size: 9
MajorVersion: 0xbbaa
- UInt32: 0xffffffff
symbols: []
...
## Try to specify load config field that does not fit specified size.
# RUN: not yaml2obj --docnum=6 %s -o %t 2>&1 | FileCheck %s --check-prefix=TOOSMALL
# TOOSMALL: error: unknown key 'MajorVersion'
--- !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: 8
MajorVersion: 10
symbols: []
...
## Set load config size to 0.
# RUN: not yaml2obj --docnum=7 %s -o %t 2>&1 | FileCheck %s --check-prefix=ZERO
# ZERO: error: Size must be at least 4
--- !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: 0
symbols: []
...