//===- FunctionInfo.h -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H #define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H #include "llvm/ADT/SmallString.h" #include "llvm/DebugInfo/GSYM/ExtractRanges.h" #include "llvm/DebugInfo/GSYM/InlineInfo.h" #include "llvm/DebugInfo/GSYM/LineTable.h" #include "llvm/DebugInfo/GSYM/LookupResult.h" #include "llvm/DebugInfo/GSYM/MergedFunctionsInfo.h" #include "llvm/DebugInfo/GSYM/StringTable.h" #include <cstdint> namespace llvm { class raw_ostream; namespace gsym { class GsymReader; /// Function information in GSYM files encodes information for one contiguous /// address range. If a function has discontiguous address ranges, they will /// need to be encoded using multiple FunctionInfo objects. /// /// ENCODING /// /// The function information gets the function start address as an argument /// to the FunctionInfo::decode(...) function. This information is calculated /// from the GSYM header and an address offset from the GSYM address offsets /// table. The encoded FunctionInfo information must be aligned to a 4 byte /// boundary. /// /// The encoded data for a FunctionInfo starts with fixed data that all /// function info objects have: /// /// ENCODING NAME DESCRIPTION /// ========= =========== ==================================================== /// uint32_t Size The size in bytes of this function. /// uint32_t Name The string table offset of the function name. /// /// The optional data in a FunctionInfo object follows this fixed information /// and consists of a stream of tuples that consist of: /// /// ENCODING NAME DESCRIPTION /// ========= =========== ==================================================== /// uint32_t InfoType An "InfoType" enumeration that describes the type /// of optional data that is encoded. /// uint32_t InfoLength The size in bytes of the encoded data that /// immediately follows this length if this value is /// greater than zero. /// uint8_t[] InfoData Encoded bytes that represent the data for the /// "InfoType". These bytes are only present if /// "InfoLength" is greater than zero. /// /// The "InfoType" is an enumeration: /// /// enum InfoType { /// EndOfList = 0u, /// LineTableInfo = 1u, /// InlineInfo = 2u /// }; /// /// This stream of tuples is terminated by a "InfoType" whose value is /// InfoType::EndOfList and a zero for "InfoLength". This signifies the end of /// the optional information list. This format allows us to add new optional /// information data to a FunctionInfo object over time and allows older /// clients to still parse the format and skip over any data that they don't /// understand or want to parse. /// /// So the function information encoding essientially looks like: /// /// struct { /// uint32_t Size; /// uint32_t Name; /// struct { /// uint32_t InfoType; /// uint32_t InfoLength; /// uint8_t InfoData[InfoLength]; /// }[N]; /// } /// /// Where "N" is the number of tuples. struct FunctionInfo { … }; inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) { … } inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { … } /// This sorting will order things consistently by address range first, but /// then followed by increasing levels of debug info like inline information /// and line tables. We might end up with a FunctionInfo from debug info that /// will have the same range as one from the symbol table, but we want to /// quickly be able to sort and use the best version when creating the final /// GSYM file. This function compares the inline information as we have seen /// cases where LTO can generate a wide array of differing inline information, /// mostly due to messing up the address ranges for inlined functions, so the /// inline information with the most entries will appeear last. If the inline /// information match, either by both function infos not having any or both /// being exactly the same, we will then compare line tables. Comparing line /// tables allows the entry with the most line entries to appear last. This /// ensures we are able to save the FunctionInfo with the most debug info into /// the GSYM file. inline bool operator<(const FunctionInfo &LHS, const FunctionInfo &RHS) { … } raw_ostream &operator<<(raw_ostream &OS, const FunctionInfo &R); } // namespace gsym } // namespace llvm #endif // LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H