Index: llvm/trunk/test/tools/obj2yaml/elf-null-section.yaml =================================================================== --- llvm/trunk/test/tools/obj2yaml/elf-null-section.yaml +++ llvm/trunk/test/tools/obj2yaml/elf-null-section.yaml @@ -0,0 +1,143 @@ +## Check we are able to dump the SHT_NULL section at +## index 0 when it has custom section fields. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=FIRST-SEC + +# FIRST-SEC: --- !ELF +# FIRST-SEC-NEXT: FileHeader: +# FIRST-SEC-NEXT: Class: ELFCLASS64 +# FIRST-SEC-NEXT: Data: ELFDATA2LSB +# FIRST-SEC-NEXT: Type: ET_REL +# FIRST-SEC-NEXT: Machine: EM_X86_64 +# FIRST-SEC-NEXT: Sections: +# FIRST-SEC-NEXT: - Type: SHT_NULL +# FIRST-SEC-NEXT: Flags: [ SHF_ALLOC ] +# FIRST-SEC-NEXT: Address: 0x0000000000000006 +# FIRST-SEC-NEXT: Link: .foo +# FIRST-SEC-NEXT: AddressAlign: 0x0000000000000003 +# FIRST-SEC-NEXT: EntSize: 0x0000000000000005 +# FIRST-SEC-NEXT: Size: 0x0000000000000004 +# FIRST-SEC-NEXT: Info: 0x0000000000000002 +# FIRST-SEC-NEXT: - Name: .foo +# FIRST-SEC-NEXT: Type: SHT_PROGBITS +# FIRST-SEC-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Type: SHT_NULL + Name: '' + Flags: [ SHF_ALLOC ] + Link: 1 + Info: 2 + AddressAlign: 0x3 + Size: 0x4 + EntSize: 0x5 + Address: 0x6 + - Type: SHT_PROGBITS + Name: .foo + +## Check we are able to dump the SHT_NULL section with a non-zero index. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=SECOND-SEC + +# SECOND-SEC: --- !ELF +# SECOND-SEC-NEXT: FileHeader: +# SECOND-SEC-NEXT: Class: ELFCLASS64 +# SECOND-SEC-NEXT: Data: ELFDATA2LSB +# SECOND-SEC-NEXT: Type: ET_REL +# SECOND-SEC-NEXT: Machine: EM_X86_64 +# SECOND-SEC-NEXT: Sections: +# SECOND-SEC-NEXT: - Name: .foo +# SECOND-SEC-NEXT: Type: SHT_PROGBITS +# SECOND-SEC-NEXT: - Type: SHT_NULL +# SECOND-SEC-NEXT: Flags: [ SHF_ALLOC ] +# SECOND-SEC-NEXT: Address: 0x0000000000000006 +# SECOND-SEC-NEXT: Link: .foo +# SECOND-SEC-NEXT: AddressAlign: 0x0000000000000003 +# SECOND-SEC-NEXT: EntSize: 0x0000000000000005 +# SECOND-SEC-NEXT: Content: '00000000' +# SECOND-SEC-NEXT: Info: 0x0000000000000002 +# SECOND-SEC-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Type: SHT_PROGBITS + Name: .foo + - Type: SHT_NULL + Name: '' + Flags: [ SHF_ALLOC ] + Link: 1 + Info: 2 + AddressAlign: 0x3 + Size: 0x4 + EntSize: 0x5 + Address: 0x6 + +## Check we do not dump the SHT_NULL section with index 0 +## when it does not have any custom fields. + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=NULL-SEC + +# NULL-SEC: --- !ELF +# NULL-SEC-NEXT: FileHeader: +# NULL-SEC-NEXT: Class: ELFCLASS64 +# NULL-SEC-NEXT: Data: ELFDATA2LSB +# NULL-SEC-NEXT: Type: ET_REL +# NULL-SEC-NEXT: Machine: EM_X86_64 +# NULL-SEC-NEXT: Sections: +# NULL-SEC-NEXT: - Name: .foo +# NULL-SEC-NEXT: Type: SHT_PROGBITS +# NULL-SEC-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Type: SHT_NULL + - Type: SHT_PROGBITS + Name: .foo + +## Check we dump SHT_NULL sections which are not at the beginning +## of the section list even if they don't have any non-null fields. + +# RUN: yaml2obj --docnum=4 %s -o %t4 +# RUN: obj2yaml %t4 | FileCheck %s --check-prefix=NULL-SEC-MIDDLE + +# NULL-SEC-MIDDLE: --- !ELF +# NULL-SEC-MIDDLE-NEXT: FileHeader: +# NULL-SEC-MIDDLE-NEXT: Class: ELFCLASS64 +# NULL-SEC-MIDDLE-NEXT: Data: ELFDATA2LSB +# NULL-SEC-MIDDLE-NEXT: Type: ET_REL +# NULL-SEC-MIDDLE-NEXT: Machine: EM_X86_64 +# NULL-SEC-MIDDLE-NEXT: Sections: +# NULL-SEC-MIDDLE-NEXT: - Name: .foo +# NULL-SEC-MIDDLE-NEXT: Type: SHT_PROGBITS +# NULL-SEC-MIDDLE-NEXT: - Type: SHT_NULL +# NULL-SEC-MIDDLE-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Type: SHT_PROGBITS + Name: .foo + - Type: SHT_NULL Index: llvm/trunk/tools/obj2yaml/elf2yaml.cpp =================================================================== --- llvm/trunk/tools/obj2yaml/elf2yaml.cpp +++ llvm/trunk/tools/obj2yaml/elf2yaml.cpp @@ -176,7 +176,6 @@ Y->Sections.emplace_back(*SecOrErr); break; } - case ELF::SHT_NULL: case ELF::SHT_STRTAB: case ELF::SHT_SYMTAB: case ELF::SHT_DYNSYM: @@ -239,6 +238,18 @@ Y->Sections.emplace_back(*SecOrErr); break; } + case ELF::SHT_NULL: { + // We only dump the SHT_NULL section at index 0 when it + // has at least one non-null field, because yaml2obj + // normally creates the zero section at index 0 implicitly. + if (&Sec == &Sections[0]) { + const uint8_t *Begin = reinterpret_cast(&Sec); + const uint8_t *End = Begin + sizeof(Elf_Shdr); + if (std::find_if(Begin, End, [](uint8_t V) { return V != 0; }) == End) + break; + } + LLVM_FALLTHROUGH; + } default: { Expected SecOrErr = dumpContentSection(&Sec); @@ -471,12 +482,18 @@ if (Error E = dumpCommonSection(Shdr, *S)) return std::move(E); - auto ContentOrErr = Obj.getSectionContents(Shdr); - if (!ContentOrErr) - return ContentOrErr.takeError(); - ArrayRef Content = *ContentOrErr; - if (!Content.empty()) - S->Content = yaml::BinaryRef(Content); + unsigned SecIndex = Shdr - &Sections[0]; + if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) { + auto ContentOrErr = Obj.getSectionContents(Shdr); + if (!ContentOrErr) + return ContentOrErr.takeError(); + ArrayRef Content = *ContentOrErr; + if (!Content.empty()) + S->Content = yaml::BinaryRef(Content); + } else { + S->Size = static_cast(Shdr->sh_size); + } + if (Shdr->sh_info) S->Info = static_cast(Shdr->sh_info); return S.release();