InlineInfo.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- InlineInfo.h ---------------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_GSYM_INLINEINFO_H
  14. #define LLVM_DEBUGINFO_GSYM_INLINEINFO_H
  15. #include "llvm/ADT/Optional.h"
  16. #include "llvm/DebugInfo/GSYM/LineEntry.h"
  17. #include "llvm/DebugInfo/GSYM/LookupResult.h"
  18. #include "llvm/DebugInfo/GSYM/Range.h"
  19. #include "llvm/Support/Error.h"
  20. #include <stdint.h>
  21. #include <vector>
  22. namespace llvm {
  23. class raw_ostream;
  24. namespace gsym {
  25. class GsymReader;
  26. /// Inline information stores the name of the inline function along with
  27. /// an array of address ranges. It also stores the call file and call line
  28. /// that called this inline function. This allows us to unwind inline call
  29. /// stacks back to the inline or concrete function that called this
  30. /// function. Inlined functions contained in this function are stored in the
  31. /// "Children" variable. All address ranges must be sorted and all address
  32. /// ranges of all children must be contained in the ranges of this function.
  33. /// Any clients that encode information will need to ensure the ranges are
  34. /// all contined correctly or lookups could fail. Add ranges in these objects
  35. /// must be contained in the top level FunctionInfo address ranges as well.
  36. ///
  37. /// ENCODING
  38. ///
  39. /// When saved to disk, the inline info encodes all ranges to be relative to
  40. /// a parent address range. This will be the FunctionInfo's start address if
  41. /// the InlineInfo is directly contained in a FunctionInfo, or a the start
  42. /// address of the containing parent InlineInfo's first "Ranges" member. This
  43. /// allows address ranges to be efficiently encoded using ULEB128 encodings as
  44. /// we encode the offset and size of each range instead of full addresses. This
  45. /// also makes any encoded addresses easy to relocate as we just need to
  46. /// relocate the FunctionInfo's start address.
  47. ///
  48. /// - The AddressRanges member "Ranges" is encoded using an appropriate base
  49. /// address as described above.
  50. /// - UINT8 boolean value that specifies if the InlineInfo object has children.
  51. /// - UINT32 string table offset that points to the name of the inline
  52. /// function.
  53. /// - ULEB128 integer that specifies the file of the call site that called
  54. /// this function.
  55. /// - ULEB128 integer that specifies the source line of the call site that
  56. /// called this function.
  57. /// - if this object has children, enocode each child InlineInfo using the
  58. /// the first address range's start address as the base address.
  59. ///
  60. struct InlineInfo {
  61. uint32_t Name; ///< String table offset in the string table.
  62. uint32_t CallFile; ///< 1 based file index in the file table.
  63. uint32_t CallLine; ///< Source line number.
  64. AddressRanges Ranges;
  65. std::vector<InlineInfo> Children;
  66. InlineInfo() : Name(0), CallFile(0), CallLine(0) {}
  67. void clear() {
  68. Name = 0;
  69. CallFile = 0;
  70. CallLine = 0;
  71. Ranges.clear();
  72. Children.clear();
  73. }
  74. bool isValid() const { return !Ranges.empty(); }
  75. using InlineArray = std::vector<const InlineInfo *>;
  76. /// Lookup a single address within the inline info data.
  77. ///
  78. /// Clients have the option to decode an entire InlineInfo object (using
  79. /// InlineInfo::decode() ) or just find the matching inline info using this
  80. /// function. The benefit of using this function is that only the information
  81. /// needed for the lookup will be extracted, other info can be skipped and
  82. /// parsing can stop as soon as the deepest match is found. This allows
  83. /// symbolication tools to be fast and efficient and avoid allocation costs
  84. /// when doing lookups.
  85. ///
  86. /// This function will augment the SourceLocations array \a SrcLocs with any
  87. /// inline information that pertains to \a Addr. If no inline information
  88. /// exists for \a Addr, then \a SrcLocs will be left untouched. If there is
  89. /// inline information for \a Addr, then \a SrcLocs will be modifiied to
  90. /// contain the deepest most inline function's SourceLocation at index zero
  91. /// in the array and proceed up the the concrete function source file and
  92. /// line at the end of the array.
  93. ///
  94. /// \param GR The GSYM reader that contains the string and file table that
  95. /// will be used to fill in the source locations.
  96. ///
  97. /// \param Data The binary stream to read the data from. This object must
  98. /// have the data for the LineTable object starting at offset zero. The data
  99. /// can contain more data than needed.
  100. ///
  101. /// \param BaseAddr The base address to use when decoding the line table.
  102. /// This will be the FunctionInfo's start address and will be used to
  103. /// decode the correct addresses for the inline information.
  104. ///
  105. /// \param Addr The address to lookup.
  106. ///
  107. /// \param SrcLocs The inline source locations that matches \a Addr. This
  108. /// array must be initialized with the matching line entry
  109. /// from the line table upon entry. The name of the concrete
  110. /// function must be supplied since it will get pushed to
  111. /// the last SourceLocation entry and the inline information
  112. /// will fill in the source file and line from the inline
  113. /// information.
  114. ///
  115. /// \returns An error if the inline information is corrupt, or
  116. /// Error::success() for all other cases, even when no information
  117. /// is added to \a SrcLocs.
  118. static llvm::Error lookup(const GsymReader &GR, DataExtractor &Data,
  119. uint64_t BaseAddr, uint64_t Addr,
  120. SourceLocations &SrcLocs);
  121. /// Lookup an address in the InlineInfo object
  122. ///
  123. /// This function is used to symbolicate an inline call stack and can
  124. /// turn one address in the program into one or more inline call stacks
  125. /// and have the stack trace show the original call site from
  126. /// non-inlined code.
  127. ///
  128. /// \param Addr the address to lookup
  129. ///
  130. /// \returns optional vector of InlineInfo objects that describe the
  131. /// inline call stack for a given address, false otherwise.
  132. llvm::Optional<InlineArray> getInlineStack(uint64_t Addr) const;
  133. /// Decode an InlineInfo object from a binary data stream.
  134. ///
  135. /// \param Data The binary stream to read the data from. This object must
  136. /// have the data for the InlineInfo object starting at offset zero. The data
  137. /// can contain more data than needed.
  138. ///
  139. /// \param BaseAddr The base address to use when decoding all address ranges.
  140. /// This will be the FunctionInfo's start address if this object is directly
  141. /// contained in a FunctionInfo object, or the start address of the first
  142. /// address range in an InlineInfo object of this object is a child of
  143. /// another InlineInfo object.
  144. /// \returns An InlineInfo or an error describing the issue that was
  145. /// encountered during decoding.
  146. static llvm::Expected<InlineInfo> decode(DataExtractor &Data,
  147. uint64_t BaseAddr);
  148. /// Encode this InlineInfo object into FileWriter stream.
  149. ///
  150. /// \param O The binary stream to write the data to at the current file
  151. /// position.
  152. ///
  153. /// \param BaseAddr The base address to use when encoding all address ranges.
  154. /// This will be the FunctionInfo's start address if this object is directly
  155. /// contained in a FunctionInfo object, or the start address of the first
  156. /// address range in an InlineInfo object of this object is a child of
  157. /// another InlineInfo object.
  158. ///
  159. /// \returns An error object that indicates success or failure or the
  160. /// encoding process.
  161. llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const;
  162. };
  163. inline bool operator==(const InlineInfo &LHS, const InlineInfo &RHS) {
  164. return LHS.Name == RHS.Name && LHS.CallFile == RHS.CallFile &&
  165. LHS.CallLine == RHS.CallLine && LHS.Ranges == RHS.Ranges &&
  166. LHS.Children == RHS.Children;
  167. }
  168. raw_ostream &operator<<(raw_ostream &OS, const InlineInfo &FI);
  169. } // namespace gsym
  170. } // namespace llvm
  171. #endif // #ifndef LLVM_DEBUGINFO_GSYM_INLINEINFO_H
  172. #ifdef __GNUC__
  173. #pragma GCC diagnostic pop
  174. #endif