Index: include/llvm/Support/YAMLTraits.h =================================================================== --- include/llvm/Support/YAMLTraits.h +++ include/llvm/Support/YAMLTraits.h @@ -982,7 +982,7 @@ // These are only used by operator>>. They could be private // if those templated things could be made friends. bool setCurrentDocument(); - void nextDocument(); + bool nextDocument(); private: llvm::SourceMgr SrcMgr; // must be before Strm Index: lib/Support/YAMLTraits.cpp =================================================================== --- lib/Support/YAMLTraits.cpp +++ lib/Support/YAMLTraits.cpp @@ -90,8 +90,8 @@ return false; } -void Input::nextDocument() { - ++DocIterator; +bool Input::nextDocument() { + return ++DocIterator != Strm->end(); } bool Input::mapTag(StringRef Tag, bool Default) { Index: test/Object/yaml2obj-coff-multi-doc.test =================================================================== --- /dev/null +++ test/Object/yaml2obj-coff-multi-doc.test @@ -0,0 +1,91 @@ +# RUN: yaml2obj -format=coff -docnum=1 %s \ +# RUN: | llvm-readobj -symbols - | FileCheck -check-prefix=DOC1 %s +# RUN: yaml2obj -format=coff -docnum=2 %s \ +# RUN: | llvm-readobj -symbols - | FileCheck -check-prefix=DOC2 %s +# RUN: not yaml2obj -format=coff -docnum=3 %s 2>&1 \ +# RUN: | FileCheck -check-prefix=DOC3 %s + +# DOC1: Name: _sym1 +# DOC2: Name: _sym2 +# DOC3: yaml2obj: Cannot find document number '3'! + +--- +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ IMAGE_FILE_DEBUG_STRIPPED ] + +sections: + - Name: .text + Alignment: 16 + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, + IMAGE_SCN_MEM_READ ] + SectionData: "00000000" + +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 36 + NumberOfRelocations: 3 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 1 + + - Name: _main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + + - Name: _sym1 + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + +--- +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ IMAGE_FILE_DEBUG_STRIPPED ] + +sections: + - Name: .text + Alignment: 16 + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, + IMAGE_SCN_MEM_READ ] + SectionData: "00000000" + +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 36 + NumberOfRelocations: 3 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 1 + + - Name: _main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + + - Name: _sym2 + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: test/Object/yaml2obj-elf-multi-doc.test =================================================================== --- /dev/null +++ test/Object/yaml2obj-elf-multi-doc.test @@ -0,0 +1,56 @@ +# RUN: yaml2obj -format=elf -docnum=1 %s \ +# RUN: | llvm-readobj -symbols - | FileCheck -check-prefix=DOC1 %s +# RUN: yaml2obj -format=elf -docnum=2 %s \ +# RUN: | llvm-readobj -symbols - | FileCheck -check-prefix=DOC2 %s +# RUN: not yaml2obj -format=elf -docnum=3 %s 2>&1 \ +# RUN: | FileCheck -check-prefix=DOC3 %s + +# DOC1: Name: T1 (1) +# DOC2: Name: T2 (1) +# DOC3: yaml2obj: Cannot find document number '3'! + +--- !ELF +FileHeader: !FileHeader + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_CPIC] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "0000000000000000" + AddressAlign: 16 + Flags: [SHF_EXECINSTR, SHF_ALLOC] + +Symbols: + Global: + - Name: T1 + Section: .text + Type: STT_FUNC + Value: 0x0 + Size: 8 + +--- !ELF +FileHeader: !FileHeader + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "00000000" + AddressAlign: 16 + Flags: [SHF_EXECINSTR, SHF_ALLOC] + +Symbols: + Global: + - Name: T2 + Section: .text + Type: STT_FUNC + Value: 0x0 + Size: 4 +... Index: tools/yaml2obj/yaml2coff.cpp =================================================================== --- tools/yaml2obj/yaml2coff.cpp +++ tools/yaml2obj/yaml2coff.cpp @@ -327,28 +327,37 @@ return true; } -int yaml2coff(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf) { +int yaml2coff(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf, + unsigned DocNum) { yaml::Input YIn(Buf->getBuffer()); - COFFYAML::Object Doc; - YIn >> Doc; - if (YIn.error()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; - return 1; - } - COFFParser CP(Doc); - if (!CP.parse()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; - return 1; - } + unsigned CurNum = 0; + do { + COFFYAML::Object Doc; + YIn >> Doc; + if (YIn.error()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } + if (++CurNum == DocNum) { + COFFParser CP(Doc); + if (!CP.parse()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } - if (!layoutCOFF(CP)) { - errs() << "yaml2obj: Failed to layout COFF file!\n"; - return 1; - } - if (!writeCOFF(CP, Out)) { - errs() << "yaml2obj: Failed to write COFF file!\n"; - return 1; - } - return 0; + if (!layoutCOFF(CP)) { + errs() << "yaml2obj: Failed to layout COFF file!\n"; + return 1; + } + if (!writeCOFF(CP, Out)) { + errs() << "yaml2obj: Failed to write COFF file!\n"; + return 1; + } + return 0; + } + } while (YIn.nextDocument()); + + errs() << "yaml2obj: Cannot find document number '" << DocNum << "'!\n"; + return 1; } Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -467,14 +467,7 @@ return Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); } -int yaml2elf(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf) { - yaml::Input YIn(Buf->getBuffer()); - ELFYAML::Object Doc; - YIn >> Doc; - if (YIn.error()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; - return 1; - } +static int writeELF(raw_ostream &Out, const ELFYAML::Object &Doc) { using object::ELFType; typedef ELFType LE64; typedef ELFType BE64; @@ -492,3 +485,22 @@ return ELFState::writeELF(Out, Doc); } } + +int yaml2elf(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf, unsigned DocNum) { + yaml::Input YIn(Buf->getBuffer()); + + unsigned CurNum = 0; + do { + ELFYAML::Object Doc; + YIn >> Doc; + if (YIn.error()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } + if (++CurNum == DocNum) + return writeELF(Out, Doc); + } while (YIn.nextDocument()); + + errs() << "yaml2obj: Cannot find document number '" << DocNum << "'!\n"; + return 1; +} Index: tools/yaml2obj/yaml2obj.h =================================================================== --- tools/yaml2obj/yaml2obj.h +++ tools/yaml2obj/yaml2obj.h @@ -16,7 +16,7 @@ class raw_ostream; class MemoryBuffer; } -int yaml2coff(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf); -int yaml2elf(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf); +int yaml2coff(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf, unsigned DocNum); +int yaml2elf(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf, unsigned DocNum); #endif Index: tools/yaml2obj/yaml2obj.cpp =================================================================== --- tools/yaml2obj/yaml2obj.cpp +++ tools/yaml2obj/yaml2obj.cpp @@ -51,6 +51,10 @@ clEnumValN(YOF_ELF, "elf", "ELF object file format"), clEnumValEnd)); +cl::opt +DocNum("docnum", cl::init(1), + cl::desc("Read specified document from input (default = 1)")); + static cl::opt OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); @@ -77,9 +81,9 @@ int Res = 1; if (Format == YOF_COFF) - Res = yaml2coff(Out->os(), Buf.get()); + Res = yaml2coff(Out->os(), Buf.get(), DocNum); else if (Format == YOF_ELF) - Res = yaml2elf(Out->os(), Buf.get()); + Res = yaml2elf(Out->os(), Buf.get(), DocNum); else errs() << "Not yet implemented\n";