mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 14:20:29 +00:00
[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
This commit is contained in:
parent
1119535dde
commit
c7b0c37c92
23
test/tools/llvm-readobj/COFF/call-graph-profile-err.s
Normal file
23
test/tools/llvm-readobj/COFF/call-graph-profile-err.s
Normal file
@ -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.
|
41
test/tools/llvm-readobj/COFF/call-graph-profile.s
Normal file
41
test/tools/llvm-readobj/COFF/call-graph-profile.s
Normal file
@ -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.
|
@ -104,8 +104,10 @@ public:
|
||||
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());
|
||||
|
||||
Expected<StringRef> SymName = Obj->getSymbolName(*Sym);
|
||||
if (!SymName)
|
||||
reportError(SymName.takeError(), Obj->getFileName());
|
||||
|
||||
W.printNumber("Sym", *SymName, SymIndex);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (CGProfileSection == SectionRef())
|
||||
return;
|
||||
|
||||
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) {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user