Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:42

0001 //===- InlineInfo.h ---------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_GSYM_INLINEINFO_H
0010 #define LLVM_DEBUGINFO_GSYM_INLINEINFO_H
0011 
0012 #include "llvm/DebugInfo/GSYM/ExtractRanges.h"
0013 #include "llvm/DebugInfo/GSYM/LineEntry.h"
0014 #include "llvm/DebugInfo/GSYM/LookupResult.h"
0015 #include "llvm/Support/Error.h"
0016 #include <stdint.h>
0017 #include <vector>
0018 
0019 namespace llvm {
0020 class raw_ostream;
0021 
0022 namespace gsym {
0023 
0024 class GsymReader;
0025 /// Inline information stores the name of the inline function along with
0026 /// an array of address ranges. It also stores the call file and call line
0027 /// that called this inline function. This allows us to unwind inline call
0028 /// stacks back to the inline or concrete function that called this
0029 /// function. Inlined functions contained in this function are stored in the
0030 /// "Children" variable. All address ranges must be sorted and all address
0031 /// ranges of all children must be contained in the ranges of this function.
0032 /// Any clients that encode information will need to ensure the ranges are
0033 /// all contined correctly or lookups could fail. Add ranges in these objects
0034 /// must be contained in the top level FunctionInfo address ranges as well.
0035 ///
0036 /// ENCODING
0037 ///
0038 /// When saved to disk, the inline info encodes all ranges to be relative to
0039 /// a parent address range. This will be the FunctionInfo's start address if
0040 /// the InlineInfo is directly contained in a FunctionInfo, or a the start
0041 /// address of the containing parent InlineInfo's first "Ranges" member. This
0042 /// allows address ranges to be efficiently encoded using ULEB128 encodings as
0043 /// we encode the offset and size of each range instead of full addresses. This
0044 /// also makes any encoded addresses easy to relocate as we just need to
0045 /// relocate the FunctionInfo's start address.
0046 ///
0047 /// - The AddressRanges member "Ranges" is encoded using an appropriate base
0048 ///   address as described above.
0049 /// - UINT8 boolean value that specifies if the InlineInfo object has children.
0050 /// - UINT32 string table offset that points to the name of the inline
0051 ///   function.
0052 /// - ULEB128 integer that specifies the file of the call site that called
0053 ///   this function.
0054 /// - ULEB128 integer that specifies the source line of the call site that
0055 ///   called this function.
0056 /// - if this object has children, enocode each child InlineInfo using the
0057 ///   the first address range's start address as the base address.
0058 ///
0059 struct InlineInfo {
0060 
0061   uint32_t Name; ///< String table offset in the string table.
0062   uint32_t CallFile; ///< 1 based file index in the file table.
0063   uint32_t CallLine; ///< Source line number.
0064   AddressRanges Ranges;
0065   std::vector<InlineInfo> Children;
0066   InlineInfo() : Name(0), CallFile(0), CallLine(0) {}
0067   void clear() {
0068     Name = 0;
0069     CallFile = 0;
0070     CallLine = 0;
0071     Ranges.clear();
0072     Children.clear();
0073   }
0074   bool isValid() const { return !Ranges.empty(); }
0075 
0076   using InlineArray = std::vector<const InlineInfo *>;
0077 
0078   /// Lookup a single address within the inline info data.
0079   ///
0080   /// Clients have the option to decode an entire InlineInfo object (using
0081   /// InlineInfo::decode() ) or just find the matching inline info using this
0082   /// function. The benefit of using this function is that only the information
0083   /// needed for the lookup will be extracted, other info can be skipped and
0084   /// parsing can stop as soon as the deepest match is found. This allows
0085   /// symbolication tools to be fast and efficient and avoid allocation costs
0086   /// when doing lookups.
0087   ///
0088   /// This function will augment the SourceLocations array \a SrcLocs with any
0089   /// inline information that pertains to \a Addr. If no inline information
0090   /// exists for \a Addr, then \a SrcLocs will be left untouched. If there is
0091   /// inline information for \a Addr, then \a SrcLocs will be modifiied to
0092   /// contain the deepest most inline function's SourceLocation at index zero
0093   /// in the array and proceed up the concrete function source file and
0094   /// line at the end of the array.
0095   ///
0096   /// \param GR The GSYM reader that contains the string and file table that
0097   /// will be used to fill in the source locations.
0098   ///
0099   /// \param Data The binary stream to read the data from. This object must
0100   /// have the data for the LineTable object starting at offset zero. The data
0101   /// can contain more data than needed.
0102   ///
0103   /// \param BaseAddr The base address to use when decoding the line table.
0104   /// This will be the FunctionInfo's start address and will be used to
0105   /// decode the correct addresses for the inline information.
0106   ///
0107   /// \param Addr The address to lookup.
0108   ///
0109   /// \param SrcLocs The inline source locations that matches \a Addr. This
0110   ///                array must be initialized with the matching line entry
0111   ///                from the line table upon entry. The name of the concrete
0112   ///                function must be supplied since it will get pushed to
0113   ///                the last SourceLocation entry and the inline information
0114   ///                will fill in the source file and line from the inline
0115   ///                information.
0116   ///
0117   /// \returns An error if the inline information is corrupt, or
0118   ///          Error::success() for all other cases, even when no information
0119   ///          is added to \a SrcLocs.
0120   static llvm::Error lookup(const GsymReader &GR, DataExtractor &Data,
0121                             uint64_t BaseAddr, uint64_t Addr,
0122                             SourceLocations &SrcLocs);
0123 
0124   /// Lookup an address in the InlineInfo object
0125   ///
0126   /// This function is used to symbolicate an inline call stack and can
0127   /// turn one address in the program into one or more inline call stacks
0128   /// and have the stack trace show the original call site from
0129   /// non-inlined code.
0130   ///
0131   /// \param Addr the address to lookup
0132   ///
0133   /// \returns optional vector of InlineInfo objects that describe the
0134   /// inline call stack for a given address, false otherwise.
0135   std::optional<InlineArray> getInlineStack(uint64_t Addr) const;
0136 
0137   /// Decode an InlineInfo object from a binary data stream.
0138   ///
0139   /// \param Data The binary stream to read the data from. This object must
0140   /// have the data for the InlineInfo object starting at offset zero. The data
0141   /// can contain more data than needed.
0142   ///
0143   /// \param BaseAddr The base address to use when decoding all address ranges.
0144   /// This will be the FunctionInfo's start address if this object is directly
0145   /// contained in a FunctionInfo object, or the start address of the first
0146   /// address range in an InlineInfo object of this object is a child of
0147   /// another InlineInfo object.
0148   /// \returns An InlineInfo or an error describing the issue that was
0149   /// encountered during decoding.
0150   static llvm::Expected<InlineInfo> decode(DataExtractor &Data,
0151                                            uint64_t BaseAddr);
0152 
0153   /// Encode this InlineInfo object into FileWriter stream.
0154   ///
0155   /// \param O The binary stream to write the data to at the current file
0156   /// position.
0157   ///
0158   /// \param BaseAddr The base address to use when encoding all address ranges.
0159   /// This will be the FunctionInfo's start address if this object is directly
0160   /// contained in a FunctionInfo object, or the start address of the first
0161   /// address range in an InlineInfo object of this object is a child of
0162   /// another InlineInfo object.
0163   ///
0164   /// \returns An error object that indicates success or failure or the
0165   /// encoding process.
0166   llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const;
0167 
0168   /// Compare InlineInfo objects.
0169   ///
0170   /// When comparing InlineInfo objects the item with the most inline functions
0171   /// wins. If we have two FunctionInfo objects that both have the same address
0172   /// range and both have valid InlineInfo objects, we want the one with the
0173   /// most inline functions to win so we save the most information possible
0174   /// to the GSYM file. We have seen cases where LTO messes up the inline
0175   /// function information for the same address range, so this helps ensure we
0176   /// get the most descriptive information we can for an address range.
0177   bool operator<(const InlineInfo &RHS) const;
0178 };
0179 
0180 inline bool operator==(const InlineInfo &LHS, const InlineInfo &RHS) {
0181   return LHS.Name == RHS.Name && LHS.CallFile == RHS.CallFile &&
0182          LHS.CallLine == RHS.CallLine && LHS.Ranges == RHS.Ranges &&
0183          LHS.Children == RHS.Children;
0184 }
0185 
0186 raw_ostream &operator<<(raw_ostream &OS, const InlineInfo &FI);
0187 
0188 } // namespace gsym
0189 } // namespace llvm
0190 
0191 #endif // LLVM_DEBUGINFO_GSYM_INLINEINFO_H