aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorGeorgii Rymar <grimar@accesssoftek.com>2020-07-03 16:23:46 +0300
committerGeorgii Rymar <grimar@accesssoftek.com>2020-07-07 13:30:12 +0300
commit2d9bd448c9f051de088b53592f89871e9b390fba (patch)
tree108967bfa09b740ca51df535f923fb23756fcf2d /llvm
parent5e8084beba20f27ce14536168087e5c6971e292d (diff)
downloadllvm-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.test63
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp39
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);
}
}