Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- FunctionInfo.h -------------------------------------------*- C++ -*-===//
  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. #ifndef LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
  10. #define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
  11.  
  12. #include "llvm/DebugInfo/GSYM/ExtractRanges.h"
  13. #include "llvm/DebugInfo/GSYM/InlineInfo.h"
  14. #include "llvm/DebugInfo/GSYM/LineTable.h"
  15. #include "llvm/DebugInfo/GSYM/LookupResult.h"
  16. #include "llvm/DebugInfo/GSYM/StringTable.h"
  17. #include <cstdint>
  18. #include <tuple>
  19.  
  20. namespace llvm {
  21. class raw_ostream;
  22.  
  23. namespace gsym {
  24.  
  25. class GsymReader;
  26. /// Function information in GSYM files encodes information for one contiguous
  27. /// address range. If a function has discontiguous address ranges, they will
  28. /// need to be encoded using multiple FunctionInfo objects.
  29. ///
  30. /// ENCODING
  31. ///
  32. /// The function information gets the function start address as an argument
  33. /// to the FunctionInfo::decode(...) function. This information is calculated
  34. /// from the GSYM header and an address offset from the GSYM address offsets
  35. /// table. The encoded FunctionInfo information must be aligned to a 4 byte
  36. /// boundary.
  37. ///
  38. /// The encoded data for a FunctionInfo starts with fixed data that all
  39. /// function info objects have:
  40. ///
  41. /// ENCODING  NAME        DESCRIPTION
  42. /// ========= =========== ====================================================
  43. /// uint32_t  Size        The size in bytes of this function.
  44. /// uint32_t  Name        The string table offset of the function name.
  45. ///
  46. /// The optional data in a FunctionInfo object follows this fixed information
  47. /// and consists of a stream of tuples that consist of:
  48. ///
  49. /// ENCODING  NAME        DESCRIPTION
  50. /// ========= =========== ====================================================
  51. /// uint32_t  InfoType    An "InfoType" enumeration that describes the type
  52. ///                       of optional data that is encoded.
  53. /// uint32_t  InfoLength  The size in bytes of the encoded data that
  54. ///                       immediately follows this length if this value is
  55. ///                       greater than zero.
  56. /// uint8_t[] InfoData    Encoded bytes that represent the data for the
  57. ///                       "InfoType". These bytes are only present if
  58. ///                       "InfoLength" is greater than zero.
  59. ///
  60. /// The "InfoType" is an enumeration:
  61. ///
  62. ///   enum InfoType {
  63. ///     EndOfList = 0u,
  64. ///     LineTableInfo = 1u,
  65. ///     InlineInfo = 2u
  66. ///   };
  67. ///
  68. /// This stream of tuples is terminated by a "InfoType" whose value is
  69. /// InfoType::EndOfList and a zero for "InfoLength". This signifies the end of
  70. /// the optional information list. This format allows us to add new optional
  71. /// information data to a FunctionInfo object over time and allows older
  72. /// clients to still parse the format and skip over any data that they don't
  73. /// understand or want to parse.
  74. ///
  75. /// So the function information encoding essientially looks like:
  76. ///
  77. /// struct {
  78. ///   uint32_t Size;
  79. ///   uint32_t Name;
  80. ///   struct {
  81. ///     uint32_t InfoType;
  82. ///     uint32_t InfoLength;
  83. ///     uint8_t InfoData[InfoLength];
  84. ///   }[N];
  85. /// }
  86. ///
  87. /// Where "N" is the number of tuples.
  88. struct FunctionInfo {
  89.   AddressRange Range;
  90.   uint32_t Name; ///< String table offset in the string table.
  91.   std::optional<LineTable> OptLineTable;
  92.   std::optional<InlineInfo> Inline;
  93.  
  94.   FunctionInfo(uint64_t Addr = 0, uint64_t Size = 0, uint32_t N = 0)
  95.       : Range(Addr, Addr + Size), Name(N) {}
  96.  
  97.   /// Query if a FunctionInfo has rich debug info.
  98.   ///
  99.   /// \returns A bool that indicates if this object has something else than
  100.   /// range and name. When converting information from a symbol table and from
  101.   /// debug info, we might end up with multiple FunctionInfo objects for the
  102.   /// same range and we need to be able to tell which one is the better object
  103.   /// to use.
  104.   bool hasRichInfo() const { return OptLineTable || Inline; }
  105.  
  106.   /// Query if a FunctionInfo object is valid.
  107.   ///
  108.   /// Address and size can be zero and there can be no line entries for a
  109.   /// symbol so the only indication this entry is valid is if the name is
  110.   /// not zero. This can happen when extracting information from symbol
  111.   /// tables that do not encode symbol sizes. In that case only the
  112.   /// address and name will be filled in.
  113.   ///
  114.   /// \returns A boolean indicating if this FunctionInfo is valid.
  115.   bool isValid() const {
  116.     return Name != 0;
  117.   }
  118.  
  119.   /// Decode an object from a binary data stream.
  120.   ///
  121.   /// \param Data The binary stream to read the data from. This object must
  122.   /// have the data for the object starting at offset zero. The data
  123.   /// can contain more data than needed.
  124.   ///
  125.   /// \param BaseAddr The FunctionInfo's start address and will be used as the
  126.   /// base address when decoding any contained information like the line table
  127.   /// and the inline info.
  128.   ///
  129.   /// \returns An FunctionInfo or an error describing the issue that was
  130.   /// encountered during decoding.
  131.   static llvm::Expected<FunctionInfo> decode(DataExtractor &Data,
  132.                                              uint64_t BaseAddr);
  133.  
  134.   /// Encode this object into FileWriter stream.
  135.   ///
  136.   /// \param O The binary stream to write the data to at the current file
  137.   /// position.
  138.   ///
  139.   /// \returns An error object that indicates failure or the offset of the
  140.   /// function info that was successfully written into the stream.
  141.   llvm::Expected<uint64_t> encode(FileWriter &O) const;
  142.  
  143.  
  144.   /// Lookup an address within a FunctionInfo object's data stream.
  145.   ///
  146.   /// Instead of decoding an entire FunctionInfo object when doing lookups,
  147.   /// we can decode only the information we need from the FunctionInfo's data
  148.   /// for the specific address. The lookup result information is returned as
  149.   /// a LookupResult.
  150.   ///
  151.   /// \param Data The binary stream to read the data from. This object must
  152.   /// have the data for the object starting at offset zero. The data
  153.   /// can contain more data than needed.
  154.   ///
  155.   /// \param GR The GSYM reader that contains the string and file table that
  156.   /// will be used to fill in information in the returned result.
  157.   ///
  158.   /// \param FuncAddr The function start address decoded from the GsymReader.
  159.   ///
  160.   /// \param Addr The address to lookup.
  161.   ///
  162.   /// \returns An LookupResult or an error describing the issue that was
  163.   /// encountered during decoding. An error should only be returned if the
  164.   /// address is not contained in the FunctionInfo or if the data is corrupted.
  165.   static llvm::Expected<LookupResult> lookup(DataExtractor &Data,
  166.                                              const GsymReader &GR,
  167.                                              uint64_t FuncAddr,
  168.                                              uint64_t Addr);
  169.  
  170.   uint64_t startAddress() const { return Range.start(); }
  171.   uint64_t endAddress() const { return Range.end(); }
  172.   uint64_t size() const { return Range.size(); }
  173.  
  174.   void clear() {
  175.     Range = {0, 0};
  176.     Name = 0;
  177.     OptLineTable = std::nullopt;
  178.     Inline = std::nullopt;
  179.   }
  180. };
  181.  
  182. inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
  183.   return LHS.Range == RHS.Range && LHS.Name == RHS.Name &&
  184.          LHS.OptLineTable == RHS.OptLineTable && LHS.Inline == RHS.Inline;
  185. }
  186. inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
  187.   return !(LHS == RHS);
  188. }
  189. /// This sorting will order things consistently by address range first, but then
  190. /// followed by inlining being valid and line tables. We might end up with a
  191. /// FunctionInfo from debug info that will have the same range as one from the
  192. /// symbol table, but we want to quickly be able to sort and use the best version
  193. /// when creating the final GSYM file.
  194. inline bool operator<(const FunctionInfo &LHS, const FunctionInfo &RHS) {
  195.   // First sort by address range
  196.   if (LHS.Range != RHS.Range)
  197.     return LHS.Range < RHS.Range;
  198.  
  199.   // Then sort by inline
  200.   if (LHS.Inline.has_value() != RHS.Inline.has_value())
  201.     return RHS.Inline.has_value();
  202.  
  203.   return LHS.OptLineTable < RHS.OptLineTable;
  204. }
  205.  
  206. raw_ostream &operator<<(raw_ostream &OS, const FunctionInfo &R);
  207.  
  208. } // namespace gsym
  209. } // namespace llvm
  210.  
  211. #endif // LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
  212.