diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -14,13 +14,16 @@ #define LLVM_OBJECT_ELF_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFTypes.h" #include "llvm/Object/Error.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include "llvm/Support/raw_ostream.h" #include #include #include @@ -182,6 +185,7 @@ private: StringRef Buf; std::vector FakeSections; + llvm::SmallString<0> FakeSectionStrings; ELFFile(StringRef Object); @@ -648,8 +652,12 @@ Index = Sections[0].sh_link; } - if (!Index) // no section string table. + if (!Index) { + // no section string table. + if (!FakeSectionStrings.empty()) + return FakeSectionStrings; return ""; + } if (Index >= Sections.size()) return createError("section header string table index " + Twine(Index) + " does not exist"); @@ -770,17 +778,27 @@ if (!PhdrsOrErr) return; + int Idx = 0; + llvm::StringTableBuilder StrTab(llvm::StringTableBuilder::ELF); for (auto Phdr : *PhdrsOrErr) { - if (!(Phdr.p_type & ELF::PT_LOAD) || !(Phdr.p_flags & ELF::PF_X)) + if ((Phdr.p_type != ELF::PT_LOAD) || !(Phdr.p_flags & ELF::PF_X)) { + ++Idx; continue; + } Elf_Shdr FakeShdr = {}; FakeShdr.sh_type = ELF::SHT_PROGBITS; FakeShdr.sh_flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; FakeShdr.sh_addr = Phdr.p_vaddr; FakeShdr.sh_size = Phdr.p_memsz; FakeShdr.sh_offset = Phdr.p_offset; + // Create a section name based on the p_type and index + FakeShdr.sh_name = StrTab.add("PT_LOAD#" + std::to_string(Idx)); FakeSections.push_back(FakeShdr); + ++Idx; } + StrTab.finalizeInOrder(); + llvm::raw_svector_ostream Strs(FakeSectionStrings); + StrTab.write(Strs); } template diff --git a/llvm/test/Object/objdump-no-sectionheaders.test b/llvm/test/Object/objdump-no-sectionheaders.test --- a/llvm/test/Object/objdump-no-sectionheaders.test +++ b/llvm/test/Object/objdump-no-sectionheaders.test @@ -3,6 +3,5 @@ ; CHECK: Sections: ; CHECK-NEXT: Idx Name Size VMA Type -; CHECK-NEXT: 0 000006ec 0000000000400000 TEXT -; CHECK-NEXT: 1 00000000 0000000000000000 TEXT +; CHECK-NEXT: 0 PT_LOAD#2 000006ec 0000000000400000 TEXT ; CHECK-NOT: {{.}} diff --git a/llvm/test/tools/llvm-objdump/X86/disassemble-no-section.test b/llvm/test/tools/llvm-objdump/X86/disassemble-no-section.test --- a/llvm/test/tools/llvm-objdump/X86/disassemble-no-section.test +++ b/llvm/test/tools/llvm-objdump/X86/disassemble-no-section.test @@ -6,9 +6,9 @@ # RUN: yaml2obj %s -o %t # RUN: llvm-objdump -d %t | FileCheck %s -# CHECK: Disassembly of section : +# CHECK: Disassembly of section PT_LOAD#0: # CHECK-EMPTY: -# CHECK-NEXT: <>: +# CHECK-NEXT: : # CHECK-NEXT: 55 pushq %rbp # CHECK-NEXT: 48 89 e5 movq %rsp, %rbp # CHECK-NEXT: 0f 1f 40 00 nopl (%rax) @@ -22,9 +22,9 @@ # RANGE: no section overlaps the range # RANGE-EMPTY: -# RANGE-NEXT: Disassembly of section : +# RANGE-NEXT: Disassembly of section PT_LOAD#0: # RANGE-EMPTY: -# RANGE-NEXT: <>: +# RANGE-NEXT: : # RANGE-NEXT: 55 pushq %rbp # RANGE-NEXT: 48 89 e5 movq %rsp, %rbp # RANGE-EMPTY: diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2026,6 +2026,9 @@ } void objdump::printSectionHeaders(ObjectFile &Obj) { + if (Obj.isELF() && Obj.sections().empty()) + createFakeELFSections(Obj); + size_t NameWidth = getMaxSectionNameWidth(Obj); size_t AddressWidth = 2 * Obj.getBytesInAddress(); bool HasLMAColumn = shouldDisplayLMA(Obj); @@ -2038,9 +2041,6 @@ outs() << "Idx " << left_justify("Name", NameWidth) << " Size " << left_justify("VMA", AddressWidth) << " Type\n"; - if (Obj.isELF() && Obj.sections().empty()) - createFakeELFSections(Obj); - uint64_t Idx; for (const SectionRef &Section : ToolSectionFilter(Obj, &Idx)) { StringRef Name = unwrapOrError(Section.getName(), Obj.getFileName());