-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[llvm-readobj] Dump callgraph section info for ELF #157499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
Introduce a new flag `--call-graph-info` which outputs callgraph ELF section information to the console as a text output or as JSON output.
…toms out to llvm_unreachable.
3499c2d
to
0b9c46d
Compare
Tests failing seems unrelated. Probably rebase. |
# CHECK: {{.*}}llvm-readelf{{.*}}: warning: '[[FILE]]': .callgraph section has unknown type id for 1 indirect targets. | ||
# CHECK-NEXT: Per-function call graph information:: | ||
# CHECK-EMPTY: | ||
# CHECK-NEXT: Function:: foo | ||
# CHECK-NEXT: Function PC:: 0x0 | ||
# CHECK-NEXT: FormatVersionNumber:: 0 | ||
# CHECK-NEXT: Function Kind:: NOT_INDIRECT | ||
# CHECK-NEXT: Indirect callee count:: 0 | ||
# CHECK-NEXT: Direct callee count:: 1 | ||
# CHECK-NEXT: { | ||
# CHECK-NEXT: CalleePC:: 0x5 | ||
# CHECK-NEXT: } | ||
# CHECK-EMPTY: | ||
# CHECK-NEXT: Function:: bar | ||
# CHECK-NEXT: Function PC:: 0x6 | ||
# CHECK-NEXT: FormatVersionNumber:: 0 | ||
# CHECK-NEXT: Function Kind:: UNKNOWN_TID | ||
# CHECK-NEXT: Indirect callee count:: 1 | ||
# CHECK-NEXT: { | ||
# CHECK-NEXT: callsite: 0x9 | ||
# CHECK-NEXT: calleeTypeId: 0x10 | ||
# CHECK-NEXT: } | ||
# CHECK-NEXT: Direct callee count:: 0 | ||
# CHECK-EMPTY: | ||
# CHECK-NEXT: Function:: baz | ||
# CHECK-NEXT: Function PC:: 0xa | ||
# CHECK-NEXT: FormatVersionNumber:: 0 | ||
# CHECK-NEXT: Function Kind:: KNOWN_TID | ||
# CHECK-NEXT: Function Type ID:: 0x20 | ||
# CHECK-NEXT: Indirect callee count:: 0 | ||
# CHECK-NEXT: Direct callee count:: 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this section fail when you do json(and I guess llvm too) output? CHECK lines are always checked no matter the prefix.
|
||
# CHECK: {{.*}}llvm-readelf{{.*}}: warning: '[[FILE]]': .callgraph section has unknown type id for 1 indirect targets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# CHECK: {{.*}}llvm-readelf{{.*}}: warning: '[[FILE]]': .callgraph section has unknown type id for 1 indirect targets. | |
# CHECK: warning: '[[FILE]]': .callgraph section has unknown type id for 1 indirect targets. |
I don't think you need to check the tool's name do you? What's the convention in other tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to use --match-full-lines
in my test. Let me try if the test passes if the toolname prefix is not part of the CHECK lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason you want to match full lines? convention? specific criteria?
# JSON-NEXT: "Function": { | ||
# JSON-NEXT: "Name": "foo", | ||
# JSON-NEXT: "Address": 6032, | ||
# JSON-NEXT: "Version": 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the version number?
# JSON-NEXT: "NumIndirectCallSites": 0, | ||
# JSON-NEXT: "NumDirectCallSites": 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The arrays of the callsites should always be in the output. the schema needs to be fixed to be easily processable.
# CHECK-NEXT: Callee:: foo | ||
# CHECK-NEXT: CalleePC:: 0x1790 | ||
# CHECK-NEXT: Callee:: bar | ||
# CHECK-NEXT: CalleePC:: 0x17a0 | ||
# CHECK-NEXT: Callee:: baz | ||
# CHECK-NEXT: CalleePC:: 0x17b0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the ::
is odd.
Maybe this gets printed as Callee: 0x1790 foo
or something like that, since the symbol, pc pair IMO make sense to be on the same line? I don't recall the gnu output conventions, but for LLVM, its kind of haphazard, and some things are very json like, and others are just whatever people felt like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack. One of the offline feedback I received is to turn GNU output into a tabular format to match existing readelf output style. I will work on that and update the patch.
(StringRef("While reading call graph info's [") + Component + | ||
StringRef("] for function at [0x") + StringRef(FuncPC.str()) + "]") | ||
.str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(StringRef("While reading call graph info's [") + Component + | |
StringRef("] for function at [0x") + StringRef(FuncPC.str()) + "]") | |
.str(); | |
(Twine("While reading call graph info's [") + Component + | |
"] for function at [0x" + FuncPC + "]").str(); |
But I'd think you'd typically just construct this below in the call to reportError()
Error FormatErr = createError("Unknown format version value [" + | ||
std::to_string(FormatVersionNumber) + | ||
"] in .callgraph section."); | ||
reportError(std::move(FormatErr), "Unknown value"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error FormatErr = createError("Unknown format version value [" + | |
std::to_string(FormatVersionNumber) + | |
"] in .callgraph section."); | |
reportError(std::move(FormatErr), "Unknown value"); | |
reportError(createError("Unknown format version value [" + | |
std::to_string(FormatVersionNumber) + | |
"] in .callgraph section."), "Unknown value"); |
What you have is fine. I just think this is a bit more typical of what I see in the codebase. either way is OK, so I'd just follow whatever convention this file/library uses.
return CallGraphSection; | ||
} | ||
|
||
template <class ELFT> bool ELFDumper<ELFT>::processCallGraphSection() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I missing the JSON impl? I know some of that is automagically derived, but usually there's somehting we want expressed differently in the JSON than in the LLVM output.
} | ||
} | ||
W.printNumber("NumDirectCallSites", CGInfo.DirectCallees.size()); | ||
if (CGInfo.DirectCallees.size() > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should always be printed, so a parser can always expect them to be there.
OS << "\nFunction:: " << FuncSymNames; | ||
OS << "\nFunction PC:: " << format("0x%lx", FuncEntryPc); | ||
OS << "\nFormatVersionNumber:: " << CGInfo.FormatVersionNumber; | ||
OS << "\nFunction Kind:: " << GetFuntionKindString(CGInfo.Kind); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use something like a list scope and the print() APIs, like the later changes?
Introduce a new flag
--call-graph-info
which outputs callgraph ELFsection information to the console as a text output or as JSON output.