forked from OSchip/llvm-project
Parse statically defined tracepoint markers from .note.stapsdt section
Summary: Parse statically defined tracepoints(SDT) markers from the ELF file, and store them. Add an option to print SDTs (-print-sdt). Add test case for parsing and printing SDTs. (cherry picked from FBD15366712)
This commit is contained in:
parent
f1fde44154
commit
4755825447
|
@ -395,6 +395,9 @@ public:
|
|||
/// List of functions that always trap.
|
||||
std::vector<const BinaryFunction *> TrappedFunctions;
|
||||
|
||||
/// List of the SDT markers in the elf file
|
||||
std::vector<SDTMarkerInfo> SDTMarkers;
|
||||
|
||||
BinaryContext(std::unique_ptr<MCContext> Ctx,
|
||||
std::unique_ptr<DWARFContext> DwCtx,
|
||||
std::unique_ptr<Triple> TheTriple,
|
||||
|
|
|
@ -441,4 +441,13 @@ inline raw_ostream &operator<<(raw_ostream &OS, const BinarySection &Section) {
|
|||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
||||
struct SDTMarkerInfo {
|
||||
uint64_t PC;
|
||||
uint64_t Base;
|
||||
uint64_t Semaphore;
|
||||
llvm::StringRef Provider;
|
||||
llvm::StringRef Name;
|
||||
llvm::StringRef Args;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -294,6 +294,13 @@ PrintLoopInfo("print-loops",
|
|||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintSDTMarkers("print-sdt",
|
||||
cl::desc("print all SDT markers"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<cl::boolOrDefault>
|
||||
RelocationMode("relocs",
|
||||
cl::desc("use relocations in the binary (default=autodetect)"),
|
||||
|
@ -874,6 +881,64 @@ void RewriteInstance::discoverStorage() {
|
|||
BC->LayoutStartAddress = NextAvailableAddress;
|
||||
}
|
||||
|
||||
void RewriteInstance::parseSDTNotes() {
|
||||
if (!SDTSection)
|
||||
return;
|
||||
|
||||
StringRef Buf = SDTSection->getContents();
|
||||
auto DE = DataExtractor(Buf, BC->AsmInfo->isLittleEndian(),
|
||||
BC->AsmInfo->getCodePointerSize());
|
||||
uint32_t Offset = 0;
|
||||
|
||||
while (DE.isValidOffset(Offset)) {
|
||||
auto NameSz = DE.getU32(&Offset);
|
||||
DE.getU32(&Offset); // skip over DescSz
|
||||
auto Type = DE.getU32(&Offset);
|
||||
Offset = alignTo(Offset, 4);
|
||||
|
||||
if (Type != 3)
|
||||
errs() << "BOLT-WARNING: SDT note type \"" << Type
|
||||
<< "\" is not expected\n";
|
||||
|
||||
if (NameSz == 0)
|
||||
errs() << "BOLT-WARNING: SDT note has empty name\n";
|
||||
|
||||
StringRef Name = DE.getCStr(&Offset);
|
||||
|
||||
if (!Name.equals("stapsdt"))
|
||||
errs() << "BOLT-WARNING: SDT note name \"" << Name
|
||||
<< "\" is not expected\n";
|
||||
|
||||
// Parse description
|
||||
SDTMarkerInfo Marker;
|
||||
Marker.PC = DE.getU64(&Offset);
|
||||
Marker.Base = DE.getU64(&Offset);
|
||||
Marker.Semaphore = DE.getU64(&Offset);
|
||||
Marker.Provider = DE.getCStr(&Offset);
|
||||
Marker.Name = DE.getCStr(&Offset);
|
||||
Marker.Args = DE.getCStr(&Offset);
|
||||
|
||||
Offset = alignTo(Offset, 4);
|
||||
|
||||
BC->SDTMarkers.push_back(Marker);
|
||||
}
|
||||
|
||||
if (opts::PrintSDTMarkers)
|
||||
printSDTMarkers();
|
||||
}
|
||||
|
||||
void RewriteInstance::printSDTMarkers() {
|
||||
outs() << "BOLT-INFO: Number of SDT markers is " << BC->SDTMarkers.size()
|
||||
<< "\n";
|
||||
for (auto &Marker : BC->SDTMarkers) {
|
||||
outs() << "BOLT-INFO: PC: " << utohexstr(Marker.PC)
|
||||
<< ", Base: " << utohexstr(Marker.Base)
|
||||
<< ", Semaphore: " << utohexstr(Marker.Semaphore)
|
||||
<< ", Provider: " << Marker.Provider << ", Name: " << Marker.Name
|
||||
<< ", Args: " << Marker.Args << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void RewriteInstance::parseBuildID() {
|
||||
if (!BuildIDSection)
|
||||
return;
|
||||
|
@ -1753,6 +1818,7 @@ void RewriteInstance::readSpecialSections() {
|
|||
PLTGOTSection = BC->getUniqueSectionByName(".plt.got");
|
||||
RelaPLTSection = BC->getUniqueSectionByName(".rela.plt");
|
||||
BuildIDSection = BC->getUniqueSectionByName(".note.gnu.build-id");
|
||||
SDTSection = BC->getUniqueSectionByName(".note.stapsdt");
|
||||
|
||||
if (opts::PrintSections) {
|
||||
outs() << "BOLT-INFO: Sections from original binary:\n";
|
||||
|
@ -1781,6 +1847,7 @@ void RewriteInstance::readSpecialSections() {
|
|||
|
||||
// Parse build-id
|
||||
parseBuildID();
|
||||
|
||||
if (DA.started()) {
|
||||
if (auto FileBuildID = getPrintableBuildID()) {
|
||||
outs() << "BOLT-INFO: binary build-id is: " << *FileBuildID << "\n";
|
||||
|
@ -1790,6 +1857,8 @@ void RewriteInstance::readSpecialSections() {
|
|||
"not read one from input binary\n";
|
||||
}
|
||||
}
|
||||
|
||||
parseSDTNotes();
|
||||
}
|
||||
|
||||
void RewriteInstance::adjustCommandLineOptions() {
|
||||
|
|
|
@ -258,6 +258,12 @@ private:
|
|||
/// Return true if the function \p BF should be disassembled.
|
||||
bool shouldDisassemble(BinaryFunction &BF) const;
|
||||
|
||||
/// Parse .note.stapsdt section
|
||||
void parseSDTNotes();
|
||||
|
||||
/// Print all SDT markers
|
||||
void printSDTMarkers();
|
||||
|
||||
public:
|
||||
/// Standard ELF sections we overwrite.
|
||||
static constexpr const char *SectionsToOverwrite[] = {
|
||||
|
@ -384,6 +390,10 @@ private:
|
|||
/// .note.gnu.build-id section.
|
||||
ErrorOr<BinarySection &> BuildIDSection{std::errc::bad_address};
|
||||
|
||||
/// .note.stapsdt section.
|
||||
/// Contains information about statically defined tracing points
|
||||
ErrorOr<BinarySection &> SDTSection{std::errc::bad_address};
|
||||
|
||||
/// A reference to the build-id bytes in the original binary
|
||||
StringRef BuildID;
|
||||
|
||||
|
|
Loading…
Reference in New Issue