[llvm] 79d7e9c - [llvm-readobj][COFF] add .llvm.call-graph-profile section dump
Zequan Wu via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 09:52:56 PDT 2020
Author: Zequan Wu
Date: 2020-06-25T09:52:49-07:00
New Revision: 79d7e9c7d07a7ba4a65f4579bf3a8756c757e634
URL: https://github.com/llvm/llvm-project/commit/79d7e9c7d07a7ba4a65f4579bf3a8756c757e634
DIFF: https://github.com/llvm/llvm-project/commit/79d7e9c7d07a7ba4a65f4579bf3a8756c757e634.diff
LOG: [llvm-readobj][COFF] add .llvm.call-graph-profile section dump
Summary: Dumping contents of `.llvm.call-graph-profile` section of COFF in the same format as ELF.
Reviewers: jhenderson, MaskRay, hans
Reviewed By: jhenderson
Subscribers: grimar, rupprecht, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D81894
Added:
llvm/test/tools/llvm-readobj/COFF/call-graph-profile-err.s
llvm/test/tools/llvm-readobj/COFF/call-graph-profile.s
Modified:
llvm/tools/llvm-readobj/COFFDumper.cpp
llvm/tools/llvm-readobj/llvm-readobj.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-readobj/COFF/call-graph-profile-err.s b/llvm/test/tools/llvm-readobj/COFF/call-graph-profile-err.s
new file mode 100644
index 000000000000..6ba01f6c2fa1
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/call-graph-profile-err.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s -o %t
+# RUN: not llvm-readobj %t --cg-profile 2>&1 | FileCheck --check-prefix=ERR %s
+
+## In order to use --cg-profile option, the section ".llvm.call-graph-profile"
+## should have two 4-byte fields representing the indexes of two symbols and
+## one 8-byte fields representing the weight from first symbol to second
+## symbol.
+## The section in this test case has 9 bytes of data, so it's malformed.
+
+# ERR: error: '{{.*}}': Stream Error: The stream is too short to perform the requested operation.
+
+.section .test
+a:
+b:
+c:
+d:
+e:
+
+.section ".llvm.call-graph-profile"
+ .long 10 ## Symbol index of a.
+ .long 11 ## Symbol index of b.
+ .byte 32 ## Weight from a to b. It is an error, since it should have a length of 8 bytes.
diff --git a/llvm/test/tools/llvm-readobj/COFF/call-graph-profile.s b/llvm/test/tools/llvm-readobj/COFF/call-graph-profile.s
new file mode 100644
index 000000000000..1a4294255bf6
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/call-graph-profile.s
@@ -0,0 +1,41 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s -o %t
+# RUN: llvm-readobj %t --cg-profile | FileCheck %s
+
+# CHECK: CGProfile [
+# CHECK-NEXT: CGProfileEntry {
+# CHECK-NEXT: From: a (10)
+# CHECK-NEXT: To: b (11)
+# CHECK-NEXT: Weight: 32
+# CHECK-NEXT: }
+# CHECK-NEXT: CGProfileEntry {
+# CHECK-NEXT: From: c (12)
+# CHECK-NEXT: To: a (10)
+# CHECK-NEXT: Weight: 11
+# CHECK-NEXT: }
+# CHECK-NEXT: CGProfileEntry {
+# CHECK-NEXT: From: d (13)
+# CHECK-NEXT: To: e (14)
+# CHECK-NEXT: Weight: 20
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.section .test
+a:
+b:
+c:
+d:
+e:
+
+.section ".llvm.call-graph-profile"
+ .long 10 ## Symbol index of a.
+ .long 11 ## Symbol index of b.
+ .quad 32 ## Weight from a to b.
+
+ .long 12 ## Symbol index of c.
+ .long 10 ## Symbol index of a.
+ .quad 11 ## Weight from c to a.
+
+ .long 13 ## Symbol index of d.
+ .long 14 ## Symbol index of e.
+ .quad 20 ## Weight from d to e.
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index fa1442639594..89a904f53ae7 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -104,8 +104,10 @@ class COFFDumper : public ObjDumper {
bool GHash) override;
void printStackMap() const override;
void printAddrsig() override;
+ void printCGProfile() override;
private:
+ StringRef getSymbolName(uint32_t Index);
void printSymbols() override;
void printDynamicSymbols() override;
void printSymbol(const SymbolRef &Sym);
@@ -1516,16 +1518,8 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, Aux))
reportError(errorCodeToError(EC), Obj->getFileName());
- Expected<COFFSymbolRef> Linked = Obj->getSymbol(Aux->TagIndex);
- if (!Linked)
- reportError(Linked.takeError(), Obj->getFileName());
-
- Expected<StringRef> LinkedName = Obj->getSymbolName(*Linked);
- if (!LinkedName)
- reportError(LinkedName.takeError(), Obj->getFileName());
-
DictScope AS(W, "AuxWeakExternal");
- W.printNumber("Linked", *LinkedName, Aux->TagIndex);
+ W.printNumber("Linked", getSymbolName(Aux->TagIndex), Aux->TagIndex);
W.printEnum ("Search", Aux->Characteristics,
makeArrayRef(WeakExternalCharacteristics));
@@ -1570,19 +1564,11 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
if (std::error_code EC = getSymbolAuxData(Obj, Symbol, I, Aux))
reportError(errorCodeToError(EC), Obj->getFileName());
- Expected<COFFSymbolRef> ReferredSym =
- Obj->getSymbol(Aux->SymbolTableIndex);
- if (!ReferredSym)
- reportError(ReferredSym.takeError(), Obj->getFileName());
-
- Expected<StringRef> ReferredName = Obj->getSymbolName(*ReferredSym);
- if (!ReferredName)
- reportError(ReferredName.takeError(), Obj->getFileName());
-
DictScope AS(W, "AuxCLRToken");
W.printNumber("AuxType", Aux->AuxType);
W.printNumber("Reserved", Aux->Reserved);
- W.printNumber("SymbolTableIndex", *ReferredName, Aux->SymbolTableIndex);
+ W.printNumber("SymbolTableIndex", getSymbolName(Aux->SymbolTableIndex),
+ Aux->SymbolTableIndex);
} else {
W.startLine() << "<unhandled auxiliary record>\n";
@@ -1904,7 +1890,7 @@ void COFFDumper::printResourceDirectoryTable(
}
void COFFDumper::printStackMap() const {
- object::SectionRef StackMapSection;
+ SectionRef StackMapSection;
for (auto Sec : Obj->sections()) {
StringRef Name;
if (Expected<StringRef> NameOrErr = Sec.getName())
@@ -1918,7 +1904,7 @@ void COFFDumper::printStackMap() const {
}
}
- if (StackMapSection == object::SectionRef())
+ if (StackMapSection == SectionRef())
return;
StringRef StackMapContents =
@@ -1935,7 +1921,7 @@ void COFFDumper::printStackMap() const {
}
void COFFDumper::printAddrsig() {
- object::SectionRef AddrsigSection;
+ SectionRef AddrsigSection;
for (auto Sec : Obj->sections()) {
StringRef Name;
if (Expected<StringRef> NameOrErr = Sec.getName())
@@ -1949,7 +1935,7 @@ void COFFDumper::printAddrsig() {
}
}
- if (AddrsigSection == object::SectionRef())
+ if (AddrsigSection == SectionRef())
return;
StringRef AddrsigContents =
@@ -1967,19 +1953,58 @@ void COFFDumper::printAddrsig() {
if (Err)
reportError(createError(Err), Obj->getFileName());
- Expected<COFFSymbolRef> Sym = Obj->getSymbol(SymIndex);
- if (!Sym)
- reportError(Sym.takeError(), Obj->getFileName());
+ W.printNumber("Sym", getSymbolName(SymIndex), SymIndex);
+ Cur += Size;
+ }
+}
+
+void COFFDumper::printCGProfile() {
+ SectionRef CGProfileSection;
+ for (SectionRef Sec : Obj->sections()) {
+ StringRef Name = unwrapOrError(Obj->getFileName(), Sec.getName());
+ if (Name == ".llvm.call-graph-profile") {
+ CGProfileSection = Sec;
+ break;
+ }
+ }
- Expected<StringRef> SymName = Obj->getSymbolName(*Sym);
- if (!SymName)
- reportError(SymName.takeError(), Obj->getFileName());
+ if (CGProfileSection == SectionRef())
+ return;
- W.printNumber("Sym", *SymName, SymIndex);
- Cur += Size;
+ StringRef CGProfileContents =
+ unwrapOrError(Obj->getFileName(), CGProfileSection.getContents());
+ BinaryStreamReader Reader(CGProfileContents, llvm::support::little);
+
+ ListScope L(W, "CGProfile");
+ while (!Reader.empty()) {
+ uint32_t FromIndex, ToIndex;
+ uint64_t Count;
+ if (Error Err = Reader.readInteger(FromIndex))
+ reportError(std::move(Err), Obj->getFileName());
+ if (Error Err = Reader.readInteger(ToIndex))
+ reportError(std::move(Err), Obj->getFileName());
+ if (Error Err = Reader.readInteger(Count))
+ reportError(std::move(Err), Obj->getFileName());
+
+ DictScope D(W, "CGProfileEntry");
+ W.printNumber("From", getSymbolName(FromIndex), FromIndex);
+ W.printNumber("To", getSymbolName(ToIndex), ToIndex);
+ W.printNumber("Weight", Count);
}
}
+StringRef COFFDumper::getSymbolName(uint32_t Index) {
+ Expected<COFFSymbolRef> Sym = Obj->getSymbol(Index);
+ if (!Sym)
+ reportError(Sym.takeError(), Obj->getFileName());
+
+ Expected<StringRef> SymName = Obj->getSymbolName(*Sym);
+ if (!SymName)
+ reportError(SymName.takeError(), Obj->getFileName());
+
+ return *SymName;
+}
+
void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer,
ArrayRef<ArrayRef<uint8_t>> IpiRecords,
ArrayRef<ArrayRef<uint8_t>> TpiRecords) {
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 4c00b740de75..b9c6ad2256ae 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -528,6 +528,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer,
Dumper->printCOFFResources();
if (opts::COFFLoadConfig)
Dumper->printCOFFLoadConfig();
+ if (opts::CGProfile)
+ Dumper->printCGProfile();
if (opts::Addrsig)
Dumper->printAddrsig();
if (opts::CodeView)
More information about the llvm-commits
mailing list