[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