Skip to content

Conversation

Prabhuk
Copy link
Contributor

@Prabhuk Prabhuk commented Jul 28, 2025

Introduce --call-graph-info flag to read and print .callgraph section's contents to console in a human readable format

@Prabhuk Prabhuk changed the title Handle .callgraph section [llvm-objdump] Handle .callgraph section Jul 28, 2025
Copy link

github-actions bot commented Jul 28, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

uint64_t IgnoredICallIdCount = 0;
// Number of valid indirect calls with type ids.
uint64_t ICallWithTypeIdCount = 0;
if (CallGraphSection) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we handle direct callsites and print them out even if the CallgraphSection is empty?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's reasonable if they pass the flag and ask for the call graph. AIUI, that section will only ever contain info on indirect call targets, so it should be fine.

@Prabhuk Prabhuk requested a review from ilovepi July 28, 2025 19:07
if (CallGraphSection) {
StringRef CGSecContents = unwrapOrError(
CallGraphSection.value().getContents(), Obj->getFileName());
// TODO: some entries are written in pointer size. are they always 64-bit?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to change this to target specific pointer size so that we can support both 32 bit and 64 bit targets.

Comment on lines +3392 to +3401
outs() << "\n\nINDIRECT CALL SITES (CALLER_ADDR [CALL_SITE_ADDR,])";
for (const auto &El : FuncInfo) {
auto CallerPc = El.first;
auto FuncIndirCallSites = El.second.IndirectCallSites;
if (!FuncIndirCallSites.empty()) {
outs() << "\n" << format("%lx", CallerPc);
for (auto IndirCallSitePc : FuncIndirCallSites)
outs() << " " << format("%lx", IndirCallSitePc);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all these printing routines should be factored out, so you can change them more easily, or support additional formats.

if (CGSecContents.size() % sizeof(uint64_t))
reportError(Obj->getFileName(), "Malformed .callgraph section.");

size_t Size = CGSecContents.size() / sizeof(uint64_t);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
size_t Size = CGSecContents.size() / sizeof(uint64_t);
const size_t Size = CGSecContents.size() / sizeof(uint64_t);

Comment on lines +3239 to +3240
else
consumeError(NameOrErr.takeError());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return the error? or maybe at least continue to the next iteration?

reportWarning("there is no .callgraph section", Obj->getFileName());

// Map type id to indirect call sites.
MapVector<uint64_t, SmallVector<uint64_t>> TypeIdToIndirCallSites;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider a using statement to make this type easier to reason about.

using TypIdCallSiteMap = MapVector<uint64_t, SmallVector<uint64_t>>

@Prabhuk
Copy link
Contributor Author

Prabhuk commented Sep 9, 2025

Moving call-graph-info support from llvm-objdump to llvm-readelf.

Handle direct calls: #155706
llvm-readelf: #157499

Closing this PR.

@Prabhuk Prabhuk closed this Sep 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants