diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index b45507920a9..df0aa500c8a 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/include/llvm/Object/ELFYAML.h @@ -85,7 +85,13 @@ struct SectionOrType { }; struct Section { - enum class SectionKind { Group, RawContent, Relocation, MipsABIFlags }; + enum class SectionKind { + Group, + RawContent, + Relocation, + NoBits, + MipsABIFlags + }; SectionKind Kind; StringRef Name; ELF_SHT Type; @@ -106,6 +112,14 @@ struct RawContentSection : Section { } }; +struct NoBitsSection : Section { + llvm::yaml::Hex64 Size; + NoBitsSection() : Section(SectionKind::NoBits) {} + static bool classof(const Section *S) { + return S->Kind == SectionKind::NoBits; + } +}; + struct Group : Section { // Members of a group contain a flag and a list of section indices // that are part of the group. diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp index ecdd468305b..72c232c3287 100644 --- a/lib/Object/ELFYAML.cpp +++ b/lib/Object/ELFYAML.cpp @@ -627,6 +627,11 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size())); } +static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Size", Section.Size, Hex64(0)); +} + static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Relocations", Section.Relocations); @@ -682,6 +687,11 @@ void MappingTraits>::mapping( Section.reset(new ELFYAML::Group()); groupSectionMapping(IO, *cast(Section.get())); break; + case ELF::SHT_NOBITS: + if (!IO.outputting()) + Section.reset(new ELFYAML::NoBitsSection()); + sectionMapping(IO, *cast(Section.get())); + break; case ELF::SHT_MIPS_ABIFLAGS: if (!IO.outputting()) Section.reset(new ELFYAML::MipsABIFlags()); diff --git a/test/Object/obj2yaml.test b/test/Object/obj2yaml.test index 08000f66581..8054b23eb56 100644 --- a/test/Object/obj2yaml.test +++ b/test/Object/obj2yaml.test @@ -234,7 +234,7 @@ ELF-MIPSEL-NEXT: - Name: .bss ELF-MIPSEL-NEXT: Type: SHT_NOBITS ELF-MIPSEL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] ELF-MIPSEL-NEXT: AddressAlign: 0x0000000000000004 -ELF-MIPSEL-NEXT: Content: 48656C6C +ELF-MIPSEL-NEXT: Size: 0x0000000000000004 ELF-MIPSEL-NEXT: - Name: .mdebug.abi32 ELF-MIPSEL-NEXT: Type: SHT_PROGBITS ELF-MIPSEL-NEXT: AddressAlign: 0x0000000000000001 @@ -324,7 +324,6 @@ ELF-MIPS64EL-NEXT: - Name: .bss ELF-MIPS64EL-NEXT: Type: SHT_NOBITS ELF-MIPS64EL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] ELF-MIPS64EL-NEXT: AddressAlign: 0x0000000000000010 -ELF-MIPS64EL-NEXT: Content: '' ELF-MIPS64EL-NEXT: - Name: .MIPS.options ELF-MIPS64EL-NEXT: Type: SHT_MIPS_OPTIONS ELF-MIPS64EL-NEXT: Flags: [ SHF_ALLOC ] diff --git a/test/Object/yaml2obj-elf-rel-noref.yaml b/test/Object/yaml2obj-elf-rel-noref.yaml index 69fcf085443..4a13acd1fd3 100644 --- a/test/Object/yaml2obj-elf-rel-noref.yaml +++ b/test/Object/yaml2obj-elf-rel-noref.yaml @@ -32,7 +32,7 @@ Sections: Type: SHT_NOBITS Flags: [ SHF_WRITE, SHF_ALLOC ] AddressAlign: 0x0000000000000001 - Content: '' + Size: 0 - Name: .ARM.attributes Type: SHT_ARM_ATTRIBUTES AddressAlign: 0x0000000000000001 diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index 9afcedef639..f117a10d382 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -40,6 +40,7 @@ class ELFDumper { ErrorOr dumpRelaSection(const Elf_Shdr *Shdr); ErrorOr dumpContentSection(const Elf_Shdr *Shdr); + ErrorOr dumpNoBitsSection(const Elf_Shdr *Shdr); ErrorOr dumpGroup(const Elf_Shdr *Shdr); ErrorOr dumpMipsABIFlags(const Elf_Shdr *Shdr); @@ -104,6 +105,13 @@ ErrorOr ELFDumper::dump() { Y->Sections.push_back(std::unique_ptr(G.get())); break; } + case ELF::SHT_NOBITS: { + ErrorOr S = dumpNoBitsSection(&Sec); + if (std::error_code EC = S.getError()) + return EC; + Y->Sections.push_back(std::unique_ptr(S.get())); + break; + } default: { ErrorOr S = dumpContentSection(&Sec); if (std::error_code EC = S.getError()) @@ -304,6 +312,18 @@ ELFDumper::dumpContentSection(const Elf_Shdr *Shdr) { return S.release(); } +template +ErrorOr +ELFDumper::dumpNoBitsSection(const Elf_Shdr *Shdr) { + auto S = make_unique(); + + if (std::error_code EC = dumpCommonSection(Shdr, *S)) + return EC; + S->Size = Shdr->sh_size; + + return S.release(); +} + template ErrorOr ELFDumper::dumpGroup(const Elf_Shdr *Shdr) { auto S = make_unique(); diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 772b5b918ec..2cbc3380358 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -241,6 +241,12 @@ bool ELFState::initSectionHeaders(std::vector &SHeaders, } else if (auto S = dyn_cast(Sec.get())) { if (!writeSectionContent(SHeader, *S, CBA)) return false; + } else if (auto S = dyn_cast(Sec.get())) { + SHeader.sh_entsize = 0; + SHeader.sh_size = S->Size; + // SHT_NOBITS section does not have content + // so just to setup the section offset. + CBA.getOSAndAlignedOffset(SHeader.sh_offset); } else llvm_unreachable("Unknown section type");