[llvm-objdump] Create name for fake sections

It doesn't have a section header string table so add a vector to have
the strings and create name based on the program header type and the
index.

Differential Revision: https://reviews.llvm.org/D131290
This commit is contained in:
Namhyung Kim 2022-09-09 09:36:41 +01:00 committed by James Henderson
parent 7b9fae05b4
commit 43efb5e445
4 changed files with 79 additions and 18 deletions

View File

@ -14,6 +14,7 @@
#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"
@ -182,6 +183,7 @@ public:
private:
StringRef Buf;
std::vector<Elf_Shdr> FakeSections;
SmallString<0> FakeSectionStrings;
ELFFile(StringRef Object);
@ -648,8 +650,11 @@ ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
Index = Sections[0].sh_link;
}
if (!Index) // no section string table.
return "";
// There is no section name string table. Return FakeSectionStrings which
// is non-empty if we have created fake sections.
if (!Index)
return FakeSectionStrings;
if (Index >= Sections.size())
return createError("section header string table index " + Twine(Index) +
" does not exist");
@ -770,8 +775,9 @@ template <class ELFT> void ELFFile<ELFT>::createFakeSections() {
if (!PhdrsOrErr)
return;
for (auto Phdr : *PhdrsOrErr) {
if (!(Phdr.p_type & ELF::PT_LOAD) || !(Phdr.p_flags & ELF::PF_X))
FakeSectionStrings += '\0';
for (auto [Idx, Phdr] : llvm::enumerate(*PhdrsOrErr)) {
if (Phdr.p_type != ELF::PT_LOAD || !(Phdr.p_flags & ELF::PF_X))
continue;
Elf_Shdr FakeShdr = {};
FakeShdr.sh_type = ELF::SHT_PROGBITS;
@ -779,6 +785,10 @@ template <class ELFT> void ELFFile<ELFT>::createFakeSections() {
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 = FakeSectionStrings.size();
FakeSectionStrings += ("PT_LOAD#" + Twine(Idx)).str();
FakeSectionStrings += '\0';
FakeSections.push_back(FakeShdr);
}
}

View File

@ -1,8 +1,59 @@
; RUN: llvm-objdump -h %p/Inputs/no-sections.elf-x86-64 \
; RUN: | FileCheck %s
## Check llvm-objdump -h can handle ELF files without section info.
## Only PT_LOAD segments with the PF_X flag will be displayed as fake sections.
; CHECK: Sections:
; CHECK-NEXT: Idx Name Size VMA Type
; CHECK-NEXT: 0 000006ec 0000000000400000 TEXT
; CHECK-NEXT: 1 00000000 0000000000000000 TEXT
; CHECK-NOT: {{.}}
# RUN: yaml2obj %s -o %t
# RUN: llvm-objdump -h %t | FileCheck %s
# CHECK: Sections:
# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 PT_LOAD#1 00000100 0000000000400000 TEXT
# CHECK-NEXT: 1 PT_LOAD#3 00000200 0000000000600400 TEXT
# CHECK-NOT: {{.}}
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_CORE
Machine: EM_X86_64
Sections:
- Type: SectionHeaderTable
NoHeaders: true
- Type: Fill
Name: code1
Pattern: "cc"
Size: 0x100
Offset: 0x200
- Type: Fill
Name: data1
Pattern: "aa55"
Size: 0x100
Offset: 0x300
- Type: Fill
Name: code2
Pattern: "ff"
Size: 0x200
Offset: 0x400
ProgramHeaders:
- Type: PT_PHDR
Flags: [ PF_X ]
VAddr: 0x400000
MemSize: 0x100
- Type: PT_LOAD
Flags: [ PF_X ]
VAddr: 0x400000
MemSize: 0x100
FirstSec: code1
LastSec: code1
- Type: PT_LOAD
Flags: [ PF_R ]
VAddr: 0x500300
MemSize: 0x100
FirstSec: data1
LastSec: data1
- Type: PT_LOAD
Flags: [ PF_R, PF_X ]
VAddr: 0x600400
MemSize: 0x200
FirstSec: code2
LastSec: code2

View File

@ -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: <PT_LOAD#0>:
# 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: <PT_LOAD#0>:
# RANGE-NEXT: 55 pushq %rbp
# RANGE-NEXT: 48 89 e5 movq %rsp, %rbp
# RANGE-EMPTY:

View File

@ -2166,6 +2166,9 @@ static size_t getMaxSectionNameWidth(const ObjectFile &Obj) {
}
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);
@ -2178,9 +2181,6 @@ void objdump::printSectionHeaders(ObjectFile &Obj) {
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());