LLVM  10.0.0svn
InlineInfo.cpp
Go to the documentation of this file.
1 //===- InlineInfo.cpp -------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
14 #include <algorithm>
15 #include <inttypes.h>
16 
17 using namespace llvm;
18 using namespace gsym;
19 
20 
22  if (!II.isValid())
23  return OS;
24  bool First = true;
25  for (auto Range : II.Ranges) {
26  if (First)
27  First = false;
28  else
29  OS << ' ';
30  OS << Range;
31  }
32  OS << " Name = " << HEX32(II.Name) << ", CallFile = " << II.CallFile
33  << ", CallLine = " << II.CallFile << '\n';
34  for (const auto &Child : II.Children)
35  OS << Child;
36  return OS;
37 }
38 
39 static bool getInlineStackHelper(const InlineInfo &II, uint64_t Addr,
40  std::vector<const InlineInfo *> &InlineStack) {
41  if (II.Ranges.contains(Addr)) {
42  // If this is the top level that represents the concrete function,
43  // there will be no name and we shoud clear the inline stack. Otherwise
44  // we have found an inline call stack that we need to insert.
45  if (II.Name != 0)
46  InlineStack.insert(InlineStack.begin(), &II);
47  for (const auto &Child : II.Children) {
48  if (::getInlineStackHelper(Child, Addr, InlineStack))
49  break;
50  }
51  return !InlineStack.empty();
52  }
53  return false;
54 }
55 
57  InlineArray Result;
58  if (getInlineStackHelper(*this, Addr, Result))
59  return Result;
60  return llvm::None;
61 }
62 
63 /// Decode an InlineInfo in Data at the specified offset.
64 ///
65 /// A local helper function to decode InlineInfo objects. This function is
66 /// called recursively when parsing child InlineInfo objects.
67 ///
68 /// \param Data The data extractor to decode from.
69 /// \param Offset The offset within \a Data to decode from.
70 /// \param BaseAddr The base address to use when decoding address ranges.
71 /// \returns An InlineInfo or an error describing the issue that was
72 /// encountered during decoding.
74  uint64_t BaseAddr) {
75  InlineInfo Inline;
76  if (!Data.isValidOffset(Offset))
77  return createStringError(std::errc::io_error,
78  "0x%8.8" PRIx64 ": missing InlineInfo address ranges data", Offset);
79  Inline.Ranges.decode(Data, BaseAddr, Offset);
80  if (Inline.Ranges.empty())
81  return Inline;
82  if (!Data.isValidOffsetForDataOfSize(Offset, 1))
83  return createStringError(std::errc::io_error,
84  "0x%8.8" PRIx64 ": missing InlineInfo uint8_t indicating children",
85  Offset);
86  bool HasChildren = Data.getU8(&Offset) != 0;
87  if (!Data.isValidOffsetForDataOfSize(Offset, 4))
88  return createStringError(std::errc::io_error,
89  "0x%8.8" PRIx64 ": missing InlineInfo uint32_t for name", Offset);
90  Inline.Name = Data.getU32(&Offset);
91  if (!Data.isValidOffset(Offset))
92  return createStringError(std::errc::io_error,
93  "0x%8.8" PRIx64 ": missing ULEB128 for InlineInfo call file", Offset);
94  Inline.CallFile = (uint32_t)Data.getULEB128(&Offset);
95  if (!Data.isValidOffset(Offset))
96  return createStringError(std::errc::io_error,
97  "0x%8.8" PRIx64 ": missing ULEB128 for InlineInfo call line", Offset);
98  Inline.CallLine = (uint32_t)Data.getULEB128(&Offset);
99  if (HasChildren) {
100  // Child address ranges are encoded relative to the first address in the
101  // parent InlineInfo object.
102  const auto ChildBaseAddr = Inline.Ranges[0].Start;
103  while (true) {
104  llvm::Expected<InlineInfo> Child = decode(Data, Offset, ChildBaseAddr);
105  if (!Child)
106  return Child.takeError();
107  // InlineInfo with empty Ranges termintes a child sibling chain.
108  if (Child.get().Ranges.empty())
109  break;
110  Inline.Children.emplace_back(std::move(*Child));
111  }
112  }
113  return Inline;
114 }
115 
117  uint64_t BaseAddr) {
118  uint64_t Offset = 0;
119  return ::decode(Data, Offset, BaseAddr);
120 }
121 
122 llvm::Error InlineInfo::encode(FileWriter &O, uint64_t BaseAddr) const {
123  // Users must verify the InlineInfo is valid prior to calling this funtion.
124  // We don't want to emit any InlineInfo objects if they are not valid since
125  // it will waste space in the GSYM file.
126  if (!isValid())
127  return createStringError(std::errc::invalid_argument,
128  "attempted to encode invalid InlineInfo object");
129  Ranges.encode(O, BaseAddr);
130  bool HasChildren = !Children.empty();
131  O.writeU8(HasChildren);
132  O.writeU32(Name);
133  O.writeULEB(CallFile);
134  O.writeULEB(CallLine);
135  if (HasChildren) {
136  // Child address ranges are encoded as relative to the first
137  // address in the Ranges for this object. This keeps the offsets
138  // small and allows for efficient encoding using ULEB offsets.
139  const uint64_t ChildBaseAddr = Ranges[0].Start;
140  for (const auto &Child : Children) {
141  // Make sure all child address ranges are contained in the parent address
142  // ranges.
143  for (const auto &ChildRange: Child.Ranges) {
144  if (!Ranges.contains(ChildRange))
145  return createStringError(std::errc::invalid_argument,
146  "child range not contained in parent");
147  }
148  llvm::Error Err = Child.encode(O, ChildBaseAddr);
149  if (Err)
150  return Err;
151  }
152 
153  // Terminate child sibling chain by emitting a zero. This zero will cause
154  // the decodeAll() function above to return false and stop the decoding
155  // of child InlineInfo objects that are siblings.
156  O.writeULEB(0);
157  }
158  return Error::success();
159 }
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void writeU8(uint8_t Value)
Write a single uint8_t value into the stream at the current file position.
Definition: FileWriter.cpp:34
void writeULEB(uint64_t Value)
Write the value into the stream encoded using unsigned LEB128 at the current file position...
Definition: FileWriter.cpp:27
Inline information stores the name of the inline function along with an array of address ranges...
Definition: InlineInfo.h:58
bool contains(uint64_t Addr) const
Definition: Range.cpp:38
uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
void writeU32(uint32_t Value)
Write a single uint32_t value into the stream at the current file position.
Definition: FileWriter.cpp:43
uint32_t Name
String table offset in the string table.
Definition: InlineInfo.h:60
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
std::vector< InlineInfo > Children
Definition: InlineInfo.h:64
llvm::Optional< InlineArray > getInlineStack(uint64_t Addr) const
Lookup an address in the InlineInfo object.
Definition: InlineInfo.cpp:56
A simplified binary data writer class that doesn&#39;t require targets, target definitions, architectures, or require any other optional compile time libraries to be enabled via the build process.
Definition: FileWriter.h:29
bool empty() const
Definition: Range.h:81
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t BaseAddr)
Decode an InlineInfo object from a binary data stream.
Definition: InlineInfo.cpp:116
std::vector< const InlineInfo * > InlineArray
Definition: InlineInfo.h:75
uint32_t CallFile
1 based file index in the file table.
Definition: InlineInfo.h:61
AddressRanges Ranges
Definition: InlineInfo.h:63
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
reference get()
Returns a reference to the stored T value.
Definition: Error.h:532
void encode(FileWriter &O, uint64_t BaseAddr) const
Definition: Range.cpp:85
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
uint32_t CallLine
Source line number.
Definition: InlineInfo.h:62
static bool getInlineStackHelper(const InlineInfo &II, uint64_t Addr, std::vector< const InlineInfo *> &InlineStack)
Definition: InlineInfo.cpp:39
void decode(DataExtractor &Data, uint64_t BaseAddr, uint64_t &Offset)
Address ranges are decoded and encoded to be relative to a base address.
Definition: Range.cpp:93
#define HEX32(v)
Definition: Range.h:19
bool isValid() const
Definition: InlineInfo.h:73
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
Definition: InlineInfo.cpp:73
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const
Encode this InlineInfo object into FileWriter stream.
Definition: InlineInfo.cpp:122
raw_ostream & operator<<(raw_ostream &OS, const FunctionInfo &R)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1197