From 242da4e83eff12b1eac2f82bb1bd52a83a43184d Mon Sep 17 00:00:00 2001 From: George Rimar Date: Wed, 24 Jul 2019 12:16:22 +0000 Subject: [PATCH] [yaml2obj] - Allow custom fields for the SHT_UNDEF sections. This is a follow-up refactoring patch for recently introduced functionality which which reduces the code duplication and also makes possible to redefine all possible fields of the first SHT_NULL section (previously it was only possible to set sh_link and sh_size). Differential revision: https://reviews.llvm.org/D65140 llvm-svn: 366894 --- .../tools/yaml2obj/elf-custom-null-section.yaml | 106 ++++++++++++++------- llvm/tools/yaml2obj/yaml2elf.cpp | 38 ++++---- 2 files changed, 89 insertions(+), 55 deletions(-) diff --git a/llvm/test/tools/yaml2obj/elf-custom-null-section.yaml b/llvm/test/tools/yaml2obj/elf-custom-null-section.yaml index 23b877f..17b4f28 100644 --- a/llvm/test/tools/yaml2obj/elf-custom-null-section.yaml +++ b/llvm/test/tools/yaml2obj/elf-custom-null-section.yaml @@ -42,18 +42,14 @@ Sections: 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 @@ FileHeader: 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: stat %t3 > %t.txt +# RUN: stat %t4 >> %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: Size: [[FILESIZE:.*]] +# SIZE: Size: [[FILESIZE]] --- !ELF FileHeader: @@ -88,16 +86,28 @@ FileHeader: 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 @@ FileHeader: 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 @@ Sections: # 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 @@ FileHeader: 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 diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp index c6be508..e11d8fe 100644 --- a/llvm/tools/yaml2obj/yaml2elf.cpp +++ b/llvm/tools/yaml2obj/yaml2elf.cpp @@ -247,7 +247,7 @@ void ELFState::initELFHeader(Elf_Ehdr &Header) { ? (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 @@ bool ELFState::initSectionHeaders(ELFState &State, 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 @@ bool ELFState::initSectionHeaders(ELFState &State, 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 @@ bool ELFState::writeSectionContent(Elf_Shdr &SHeader, } 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 -- 2.7.4