Index: test/tools/yaml2obj/elf-custom-null-section.yaml =================================================================== --- test/tools/yaml2obj/elf-custom-null-section.yaml +++ test/tools/yaml2obj/elf-custom-null-section.yaml @@ -42,18 +42,14 @@ Info: 0 Address: 0x0 -## Check we are still able to describe other sections too. +## Check we can redefine fields of the first SHT_NULL section. # RUN: yaml2obj --docnum=3 %s -o %t3 -# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=OTHER-SECTION +# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=REDEFINE -# OTHER-SECTION: Section Headers: -# OTHER-SECTION-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# OTHER-SECTION-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 -# OTHER-SECTION-NEXT: [ 1] foo PROGBITS 0000000000000000 000180 000000 00 0 0 0 -# OTHER-SECTION-NEXT: [ 2] .symtab SYMTAB 0000000000000000 000180 000018 18 3 1 8 -# OTHER-SECTION-NEXT: [ 3] .strtab STRTAB 0000000000000000 000198 000001 00 0 0 1 -# OTHER-SECTION-NEXT: [ 4] .shstrtab STRTAB 0000000000000000 000199 00001f 00 0 0 1 +# REDEFINE: Section Headers: +# REDEFINE-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# REDEFINE-NEXT: [ 0] .foo NULL 0000000000000006 000000 000002 03 A 4 5 1 --- !ELF FileHeader: @@ -63,23 +59,25 @@ Machine: EM_X86_64 Sections: - Type: SHT_NULL - Name: '' - Flags: [ ] - AddressAlign: 0x0 - Size: 0x0 - EntSize: 0x0 - Link: 0 - - Type: SHT_PROGBITS - Name: 'foo' - -## Check we can redefine sh_size and sh_link fields of the SHT_NULL section. + Name: .foo + Flags: [ SHF_ALLOC ] + AddressAlign: 0x1 + Size: 0x2 + EntSize: 0x3 + Link: 4 + Info: 5 + Address: 0x6 + +## Check that file size does not change if we redefine the Size +## of the first SHT_NULL section. # RUN: yaml2obj --docnum=4 %s -o %t4 -# RUN: llvm-readelf --sections %t4 | FileCheck %s --check-prefix=REDEFINE +# RUN: ls -l %t3 | tr -s ' ' | cut -d ' ' -f 5 > %t.txt +# RUN: ls -l %t4 | tr -s ' ' | cut -d ' ' -f 5 >> %t.txt +# RUN: FileCheck %s --input-file=%t.txt --check-prefix=SIZE -# REDEFINE: Section Headers: -# REDEFINE-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# REDEFINE-NEXT: [ 0] NULL 0000000000000000 000000 000123 00 1 0 0 +# SIZE: [[FILESIZE:.*]] +# SIZE: [[FILESIZE]] --- !ELF FileHeader: @@ -88,16 +86,28 @@ Type: ET_REL Machine: EM_X86_64 Sections: - - Type: SHT_NULL - Link: .foo - Size: 0x123 - - Type: SHT_PROGBITS - Name: .foo + - Type: SHT_NULL + Name: .foo + Flags: [ SHF_ALLOC ] + AddressAlign: 0x1 + Size: 0xFFFF + EntSize: 0x3 + Link: 4 + Info: 5 + Address: 0x6 -## The same as above, but using a number as a Link value. +## Check we are still able to describe other sections too. # RUN: yaml2obj --docnum=5 %s -o %t5 -# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=REDEFINE +# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=OTHER-SECTION + +# OTHER-SECTION: Section Headers: +# OTHER-SECTION-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# OTHER-SECTION-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 +# OTHER-SECTION-NEXT: [ 1] foo PROGBITS 0000000000000000 000180 000000 00 0 0 0 +# OTHER-SECTION-NEXT: [ 2] .symtab SYMTAB 0000000000000000 000180 000018 18 3 1 8 +# OTHER-SECTION-NEXT: [ 3] .strtab STRTAB 0000000000000000 000198 000001 00 0 0 1 +# OTHER-SECTION-NEXT: [ 4] .shstrtab STRTAB 0000000000000000 000199 00001f 00 0 0 1 --- !ELF FileHeader: @@ -106,11 +116,15 @@ Type: ET_REL Machine: EM_X86_64 Sections: - - Type: SHT_NULL - Link: 1 - Size: 0x123 + - Type: SHT_NULL + Name: '' + Flags: [ ] + AddressAlign: 0x0 + Size: 0x0 + EntSize: 0x0 + Link: 0 - Type: SHT_PROGBITS - Name: .foo + Name: 'foo' ## Check we report an error if null section sh_link field refers to an unknown section. @@ -150,7 +164,7 @@ # MULTIPLE: Section Headers: # MULTIPLE-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al # MULTIPLE-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 -# MULTIPLE-NEXT: [ 1] NULL 0000000000000123 000180 000020 10 A 1 2 0 +# MULTIPLE-NEXT: [ 1] .foo NULL 0000000000000123 000180 000020 10 A 1 2 0 --- !ELF FileHeader: @@ -161,9 +175,31 @@ Sections: - Type: SHT_NULL - Type: SHT_NULL + Name: .foo Flags: [ SHF_ALLOC ] Size: 0x20 EntSize: 0x10 Link: 1 Info: 2 Address: 0x123 + +## Check we can override the sh_offset/sh_size fields of the first SHT_NULL section if requested. + +# RUN: yaml2obj --docnum=9 %s -o %t9 +# RUN: llvm-readelf --sections %t9 | FileCheck %s --check-prefix=OVERRIDE + +# OVERRIDE: Section Headers: +# OVERRIDE-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# OVERRIDE-NEXT: [ 0] NULL 0000000000000000 000007 000008 00 0 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Type: SHT_NULL + Size: 0x2 + ShOffset: 0x7 + ShSize: 0x8 Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -247,7 +247,7 @@ ? (typename ELFT::uint)(*Doc.Header.SHOffset) : sizeof(Header) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size(); Header.e_shnum = - Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : SN2I.size() + 1; + Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : Doc.Sections.size(); Header.e_shstrndx = Doc.Header.SHStrNdx ? (uint16_t)*Doc.Header.SHStrNdx : SN2I.get(".shstrtab"); } @@ -327,30 +327,15 @@ SHeaders.resize(Doc.Sections.size()); for (size_t I = 0; I < Doc.Sections.size(); ++I) { - Elf_Shdr &SHeader = SHeaders[I]; ELFYAML::Section *Sec = Doc.Sections[I].get(); - - if (I == 0) { - if (Sec->IsImplicit) - continue; - - if (auto S = dyn_cast(Sec)) - if (S->Size) - SHeader.sh_size = *S->Size; - - if (!Sec->Link.empty()) { - unsigned Index; - if (!convertSectionIndex(SN2I, Sec->Name, Sec->Link, Index)) - return false; - SHeader.sh_link = Index; - } + if (I == 0 && Sec->IsImplicit) continue; - } // We have a few sections like string or symbol tables that are usually // added implicitly to the end. However, if they are explicitly specified // in the YAML, we need to write them here. This ensures the file offset // remains correct. + Elf_Shdr &SHeader = SHeaders[I]; if (initImplicitHeader(State, CBA, SHeader, Sec->Name, Sec->IsImplicit ? nullptr : Sec)) continue; @@ -372,7 +357,17 @@ SHeader.sh_link = Index; } - if (auto S = dyn_cast(Sec)) { + if (I == 0) { + if (auto RawSec = dyn_cast(Sec)) { + // We do not write any content for special SHN_UNDEF section. + if (RawSec->Size) + SHeader.sh_size = *RawSec->Size; + if (RawSec->Info) + SHeader.sh_info = *RawSec->Info; + } + if (Sec->EntSize) + SHeader.sh_entsize = *Sec->EntSize; + } else if (auto S = dyn_cast(Sec)) { if (!writeSectionContent(SHeader, *S, CBA)) return false; } else if (auto S = dyn_cast(Sec)) { @@ -966,8 +961,11 @@ } template bool ELFState::buildSectionIndex() { - for (unsigned I = 1, E = Doc.Sections.size(); I != E; ++I) { + for (unsigned I = 0, E = Doc.Sections.size(); I != E; ++I) { StringRef Name = Doc.Sections[I]->Name; + if (Name.empty()) + continue; + DotShStrtab.add(dropUniqueSuffix(Name)); if (!SN2I.addName(Name, I)) { WithColor::error() << "Repeated section name: '" << Name