1 //===- lib/MC/MCPseudoProbe.cpp - Pseudo probe encoding support ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/MC/MCPseudoProbe.h"
10 #include "llvm/MC/MCAsmInfo.h"
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCObjectFileInfo.h"
13 #include "llvm/MC/MCObjectStreamer.h"
14 #include "llvm/MC/MCStreamer.h"
15 #include "llvm/Support/Endian.h"
16 #include "llvm/Support/LEB128.h"
17 #include "llvm/Support/raw_ostream.h"
18 #include <limits>
19 #include <memory>
20 
21 #define DEBUG_TYPE "mcpseudoprobe"
22 
23 using namespace llvm;
24 using namespace support;
25 
26 #ifndef NDEBUG
27 int MCPseudoProbeTable::DdgPrintIndent = 0;
28 #endif
29 
30 static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
31                                      const MCSymbol *B) {
32   MCContext &Context = MCOS->getContext();
33   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
34   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
35   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
36   const MCExpr *AddrDelta =
37       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
38   return AddrDelta;
39 }
40 
41 void MCPseudoProbe::emit(MCObjectStreamer *MCOS,
42                          const MCPseudoProbe *LastProbe) const {
43   // Emit Index
44   MCOS->emitULEB128IntValue(Index);
45   // Emit Type and the flag:
46   // Type (bit 0 to 3), with bit 4 to 6 for attributes.
47   // Flag (bit 7, 0 - code address, 1 - address delta). This indicates whether
48   // the following field is a symbolic code address or an address delta.
49   assert(Type <= 0xF && "Probe type too big to encode, exceeding 15");
50   assert(Attributes <= 0x7 &&
51          "Probe attributes too big to encode, exceeding 7");
52   uint8_t PackedType = Type | (Attributes << 4);
53   uint8_t Flag = LastProbe ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0;
54   MCOS->emitInt8(Flag | PackedType);
55 
56   if (LastProbe) {
57     // Emit the delta between the address label and LastProbe.
58     const MCExpr *AddrDelta =
59         buildSymbolDiff(MCOS, Label, LastProbe->getLabel());
60     int64_t Delta;
61     if (AddrDelta->evaluateAsAbsolute(Delta, MCOS->getAssemblerPtr())) {
62       MCOS->emitSLEB128IntValue(Delta);
63     } else {
64       MCOS->insert(new MCPseudoProbeAddrFragment(AddrDelta));
65     }
66   } else {
67     // Emit label as a symbolic code address.
68     MCOS->emitSymbolValue(
69         Label, MCOS->getContext().getAsmInfo()->getCodePointerSize());
70   }
71 
72   LLVM_DEBUG({
73     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
74     dbgs() << "Probe: " << Index << "\n";
75   });
76 }
77 
78 void MCPseudoProbeInlineTree::addPseudoProbe(
79     const MCPseudoProbe &Probe, const MCPseudoProbeInlineStack &InlineStack) {
80   // The function should not be called on the root.
81   assert(isRoot() && "Should not be called on root");
82 
83   // When it comes here, the input look like:
84   //    Probe: GUID of C, ...
85   //    InlineStack: [88, A], [66, B]
86   // which means, Function A inlines function B at call site with a probe id of
87   // 88, and B inlines C at probe 66. The tri-tree expects a tree path like {[0,
88   // A], [88, B], [66, C]} to locate the tree node where the probe should be
89   // added. Note that the edge [0, A] means A is the top-level function we are
90   // emitting probes for.
91 
92   // Make a [0, A] edge.
93   // An empty inline stack means the function that the probe originates from
94   // is a top-level function.
95   InlineSite Top;
96   if (InlineStack.empty()) {
97     Top = InlineSite(Probe.getGuid(), 0);
98   } else {
99     Top = InlineSite(std::get<0>(InlineStack.front()), 0);
100   }
101 
102   auto *Cur = getOrAddNode(Top);
103 
104   // Make interior edges by walking the inline stack. Once it's done, Cur should
105   // point to the node that the probe originates from.
106   if (!InlineStack.empty()) {
107     auto Iter = InlineStack.begin();
108     auto Index = std::get<1>(*Iter);
109     Iter++;
110     for (; Iter != InlineStack.end(); Iter++) {
111       // Make an edge by using the previous probe id and current GUID.
112       Cur = Cur->getOrAddNode(InlineSite(std::get<0>(*Iter), Index));
113       Index = std::get<1>(*Iter);
114     }
115     Cur = Cur->getOrAddNode(InlineSite(Probe.getGuid(), Index));
116   }
117 
118   Cur->Probes.push_back(Probe);
119 }
120 
121 void MCPseudoProbeInlineTree::emit(MCObjectStreamer *MCOS,
122                                    const MCPseudoProbe *&LastProbe) {
123   LLVM_DEBUG({
124     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
125     dbgs() << "Group [\n";
126     MCPseudoProbeTable::DdgPrintIndent += 2;
127   });
128   // Emit probes grouped by GUID.
129   if (Guid != 0) {
130     LLVM_DEBUG({
131       dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
132       dbgs() << "GUID: " << Guid << "\n";
133     });
134     // Emit Guid
135     MCOS->emitInt64(Guid);
136     // Emit number of probes in this node
137     MCOS->emitULEB128IntValue(Probes.size());
138     // Emit number of direct inlinees
139     MCOS->emitULEB128IntValue(Children.size());
140     // Emit probes in this group
141     for (const auto &Probe : Probes) {
142       Probe.emit(MCOS, LastProbe);
143       LastProbe = &Probe;
144     }
145   } else {
146     assert(Probes.empty() && "Root should not have probes");
147   }
148 
149   // Emit sorted descendant
150   // InlineSite is unique for each pair,
151   // so there will be no ordering of Inlinee based on MCPseudoProbeInlineTree*
152   std::map<InlineSite, MCPseudoProbeInlineTree *> Inlinees;
153   for (auto Child = Children.begin(); Child != Children.end(); ++Child)
154     Inlinees[Child->first] = Child->second.get();
155 
156   for (const auto &Inlinee : Inlinees) {
157     if (Guid) {
158       // Emit probe index
159       MCOS->emitULEB128IntValue(std::get<1>(Inlinee.first));
160       LLVM_DEBUG({
161         dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
162         dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n";
163       });
164     }
165     // Emit the group
166     Inlinee.second->emit(MCOS, LastProbe);
167   }
168 
169   LLVM_DEBUG({
170     MCPseudoProbeTable::DdgPrintIndent -= 2;
171     dbgs().indent(MCPseudoProbeTable::DdgPrintIndent);
172     dbgs() << "]\n";
173   });
174 }
175 
176 void MCPseudoProbeSection::emit(MCObjectStreamer *MCOS) {
177   MCContext &Ctx = MCOS->getContext();
178 
179   for (auto &ProbeSec : MCProbeDivisions) {
180     const MCPseudoProbe *LastProbe = nullptr;
181     if (auto *S =
182             Ctx.getObjectFileInfo()->getPseudoProbeSection(ProbeSec.first)) {
183       // Switch to the .pseudoprobe section or a comdat group.
184       MCOS->SwitchSection(S);
185       // Emit probes grouped by GUID.
186       ProbeSec.second.emit(MCOS, LastProbe);
187     }
188   }
189 }
190 
191 //
192 // This emits the pseudo probe tables.
193 //
194 void MCPseudoProbeTable::emit(MCObjectStreamer *MCOS) {
195   MCContext &Ctx = MCOS->getContext();
196   auto &ProbeTable = Ctx.getMCPseudoProbeTable();
197 
198   // Bail out early so we don't switch to the pseudo_probe section needlessly
199   // and in doing so create an unnecessary (if empty) section.
200   auto &ProbeSections = ProbeTable.getProbeSections();
201   if (ProbeSections.empty())
202     return;
203 
204   LLVM_DEBUG(MCPseudoProbeTable::DdgPrintIndent = 0);
205 
206   // Put out the probe.
207   ProbeSections.emit(MCOS);
208 }
209 
210 static StringRef getProbeFNameForGUID(const GUIDProbeFunctionMap &GUID2FuncMAP,
211                                       uint64_t GUID) {
212   auto It = GUID2FuncMAP.find(GUID);
213   assert(It != GUID2FuncMAP.end() &&
214          "Probe function must exist for a valid GUID");
215   return It->second.FuncName;
216 }
217 
218 void MCPseudoProbeFuncDesc::print(raw_ostream &OS) {
219   OS << "GUID: " << FuncGUID << " Name: " << FuncName << "\n";
220   OS << "Hash: " << FuncHash << "\n";
221 }
222 
223 void MCDecodedPseudoProbe::getInlineContext(
224     SmallVectorImpl<std::string> &ContextStack,
225     const GUIDProbeFunctionMap &GUID2FuncMAP, bool ShowName) const {
226   uint32_t Begin = ContextStack.size();
227   MCDecodedPseudoProbeInlineTree *Cur = InlineTree;
228   // It will add the string of each node's inline site during iteration.
229   // Note that it won't include the probe's belonging function(leaf location)
230   while (Cur->hasInlineSite()) {
231     std::string ContextStr;
232     if (ShowName) {
233       StringRef FuncName =
234           getProbeFNameForGUID(GUID2FuncMAP, std::get<0>(Cur->ISite));
235       ContextStr += FuncName.str();
236     } else {
237       ContextStr += Twine(std::get<0>(Cur->ISite)).str();
238     }
239     ContextStr += ":";
240     ContextStr += Twine(std::get<1>(Cur->ISite)).str();
241     ContextStack.emplace_back(ContextStr);
242     Cur = static_cast<MCDecodedPseudoProbeInlineTree *>(Cur->Parent);
243   }
244   // Make the ContextStack in caller-callee order
245   std::reverse(ContextStack.begin() + Begin, ContextStack.end());
246 }
247 
248 std::string MCDecodedPseudoProbe::getInlineContextStr(
249     const GUIDProbeFunctionMap &GUID2FuncMAP, bool ShowName) const {
250   std::ostringstream OContextStr;
251   SmallVector<std::string, 16> ContextStack;
252   getInlineContext(ContextStack, GUID2FuncMAP, ShowName);
253   for (auto &CxtStr : ContextStack) {
254     if (OContextStr.str().size())
255       OContextStr << " @ ";
256     OContextStr << CxtStr;
257   }
258   return OContextStr.str();
259 }
260 
261 static const char *PseudoProbeTypeStr[3] = {"Block", "IndirectCall",
262                                             "DirectCall"};
263 
264 void MCDecodedPseudoProbe::print(raw_ostream &OS,
265                                  const GUIDProbeFunctionMap &GUID2FuncMAP,
266                                  bool ShowName) const {
267   OS << "FUNC: ";
268   if (ShowName) {
269     StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Guid);
270     OS << FuncName.str() << " ";
271   } else {
272     OS << Guid << " ";
273   }
274   OS << "Index: " << Index << "  ";
275   OS << "Type: " << PseudoProbeTypeStr[static_cast<uint8_t>(Type)] << "  ";
276   std::string InlineContextStr = getInlineContextStr(GUID2FuncMAP, ShowName);
277   if (InlineContextStr.size()) {
278     OS << "Inlined: @ ";
279     OS << InlineContextStr;
280   }
281   OS << "\n";
282 }
283 
284 template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnencodedNumber() {
285   if (Data + sizeof(T) > End) {
286     return std::error_code();
287   }
288   T Val = endian::readNext<T, little, unaligned>(Data);
289   return ErrorOr<T>(Val);
290 }
291 
292 template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnsignedNumber() {
293   unsigned NumBytesRead = 0;
294   uint64_t Val = decodeULEB128(Data, &NumBytesRead);
295   if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
296     return std::error_code();
297   }
298   Data += NumBytesRead;
299   return ErrorOr<T>(static_cast<T>(Val));
300 }
301 
302 template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readSignedNumber() {
303   unsigned NumBytesRead = 0;
304   int64_t Val = decodeSLEB128(Data, &NumBytesRead);
305   if (Val > std::numeric_limits<T>::max() || (Data + NumBytesRead > End)) {
306     return std::error_code();
307   }
308   Data += NumBytesRead;
309   return ErrorOr<T>(static_cast<T>(Val));
310 }
311 
312 ErrorOr<StringRef> MCPseudoProbeDecoder::readString(uint32_t Size) {
313   StringRef Str(reinterpret_cast<const char *>(Data), Size);
314   if (Data + Size > End) {
315     return std::error_code();
316   }
317   Data += Size;
318   return ErrorOr<StringRef>(Str);
319 }
320 
321 bool MCPseudoProbeDecoder::buildGUID2FuncDescMap(const uint8_t *Start,
322                                                  std::size_t Size) {
323   // The pseudo_probe_desc section has a format like:
324   // .section .pseudo_probe_desc,"",@progbits
325   // .quad -5182264717993193164   // GUID
326   // .quad 4294967295             // Hash
327   // .uleb 3                      // Name size
328   // .ascii "foo"                 // Name
329   // .quad -2624081020897602054
330   // .quad 174696971957
331   // .uleb 34
332   // .ascii "main"
333 
334   Data = Start;
335   End = Data + Size;
336 
337   while (Data < End) {
338     auto ErrorOrGUID = readUnencodedNumber<uint64_t>();
339     if (!ErrorOrGUID)
340       return false;
341 
342     auto ErrorOrHash = readUnencodedNumber<uint64_t>();
343     if (!ErrorOrHash)
344       return false;
345 
346     auto ErrorOrNameSize = readUnsignedNumber<uint32_t>();
347     if (!ErrorOrNameSize)
348       return false;
349     uint32_t NameSize = std::move(*ErrorOrNameSize);
350 
351     auto ErrorOrName = readString(NameSize);
352     if (!ErrorOrName)
353       return false;
354 
355     uint64_t GUID = std::move(*ErrorOrGUID);
356     uint64_t Hash = std::move(*ErrorOrHash);
357     StringRef Name = std::move(*ErrorOrName);
358 
359     // Initialize PseudoProbeFuncDesc and populate it into GUID2FuncDescMap
360     GUID2FuncDescMap.emplace(GUID, MCPseudoProbeFuncDesc(GUID, Hash, Name));
361   }
362   assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
363   return true;
364 }
365 
366 bool MCPseudoProbeDecoder::buildAddress2ProbeMap(const uint8_t *Start,
367                                                  std::size_t Size) {
368   // The pseudo_probe section encodes an inline forest and each tree has a
369   // format like:
370   //  FUNCTION BODY (one for each uninlined function present in the text
371   //  section)
372   //     GUID (uint64)
373   //         GUID of the function
374   //     NPROBES (ULEB128)
375   //         Number of probes originating from this function.
376   //     NUM_INLINED_FUNCTIONS (ULEB128)
377   //         Number of callees inlined into this function, aka number of
378   //         first-level inlinees
379   //     PROBE RECORDS
380   //         A list of NPROBES entries. Each entry contains:
381   //           INDEX (ULEB128)
382   //           TYPE (uint4)
383   //             0 - block probe, 1 - indirect call, 2 - direct call
384   //           ATTRIBUTE (uint3)
385   //             1 - tail call, 2 - dangling
386   //           ADDRESS_TYPE (uint1)
387   //             0 - code address, 1 - address delta
388   //           CODE_ADDRESS (uint64 or ULEB128)
389   //             code address or address delta, depending on Flag
390   //     INLINED FUNCTION RECORDS
391   //         A list of NUM_INLINED_FUNCTIONS entries describing each of the
392   //         inlined callees.  Each record contains:
393   //           INLINE SITE
394   //             Index of the callsite probe (ULEB128)
395   //           FUNCTION BODY
396   //             A FUNCTION BODY entry describing the inlined function.
397 
398   Data = Start;
399   End = Data + Size;
400 
401   MCDecodedPseudoProbeInlineTree *Root = &DummyInlineRoot;
402   MCDecodedPseudoProbeInlineTree *Cur = &DummyInlineRoot;
403   uint64_t LastAddr = 0;
404   uint32_t Index = 0;
405   // A DFS-based decoding
406   while (Data < End) {
407     if (Root == Cur) {
408       // Use a sequential id for top level inliner.
409       Index = Root->getChildren().size();
410     } else {
411       // Read inline site for inlinees
412       auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
413       if (!ErrorOrIndex)
414         return false;
415       Index = std::move(*ErrorOrIndex);
416     }
417     // Switch/add to a new tree node(inlinee)
418     Cur = Cur->getOrAddNode(std::make_tuple(Cur->Guid, Index));
419     // Read guid
420     auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
421     if (!ErrorOrCurGuid)
422       return false;
423     Cur->Guid = std::move(*ErrorOrCurGuid);
424     // Read number of probes in the current node.
425     auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
426     if (!ErrorOrNodeCount)
427       return false;
428     uint32_t NodeCount = std::move(*ErrorOrNodeCount);
429     // Read number of direct inlinees
430     auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
431     if (!ErrorOrCurChildrenToProcess)
432       return false;
433     Cur->ChildrenToProcess = std::move(*ErrorOrCurChildrenToProcess);
434     // Read all probes in this node
435     for (std::size_t I = 0; I < NodeCount; I++) {
436       // Read index
437       auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
438       if (!ErrorOrIndex)
439         return false;
440       uint32_t Index = std::move(*ErrorOrIndex);
441       // Read type | flag.
442       auto ErrorOrValue = readUnencodedNumber<uint8_t>();
443       if (!ErrorOrValue)
444         return false;
445       uint8_t Value = std::move(*ErrorOrValue);
446       uint8_t Kind = Value & 0xf;
447       uint8_t Attr = (Value & 0x70) >> 4;
448       // Read address
449       uint64_t Addr = 0;
450       if (Value & 0x80) {
451         auto ErrorOrOffset = readSignedNumber<int64_t>();
452         if (!ErrorOrOffset)
453           return false;
454         int64_t Offset = std::move(*ErrorOrOffset);
455         Addr = LastAddr + Offset;
456       } else {
457         auto ErrorOrAddr = readUnencodedNumber<int64_t>();
458         if (!ErrorOrAddr)
459           return false;
460         Addr = std::move(*ErrorOrAddr);
461       }
462       // Populate Address2ProbesMap
463       auto &Probes = Address2ProbesMap[Addr];
464       Probes.emplace_back(Addr, Cur->Guid, Index, PseudoProbeType(Kind), Attr,
465                           Cur);
466       Cur->addProbes(&Probes.back());
467       LastAddr = Addr;
468     }
469 
470     // Look for the parent for the next node by subtracting the current
471     // node count from tree counts along the parent chain. The first node
472     // in the chain that has a non-zero tree count is the target.
473     while (Cur != Root) {
474       if (Cur->ChildrenToProcess == 0) {
475         Cur = static_cast<MCDecodedPseudoProbeInlineTree *>(Cur->Parent);
476         if (Cur != Root) {
477           assert(Cur->ChildrenToProcess > 0 &&
478                  "Should have some unprocessed nodes");
479           Cur->ChildrenToProcess -= 1;
480         }
481       } else {
482         break;
483       }
484     }
485   }
486 
487   assert(Data == End && "Have unprocessed data in pseudo_probe section");
488   assert(Cur == Root &&
489          " Cur should point to root when the forest is fully built up");
490   return true;
491 }
492 
493 void MCPseudoProbeDecoder::printGUID2FuncDescMap(raw_ostream &OS) {
494   OS << "Pseudo Probe Desc:\n";
495   // Make the output deterministic
496   std::map<uint64_t, MCPseudoProbeFuncDesc> OrderedMap(GUID2FuncDescMap.begin(),
497                                                        GUID2FuncDescMap.end());
498   for (auto &I : OrderedMap) {
499     I.second.print(OS);
500   }
501 }
502 
503 void MCPseudoProbeDecoder::printProbeForAddress(raw_ostream &OS,
504                                                 uint64_t Address) {
505   auto It = Address2ProbesMap.find(Address);
506   if (It != Address2ProbesMap.end()) {
507     for (auto &Probe : It->second) {
508       OS << " [Probe]:\t";
509       Probe.print(OS, GUID2FuncDescMap, true);
510     }
511   }
512 }
513 
514 void MCPseudoProbeDecoder::printProbesForAllAddresses(raw_ostream &OS) {
515   std::vector<uint64_t> Addresses;
516   for (auto Entry : Address2ProbesMap)
517     Addresses.push_back(Entry.first);
518   std::sort(Addresses.begin(), Addresses.end());
519   for (auto K : Addresses) {
520     OS << "Address:\t";
521     OS << K;
522     OS << "\n";
523     printProbeForAddress(OS, K);
524   }
525 }
526 
527 const MCDecodedPseudoProbe *
528 MCPseudoProbeDecoder::getCallProbeForAddr(uint64_t Address) const {
529   auto It = Address2ProbesMap.find(Address);
530   if (It == Address2ProbesMap.end())
531     return nullptr;
532   const auto &Probes = It->second;
533 
534   const MCDecodedPseudoProbe *CallProbe = nullptr;
535   for (const auto &Probe : Probes) {
536     if (Probe.isCall()) {
537       assert(!CallProbe &&
538              "There should be only one call probe corresponding to address "
539              "which is a callsite.");
540       CallProbe = &Probe;
541     }
542   }
543   return CallProbe;
544 }
545 
546 const MCPseudoProbeFuncDesc *
547 MCPseudoProbeDecoder::getFuncDescForGUID(uint64_t GUID) const {
548   auto It = GUID2FuncDescMap.find(GUID);
549   assert(It != GUID2FuncDescMap.end() && "Function descriptor doesn't exist");
550   return &It->second;
551 }
552 
553 void MCPseudoProbeDecoder::getInlineContextForProbe(
554     const MCDecodedPseudoProbe *Probe,
555     SmallVectorImpl<std::string> &InlineContextStack, bool IncludeLeaf) const {
556   Probe->getInlineContext(InlineContextStack, GUID2FuncDescMap, true);
557   if (!IncludeLeaf)
558     return;
559   // Note that the context from probe doesn't include leaf frame,
560   // hence we need to retrieve and prepend leaf if requested.
561   const auto *FuncDesc = getFuncDescForGUID(Probe->getGuid());
562   InlineContextStack.emplace_back(FuncDesc->FuncName + ":" +
563                                   Twine(Probe->getIndex()).str());
564 }
565 
566 const MCPseudoProbeFuncDesc *MCPseudoProbeDecoder::getInlinerDescForProbe(
567     const MCDecodedPseudoProbe *Probe) const {
568   MCDecodedPseudoProbeInlineTree *InlinerNode = Probe->getInlineTreeNode();
569   if (!InlinerNode->hasInlineSite())
570     return nullptr;
571   return getFuncDescForGUID(std::get<0>(InlinerNode->ISite));
572 }
573