[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:
parent
7b9fae05b4
commit
43efb5e445
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user