Index: llvm/lib/ObjectYAML/COFFEmitter.cpp =================================================================== --- llvm/lib/ObjectYAML/COFFEmitter.cpp +++ llvm/lib/ObjectYAML/COFFEmitter.cpp @@ -170,8 +170,8 @@ unsigned PEHeaderSize = CP.is64Bit() ? sizeof(object::pe32plus_header) : sizeof(object::pe32_header); CP.Obj.Header.SizeOfOptionalHeader = - PEHeaderSize + - sizeof(object::data_directory) * (COFF::NUM_DATA_DIRECTORIES + 1); + PEHeaderSize + sizeof(object::data_directory) * + CP.Obj.OptionalHeader->Header.NumberOfRvaAndSize; return true; } @@ -397,7 +397,7 @@ Header->SizeOfStackCommit = CP.Obj.OptionalHeader->Header.SizeOfStackCommit; Header->SizeOfHeapReserve = CP.Obj.OptionalHeader->Header.SizeOfHeapReserve; Header->SizeOfHeapCommit = CP.Obj.OptionalHeader->Header.SizeOfHeapCommit; - Header->NumberOfRvaAndSize = COFF::NUM_DATA_DIRECTORIES + 1; + Header->NumberOfRvaAndSize = CP.Obj.OptionalHeader->Header.NumberOfRvaAndSize; return BaseOfData; } @@ -458,8 +458,11 @@ PEH.BaseOfData = BaseOfData; OS.write(reinterpret_cast(&PEH), sizeof(PEH)); } + uint32_t NumDir = 0; for (const Optional &DD : CP.Obj.OptionalHeader->DataDirectories) { + if (NumDir++ >= CP.Obj.OptionalHeader->Header.NumberOfRvaAndSize) + break; if (!DD.hasValue()) { OS << zeros(uint32_t(0)); OS << zeros(uint32_t(0)); @@ -468,8 +471,10 @@ OS << binary_le(DD->Size); } } - OS << zeros(uint32_t(0)); - OS << zeros(uint32_t(0)); + if (NumDir < CP.Obj.OptionalHeader->Header.NumberOfRvaAndSize) { + OS << zeros(uint32_t(0)); + OS << zeros(uint32_t(0)); + } } assert(OS.tell() == CP.SectionTableStart); Index: llvm/lib/ObjectYAML/COFFYAML.cpp =================================================================== --- llvm/lib/ObjectYAML/COFFYAML.cpp +++ llvm/lib/ObjectYAML/COFFYAML.cpp @@ -467,6 +467,8 @@ IO.mapRequired("SizeOfHeapReserve", PH.Header.SizeOfHeapReserve); IO.mapRequired("SizeOfHeapCommit", PH.Header.SizeOfHeapCommit); + IO.mapOptional("NumberOfRvaAndSize", PH.Header.NumberOfRvaAndSize, + COFF::NUM_DATA_DIRECTORIES + 1); IO.mapOptional("ExportTable", PH.DataDirectories[COFF::EXPORT_TABLE]); IO.mapOptional("ImportTable", PH.DataDirectories[COFF::IMPORT_TABLE]); IO.mapOptional("ResourceTable", PH.DataDirectories[COFF::RESOURCE_TABLE]); Index: llvm/test/tools/yaml2obj/COFF/variable-number-rva.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/COFF/variable-number-rva.yaml @@ -0,0 +1,86 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --file-headers %t | FileCheck %s +# RUN: obj2yaml %t | FileCheck %s --check-prefix=ROUNDTRIP + +# CHECK: NumberOfRvaAndSize: 6 +# CHECK-NEXT: DataDirectory { +# CHECK-NEXT: ExportTableRVA: 0x0 +# CHECK-NEXT: ExportTableSize: 0x0 +# CHECK-NEXT: ImportTableRVA: 0x0 +# CHECK-NEXT: ImportTableSize: 0x0 +# CHECK-NEXT: ResourceTableRVA: 0x0 +# CHECK-NEXT: ResourceTableSize: 0x0 +# CHECK-NEXT: ExceptionTableRVA: 0x0 +# CHECK-NEXT: ExceptionTableSize: 0x0 +# CHECK-NEXT: CertificateTableRVA: 0x0 +# CHECK-NEXT: CertificateTableSize: 0x0 +# CHECK-NEXT: BaseRelocationTableRVA: 0x0 +# CHECK-NEXT: BaseRelocationTableSize: 0x0 +# CHECK-NEXT: } + +# ROUNDTRIP: NumberOfRvaAndSize: 6 +# ROUNDTRIP-NEXT: ExportTable: +# ROUNDTRIP-NEXT: RelativeVirtualAddress: 0 +# ROUNDTRIP-NEXT: Size: 0 +# ROUNDTRIP-NEXT: ImportTable: +# ROUNDTRIP-NEXT: RelativeVirtualAddress: 0 +# ROUNDTRIP-NEXT: Size: 0 +# ROUNDTRIP-NEXT: ResourceTable: +# ROUNDTRIP-NEXT: RelativeVirtualAddress: 0 +# ROUNDTRIP-NEXT: Size: 0 +# ROUNDTRIP-NEXT: ExceptionTable: +# ROUNDTRIP-NEXT: RelativeVirtualAddress: 0 +# ROUNDTRIP-NEXT: Size: 0 +# ROUNDTRIP-NEXT: CertificateTable: +# ROUNDTRIP-NEXT: RelativeVirtualAddress: 0 +# ROUNDTRIP-NEXT: Size: 0 +# ROUNDTRIP-NEXT: BaseRelocationTable: +# ROUNDTRIP-NEXT: RelativeVirtualAddress: 0 +# ROUNDTRIP-NEXT: Size: 0 + +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 4096 + ImageBase: 0 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 0 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 0 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_EFI_APPLICATION + DLLCharacteristics: [ ] + SizeOfStackReserve: 0 + SizeOfStackCommit: 0 + SizeOfHeapReserve: 0 + SizeOfHeapCommit: 0 + NumberOfRvaAndSize: 6 + ExportTable: + RelativeVirtualAddress: 0 + Size: 0 + ImportTable: + RelativeVirtualAddress: 0 + Size: 0 + ResourceTable: + RelativeVirtualAddress: 0 + Size: 0 + ExceptionTable: + RelativeVirtualAddress: 0 + Size: 0 + CertificateTable: + RelativeVirtualAddress: 0 + Size: 0 + BaseRelocationTable: + RelativeVirtualAddress: 0 + Size: 0 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: foo + Characteristics: [ ] + Alignment: 4 +symbols: +... Index: llvm/tools/obj2yaml/coff2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/coff2yaml.cpp +++ llvm/tools/obj2yaml/coff2yaml.cpp @@ -80,6 +80,8 @@ OptionalHeader->SizeOfHeapReserve; YAMLObj.OptionalHeader->Header.SizeOfHeapCommit = OptionalHeader->SizeOfHeapCommit; + YAMLObj.OptionalHeader->Header.NumberOfRvaAndSize = + OptionalHeader->NumberOfRvaAndSize; unsigned I = 0; for (auto &DestDD : YAMLObj.OptionalHeader->DataDirectories) { const object::data_directory *DD = Obj.getDataDirectory(I++);