diff options
author | Georgii Rymar <grimar@accesssoftek.com> | 2020-07-03 16:23:46 +0300 |
---|---|---|
committer | Georgii Rymar <grimar@accesssoftek.com> | 2020-07-07 13:30:12 +0300 |
commit | 2d9bd448c9f051de088b53592f89871e9b390fba (patch) | |
tree | 108967bfa09b740ca51df535f923fb23756fcf2d /llvm | |
parent | 5e8084beba20f27ce14536168087e5c6971e292d (diff) | |
download | llvm-2d9bd448c9f051de088b53592f89871e9b390fba.zip llvm-2d9bd448c9f051de088b53592f89871e9b390fba.tar.gz llvm-2d9bd448c9f051de088b53592f89871e9b390fba.tar.bz2 |
[llvm-readobj] - Allow dumping partially corrupted SHT_LLVM_CALL_GRAPH_PROFILE sections.
The code we have currently reports an error if something is not right with the
profile section. Instead we can report a warning and continue dumping when it is possible.
This patch does it.
Differential revision: https://reviews.llvm.org/D83129
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test | 63 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 39 |
2 files changed, 88 insertions, 14 deletions
diff --git a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test index dfd95ea..8ccc93c 100644 --- a/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test +++ b/llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test @@ -37,6 +37,69 @@ Sections: - From: bar To: foo Weight: 98 +## 0x10 is the normal entry size for the SHT_LLVM_CALL_GRAPH_PROFILE section. + EntSize: [[ENTSIZE=0x10]] Symbols: - Name: foo - Name: bar + +## Check we report a warning when unable to get the content of the SHT_LLVM_CALL_GRAPH_PROFILE section. +# RUN: yaml2obj %s -DENTSIZE=0xF -o %t2.o +# RUN: llvm-readobj %t2.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=LLVM-ERR +# RUN: llvm-readelf %t2.o --cg-profile | FileCheck %s --check-prefix=GNU + +# LLVM-ERR: CGProfile [ +# LLVM-ERR-NEXT: warning: '[[FILE]]': unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has an invalid sh_entsize: 15 +# LLVM-ERR-NEXT: ] + +## Check we report a warning when unable to dump a name of a symbol. +# RUN: yaml2obj %s --docnum=2 -o %t3.o +# RUN: llvm-readobj %t3.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=LLVM-BROKEN-SYM +# RUN: llvm-readelf %t3.o --cg-profile | FileCheck %s --check-prefix=GNU + +# LLVM-BROKEN-SYM: CGProfile [ +# LLVM-BROKEN-SYM-NEXT: CGProfileEntry { +# LLVM-BROKEN-SYM-NEXT: From: A (1) +# LLVM-BROKEN-SYM-NEXT: warning: '[[FILE]]': unable to read the name of symbol with index 2: st_name (0xff) is past the end of the string table of size 0x5 +# LLVM-BROKEN-SYM-NEXT: To: <?> (2) +# LLVM-BROKEN-SYM-NEXT: Weight: 10 +# LLVM-BROKEN-SYM-NEXT: } +# LLVM-BROKEN-SYM-NEXT: CGProfileEntry { +# LLVM-BROKEN-SYM-NEXT: From: <?> (2) +# LLVM-BROKEN-SYM-NEXT: To: B (3) +# LLVM-BROKEN-SYM-NEXT: Weight: 20 +# LLVM-BROKEN-SYM-NEXT: } +# LLVM-BROKEN-SYM-NEXT: CGProfileEntry { +# LLVM-BROKEN-SYM-NEXT: From: (0) +# LLVM-BROKEN-SYM-NEXT: warning: '[[FILE]]': unable to read the name of symbol with index 4: unable to get symbol from section [index 3]: invalid symbol index (4) +# LLVM-BROKEN-SYM-NEXT: To: <?> (4) +# LLVM-BROKEN-SYM-NEXT: Weight: 20 +# LLVM-BROKEN-SYM-NEXT: } +# LLVM-BROKEN-SYM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .llvm.call-graph-profile + Type: SHT_LLVM_CALL_GRAPH_PROFILE + Entries: + - From: 1 + To: 2 + Weight: 10 + - From: 2 + To: 3 + Weight: 20 + - From: 0x0 ## Null symbol. + To: 0x4 ## This index goes past the end of the symbol table. + Weight: 20 + - Name: .strtab + Type: SHT_STRTAB + Content: "0041004200" ## '\0', 'A', '\0', 'B', '\0' +Symbols: + - StName: 1 ## 'A' + - StName: 0xFF ## An arbitrary currupted index in the string table. + - StName: 3 ## 'B' diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 7a29606..3d51515 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -6564,21 +6564,32 @@ void LLVMStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) { ListScope L(W, "CGProfile"); if (!this->dumper()->getDotCGProfileSec()) return; - auto CGProfile = unwrapOrError( - this->FileName, Obj->template getSectionContentsAsArray<Elf_CGProfile>( - this->dumper()->getDotCGProfileSec())); - for (const Elf_CGProfile &CGPE : CGProfile) { + + Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr = + Obj->template getSectionContentsAsArray<Elf_CGProfile>( + this->dumper()->getDotCGProfileSec()); + if (!CGProfileOrErr) { + this->reportUniqueWarning( + createError("unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: " + + toString(CGProfileOrErr.takeError()))); + return; + } + + auto GetSymName = [&](uint32_t Index) -> std::string { + if (Expected<std::string> NameOrErr = + this->dumper()->getStaticSymbolName(Index)) + return *NameOrErr; + else + this->reportUniqueWarning( + createError("unable to read the name of symbol with index " + + Twine(Index) + ": " + toString(NameOrErr.takeError()))); + return "<?>"; + }; + + for (const Elf_CGProfile &CGPE : *CGProfileOrErr) { DictScope D(W, "CGProfileEntry"); - W.printNumber( - "From", - unwrapOrError(this->FileName, - this->dumper()->getStaticSymbolName(CGPE.cgp_from)), - CGPE.cgp_from); - W.printNumber( - "To", - unwrapOrError(this->FileName, - this->dumper()->getStaticSymbolName(CGPE.cgp_to)), - CGPE.cgp_to); + W.printNumber("From", GetSymName(CGPE.cgp_from), CGPE.cgp_from); + W.printNumber("To", GetSymName(CGPE.cgp_to), CGPE.cgp_to); W.printNumber("Weight", CGPE.cgp_weight); } } |