diff --git a/llvm/test/tools/llvm-readobj/ELF/many-sections.s b/llvm/test/tools/llvm-readobj/ELF/many-sections.s --- a/llvm/test/tools/llvm-readobj/ELF/many-sections.s +++ b/llvm/test/tools/llvm-readobj/ELF/many-sections.s @@ -35,15 +35,14 @@ # RUN: llvm-readelf --file-headers --sections %t2 2>&1 | \ # RUN: FileCheck %s -DFILE=%t2 --check-prefix=GNU2 +# RUN: llvm-readelf --file-headers --section-details %t2 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2 --check-prefix=GNU2 # GNU2: Number of section headers: 0 # GNU2: Section header string table index: 65535 (corrupt: out of range) -# GNU2: There are 0 section headers, starting at offset 0x0: # GNU2-EMPTY: -# GNU2-NEXT: Section Headers: -# GNU2-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# GNU2: There are no sections in this file. # GNU2-NEXT: warning: '[[FILE]]': e_shstrndx == SHN_XINDEX, but the section header table is empty -# GNU2-NEXT: Key to Flags: # RUN: llvm-readobj --file-headers --sections %t2 | \ # RUN: FileCheck %s --check-prefix=LLVM2 --implicit-check-not="warning:" diff --git a/llvm/test/tools/llvm-readobj/ELF/no-phdrs.test b/llvm/test/tools/llvm-readobj/ELF/no-phdrs.test --- a/llvm/test/tools/llvm-readobj/ELF/no-phdrs.test +++ b/llvm/test/tools/llvm-readobj/ELF/no-phdrs.test @@ -8,9 +8,7 @@ # LLVM: ProgramHeaders [ # LLVM-NEXT: ] -# GNU: There are 0 program headers -# GNU: Program Headers: -# GNU-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# GNU: There are no program headers in this file. # GNU-EMPTY: # GNU-NEXT: Section to Segment mapping: # GNU-NEXT: Segment Sections... diff --git a/llvm/test/tools/llvm-readobj/ELF/no-shdrs.test b/llvm/test/tools/llvm-readobj/ELF/no-shdrs.test --- a/llvm/test/tools/llvm-readobj/ELF/no-shdrs.test +++ b/llvm/test/tools/llvm-readobj/ELF/no-shdrs.test @@ -5,6 +5,7 @@ # RUN: llvm-objcopy --strip-sections %t.raw %t.o # RUN: llvm-readobj --file-headers --section-headers --symbols %t.o | FileCheck %s --check-prefix=LLVM # RUN: llvm-readelf --file-headers --section-headers --symbols %t.o | FileCheck %s --check-prefix=GNU --allow-empty +# RUN: llvm-readelf --file-headers --section-details --symbols %t.o | FileCheck %s --check-prefix=GNU --allow-empty # LLVM: SectionHeaderCount: 0 # LLVM: StringTableSectionIndex: 0 @@ -15,7 +16,8 @@ # GNU: Number of section headers: 0 # GNU: Section header string table index: 0 -# GNU: There are 0 section headers +# GNU-EMPTY: +# GNU: There are no sections in this file. # GNU-NOT: Symbol table '{{.*}}' contains {{.*}} entries --- !ELF diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3681,8 +3681,16 @@ } template void GNUELFDumper::printSectionHeaders() { - unsigned Bias = ELFT::Is64Bits ? 0 : 8; ArrayRef Sections = cantFail(this->Obj.sections()); + if (Sections.empty()) { + OS << "\nThere are no sections in this file.\n"; + Expected SecStrTableOrErr = + this->Obj.getSectionStringTable(Sections, this->WarningHandler); + if (!SecStrTableOrErr) + this->reportUniqueWarning(SecStrTableOrErr.takeError()); + return; + } + unsigned Bias = ELFT::Is64Bits ? 0 : 8; OS << "There are " << to_string(Sections.size()) << " section headers, starting at offset " << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n"; @@ -4062,6 +4070,14 @@ template void GNUELFDumper::printSectionDetails() { ArrayRef Sections = cantFail(this->Obj.sections()); + if (Sections.empty()) { + OS << "\nThere are no sections in this file.\n"; + Expected SecStrTableOrErr = + this->Obj.getSectionStringTable(Sections, this->WarningHandler); + if (!SecStrTableOrErr) + this->reportUniqueWarning(SecStrTableOrErr.takeError()); + return; + } OS << "There are " << to_string(Sections.size()) << " section headers, starting at offset " << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n"; @@ -4245,13 +4261,24 @@ template void GNUELFDumper::printProgramHeaders( bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { - if (PrintProgramHeaders) - printProgramHeaders(); - - // Display the section mapping along with the program headers, unless - // -section-mapping is explicitly set to false. - if (PrintSectionMapping != cl::BOU_FALSE) - printSectionMapping(); + const bool IsPrintSectionMapping = (PrintSectionMapping != cl::BOU_FALSE); + // Exit early if no program header or section mapping details were requested. + if(!PrintProgramHeaders && !IsPrintSectionMapping) { + return; + } + // Print program header info. + if(PrintProgramHeaders) { + const Elf_Ehdr& Header = this->Obj.getHeader(); + if (Header.e_phnum == 0) { + OS << "\nThere are no program headers in this file.\n"; + } else { + printProgramHeaders(); + } + } + // Print section mapping. + if (IsPrintSectionMapping) { + printSectionMapping(); + } } template void GNUELFDumper::printProgramHeaders() {