diff options
author | vvvv <vvvv@ydb.tech> | 2024-02-06 20:01:22 +0300 |
---|---|---|
committer | vvvv <vvvv@ydb.tech> | 2024-02-06 20:22:16 +0300 |
commit | 0203b7a9a40828bb2bd4c32029b79ff0ea3d1f8f (patch) | |
tree | e630d0d5bd0bd29fc8c2d2842ed2cfde781b993a /contrib/libs/llvm16/include/llvm/DebugInfo | |
parent | ba27db76d99d12a4f1c06960b5449423218614c4 (diff) | |
download | ydb-0203b7a9a40828bb2bd4c32029b79ff0ea3d1f8f.tar.gz |
llvm16 targets
Diffstat (limited to 'contrib/libs/llvm16/include/llvm/DebugInfo')
14 files changed, 2086 insertions, 0 deletions
diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/DwarfTransformer.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/DwarfTransformer.h new file mode 100644 index 0000000000..30df451ceb --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/DwarfTransformer.h @@ -0,0 +1,102 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- DwarfTransformer.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_DWARFTRANSFORMER_H +#define LLVM_DEBUGINFO_GSYM_DWARFTRANSFORMER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/GSYM/ExtractRanges.h" +#include "llvm/Support/Error.h" + +namespace llvm { + +class raw_ostream; + +namespace gsym { + +struct CUInfo; +struct FunctionInfo; +class GsymCreator; + +/// A class that transforms the DWARF in a DWARFContext into GSYM information +/// by populating the GsymCreator object that it is constructed with. This +/// class supports converting all DW_TAG_subprogram DIEs into +/// gsym::FunctionInfo objects that includes line table information and inline +/// function information. Creating a separate class to transform this data +/// allows this class to be unit tested. +class DwarfTransformer { +public: + + /// Create a DWARF transformer. + /// + /// \param D The DWARF to use when converting to GSYM. + /// + /// \param OS The stream to log warnings and non fatal issues to. + /// + /// \param G The GSYM creator to populate with the function information + /// from the debug info. + DwarfTransformer(DWARFContext &D, raw_ostream &OS, GsymCreator &G) : + DICtx(D), Log(OS), Gsym(G) {} + + /// Extract the DWARF from the supplied object file and convert it into the + /// Gsym format in the GsymCreator object that is passed in. Returns an + /// error if something fatal is encountered. + /// + /// \returns An error indicating any fatal issues that happen when parsing + /// the DWARF, or Error::success() if all goes well. + llvm::Error convert(uint32_t NumThreads); + + llvm::Error verify(StringRef GsymPath); + + +private: + + /// Parse the DWARF in the object file and convert it into the GsymCreator. + Error parse(); + + /// Handle any DIE (debug info entry) from the DWARF. + /// + /// This function will find all DW_TAG_subprogram DIEs that convert them into + /// GSYM FuntionInfo objects and add them to the GsymCreator supplied during + /// construction. The DIE and all its children will be recursively parsed + /// with calls to this function. + /// + /// \param Strm The thread specific log stream for any non fatal errors and + /// warnings. Once a thread has finished parsing an entire compile unit, all + /// information in this temporary stream will be forwarded to the member + /// variable log. This keeps logging thread safe. + /// + /// \param CUI The compile unit specific information that contains the DWARF + /// line table, cached file list, and other compile unit specific + /// information. + /// + /// \param Die The DWARF debug info entry to parse. + void handleDie(raw_ostream &Strm, CUInfo &CUI, DWARFDie Die); + + DWARFContext &DICtx; + raw_ostream &Log; + GsymCreator &Gsym; + + friend class DwarfTransformerTest; +}; + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_DWARFTRANSFORMER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/ExtractRanges.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/ExtractRanges.h new file mode 100644 index 0000000000..8819d50e27 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/ExtractRanges.h @@ -0,0 +1,92 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- ExtractRanges.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_EXTRACTRANGES_H +#define LLVM_DEBUGINFO_GSYM_EXTRACTRANGES_H + +#include "llvm/ADT/AddressRanges.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include <stdint.h> +#include <vector> + +#define HEX8(v) llvm::format_hex(v, 4) +#define HEX16(v) llvm::format_hex(v, 6) +#define HEX32(v) llvm::format_hex(v, 10) +#define HEX64(v) llvm::format_hex(v, 18) + +namespace llvm { +class DataExtractor; +class raw_ostream; + +namespace gsym { + +class FileWriter; + +/// AddressRange objects are encoded and decoded to be relative to a base +/// address. This will be the FunctionInfo's start address if the AddressRange +/// is directly contained in a FunctionInfo, or a base address of the +/// containing parent AddressRange or AddressRanges. This allows address +/// ranges to be efficiently encoded using ULEB128 encodings as we encode the +/// offset and size of each range instead of full addresses. This also makes +/// encoded addresses easy to relocate as we just need to relocate one base +/// address. +/// @{ +AddressRange decodeRange(DataExtractor &Data, uint64_t BaseAddr, + uint64_t &Offset); +void encodeRange(const AddressRange &Range, FileWriter &O, uint64_t BaseAddr); +/// @} + +/// Skip an address range object in the specified data a the specified +/// offset. +/// +/// \param Data The binary stream to read the data from. +/// +/// \param Offset The byte offset within \a Data. +void skipRange(DataExtractor &Data, uint64_t &Offset); + +/// Address ranges are decoded and encoded to be relative to a base address. +/// See the AddressRange comment for the encode and decode methods for full +/// details. +/// @{ +void decodeRanges(AddressRanges &Ranges, DataExtractor &Data, uint64_t BaseAddr, + uint64_t &Offset); +void encodeRanges(const AddressRanges &Ranges, FileWriter &O, + uint64_t BaseAddr); +/// @} + +/// Skip an address range object in the specified data a the specified +/// offset. +/// +/// \param Data The binary stream to read the data from. +/// +/// \param Offset The byte offset within \a Data. +/// +/// \returns The number of address ranges that were skipped. +uint64_t skipRanges(DataExtractor &Data, uint64_t &Offset); + +} // namespace gsym + +raw_ostream &operator<<(raw_ostream &OS, const AddressRange &R); + +raw_ostream &operator<<(raw_ostream &OS, const AddressRanges &AR); + +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_EXTRACTRANGES_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FileEntry.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FileEntry.h new file mode 100644 index 0000000000..cf1f89882d --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FileEntry.h @@ -0,0 +1,77 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- FileEntry.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_FILEENTRY_H +#define LLVM_DEBUGINFO_GSYM_FILEENTRY_H + +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/Hashing.h" +#include <functional> +#include <stdint.h> + +namespace llvm { +namespace gsym { + +/// Files in GSYM are contained in FileEntry structs where we split the +/// directory and basename into two different strings in the string +/// table. This allows paths to shared commont directory and filename +/// strings and saves space. +struct FileEntry { + + /// Offsets in the string table. + /// @{ + uint32_t Dir = 0; + uint32_t Base = 0; + /// @} + + FileEntry() = default; + FileEntry(uint32_t D, uint32_t B) : Dir(D), Base(B) {} + + // Implement operator== so that FileEntry can be used as key in + // unordered containers. + bool operator==(const FileEntry &RHS) const { + return Base == RHS.Base && Dir == RHS.Dir; + }; + bool operator!=(const FileEntry &RHS) const { + return Base != RHS.Base || Dir != RHS.Dir; + }; +}; + +} // namespace gsym + +template <> struct DenseMapInfo<gsym::FileEntry> { + static inline gsym::FileEntry getEmptyKey() { + uint32_t key = DenseMapInfo<uint32_t>::getEmptyKey(); + return gsym::FileEntry(key, key); + } + static inline gsym::FileEntry getTombstoneKey() { + uint32_t key = DenseMapInfo<uint32_t>::getTombstoneKey(); + return gsym::FileEntry(key, key); + } + static unsigned getHashValue(const gsym::FileEntry &Val) { + return llvm::hash_combine(DenseMapInfo<uint32_t>::getHashValue(Val.Dir), + DenseMapInfo<uint32_t>::getHashValue(Val.Base)); + } + static bool isEqual(const gsym::FileEntry &LHS, const gsym::FileEntry &RHS) { + return LHS == RHS; + } +}; + +} // namespace llvm +#endif // LLVM_DEBUGINFO_GSYM_FILEENTRY_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FileWriter.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FileWriter.h new file mode 100644 index 0000000000..711ba6511b --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FileWriter.h @@ -0,0 +1,135 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- FileWriter.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_FILEWRITER_H +#define LLVM_DEBUGINFO_GSYM_FILEWRITER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Endian.h" + +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +namespace llvm { +class raw_pwrite_stream; + +namespace gsym { + +/// A simplified binary data writer class that doesn't require targets, target +/// definitions, architectures, or require any other optional compile time +/// libraries to be enabled via the build process. This class needs the ability +/// to seek to different spots in the binary stream that is produces to fixup +/// offsets and sizes. +class FileWriter { + llvm::raw_pwrite_stream &OS; + llvm::support::endianness ByteOrder; +public: + FileWriter(llvm::raw_pwrite_stream &S, llvm::support::endianness B) + : OS(S), ByteOrder(B) {} + ~FileWriter(); + /// Write a single uint8_t value into the stream at the current file + /// position. + /// + /// \param Value The value to write into the stream. + void writeU8(uint8_t Value); + + /// Write a single uint16_t value into the stream at the current file + /// position. The value will be byte swapped if needed to match the byte + /// order specified during construction. + /// + /// \param Value The value to write into the stream. + void writeU16(uint16_t Value); + + /// Write a single uint32_t value into the stream at the current file + /// position. The value will be byte swapped if needed to match the byte + /// order specified during construction. + /// + /// \param Value The value to write into the stream. + void writeU32(uint32_t Value); + + /// Write a single uint64_t value into the stream at the current file + /// position. The value will be byte swapped if needed to match the byte + /// order specified during construction. + /// + /// \param Value The value to write into the stream. + void writeU64(uint64_t Value); + + /// Write the value into the stream encoded using signed LEB128 at the + /// current file position. + /// + /// \param Value The value to write into the stream. + void writeSLEB(int64_t Value); + + /// Write the value into the stream encoded using unsigned LEB128 at the + /// current file position. + /// + /// \param Value The value to write into the stream. + void writeULEB(uint64_t Value); + + /// Write an array of uint8_t values into the stream at the current file + /// position. + /// + /// \param Data An array of values to write into the stream. + void writeData(llvm::ArrayRef<uint8_t> Data); + + /// Write a NULL terminated C string into the stream at the current file + /// position. The entire contents of Str will be written into the steam at + /// the current file position and then an extra NULL termation byte will be + /// written. It is up to the user to ensure that Str doesn't contain any NULL + /// characters unless the additional NULL characters are desired. + /// + /// \param Str The value to write into the stream. + void writeNullTerminated(llvm::StringRef Str); + + /// Fixup a uint32_t value at the specified offset in the stream. This + /// function will save the current file position, seek to the specified + /// offset, overwrite the data using Value, and then restore the file + /// position to the previous file position. + /// + /// \param Value The value to write into the stream. + /// \param Offset The offset at which to write the Value within the stream. + void fixup32(uint32_t Value, uint64_t Offset); + + /// Pad with zeroes at the current file position until the current file + /// position matches the specified alignment. + /// + /// \param Align An integer speciying the desired alignment. This does not + /// need to be a power of two. + void alignTo(size_t Align); + + /// Return the current offset within the file. + /// + /// \return The unsigned offset from the start of the file of the current + /// file position. + uint64_t tell(); + + llvm::raw_pwrite_stream &get_stream() { + return OS; + } + +private: + FileWriter(const FileWriter &rhs) = delete; + void operator=(const FileWriter &rhs) = delete; +}; + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_FILEWRITER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FunctionInfo.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FunctionInfo.h new file mode 100644 index 0000000000..b24b096994 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/FunctionInfo.h @@ -0,0 +1,222 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- 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/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/StringTable.h" +#include <cstdint> +#include <tuple> + +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 { + AddressRange Range; + uint32_t Name; ///< String table offset in the string table. + std::optional<LineTable> OptLineTable; + std::optional<InlineInfo> Inline; + + FunctionInfo(uint64_t Addr = 0, uint64_t Size = 0, uint32_t N = 0) + : Range(Addr, Addr + Size), Name(N) {} + + /// Query if a FunctionInfo has rich debug info. + /// + /// \returns A bool that indicates if this object has something else than + /// range and name. When converting information from a symbol table and from + /// debug info, we might end up with multiple FunctionInfo objects for the + /// same range and we need to be able to tell which one is the better object + /// to use. + bool hasRichInfo() const { return OptLineTable || Inline; } + + /// Query if a FunctionInfo object is valid. + /// + /// Address and size can be zero and there can be no line entries for a + /// symbol so the only indication this entry is valid is if the name is + /// not zero. This can happen when extracting information from symbol + /// tables that do not encode symbol sizes. In that case only the + /// address and name will be filled in. + /// + /// \returns A boolean indicating if this FunctionInfo is valid. + bool isValid() const { + return Name != 0; + } + + /// Decode an object from a binary data stream. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \param BaseAddr The FunctionInfo's start address and will be used as the + /// base address when decoding any contained information like the line table + /// and the inline info. + /// + /// \returns An FunctionInfo or an error describing the issue that was + /// encountered during decoding. + static llvm::Expected<FunctionInfo> decode(DataExtractor &Data, + uint64_t BaseAddr); + + /// Encode this object into FileWriter stream. + /// + /// \param O The binary stream to write the data to at the current file + /// position. + /// + /// \returns An error object that indicates failure or the offset of the + /// function info that was successfully written into the stream. + llvm::Expected<uint64_t> encode(FileWriter &O) const; + + + /// Lookup an address within a FunctionInfo object's data stream. + /// + /// Instead of decoding an entire FunctionInfo object when doing lookups, + /// we can decode only the information we need from the FunctionInfo's data + /// for the specific address. The lookup result information is returned as + /// a LookupResult. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \param GR The GSYM reader that contains the string and file table that + /// will be used to fill in information in the returned result. + /// + /// \param FuncAddr The function start address decoded from the GsymReader. + /// + /// \param Addr The address to lookup. + /// + /// \returns An LookupResult or an error describing the issue that was + /// encountered during decoding. An error should only be returned if the + /// address is not contained in the FunctionInfo or if the data is corrupted. + static llvm::Expected<LookupResult> lookup(DataExtractor &Data, + const GsymReader &GR, + uint64_t FuncAddr, + uint64_t Addr); + + uint64_t startAddress() const { return Range.start(); } + uint64_t endAddress() const { return Range.end(); } + uint64_t size() const { return Range.size(); } + + void clear() { + Range = {0, 0}; + Name = 0; + OptLineTable = std::nullopt; + Inline = std::nullopt; + } +}; + +inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) { + return LHS.Range == RHS.Range && LHS.Name == RHS.Name && + LHS.OptLineTable == RHS.OptLineTable && LHS.Inline == RHS.Inline; +} +inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { + return !(LHS == RHS); +} +/// This sorting will order things consistently by address range first, but then +/// followed by inlining being valid 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. +inline bool operator<(const FunctionInfo &LHS, const FunctionInfo &RHS) { + // First sort by address range + if (LHS.Range != RHS.Range) + return LHS.Range < RHS.Range; + + // Then sort by inline + if (LHS.Inline.has_value() != RHS.Inline.has_value()) + return RHS.Inline.has_value(); + + return LHS.OptLineTable < RHS.OptLineTable; +} + +raw_ostream &operator<<(raw_ostream &OS, const FunctionInfo &R); + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/GsymCreator.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/GsymCreator.h new file mode 100644 index 0000000000..ef1c70cb2a --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/GsymCreator.h @@ -0,0 +1,310 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- GsymCreator.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_GSYMCREATOR_H +#define LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H + +#include <functional> +#include <memory> +#include <mutex> +#include <thread> + +#include "llvm/ADT/AddressRanges.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/DebugInfo/GSYM/FileEntry.h" +#include "llvm/DebugInfo/GSYM/FunctionInfo.h" +#include "llvm/MC/StringTableBuilder.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Path.h" + +namespace llvm { + +namespace gsym { +class FileWriter; + +/// GsymCreator is used to emit GSYM data to a stand alone file or section +/// within a file. +/// +/// The GsymCreator is designed to be used in 3 stages: +/// - Create FunctionInfo objects and add them +/// - Finalize the GsymCreator object +/// - Save to file or section +/// +/// The first stage involves creating FunctionInfo objects from another source +/// of information like compiler debug info metadata, DWARF or Breakpad files. +/// Any strings in the FunctionInfo or contained information, like InlineInfo +/// or LineTable objects, should get the string table offsets by calling +/// GsymCreator::insertString(...). Any file indexes that are needed should be +/// obtained by calling GsymCreator::insertFile(...). All of the function calls +/// in GsymCreator are thread safe. This allows multiple threads to create and +/// add FunctionInfo objects while parsing debug information. +/// +/// Once all of the FunctionInfo objects have been added, the +/// GsymCreator::finalize(...) must be called prior to saving. This function +/// will sort the FunctionInfo objects, finalize the string table, and do any +/// other passes on the information needed to prepare the information to be +/// saved. +/// +/// Once the object has been finalized, it can be saved to a file or section. +/// +/// ENCODING +/// +/// GSYM files are designed to be memory mapped into a process as shared, read +/// only data, and used as is. +/// +/// The GSYM file format when in a stand alone file consists of: +/// - Header +/// - Address Table +/// - Function Info Offsets +/// - File Table +/// - String Table +/// - Function Info Data +/// +/// HEADER +/// +/// The header is fully described in "llvm/DebugInfo/GSYM/Header.h". +/// +/// ADDRESS TABLE +/// +/// The address table immediately follows the header in the file and consists +/// of Header.NumAddresses address offsets. These offsets are sorted and can be +/// binary searched for efficient lookups. Addresses in the address table are +/// stored as offsets from a 64 bit base address found in Header.BaseAddress. +/// This allows the address table to contain 8, 16, or 32 offsets. This allows +/// the address table to not require full 64 bit addresses for each address. +/// The resulting GSYM size is smaller and causes fewer pages to be touched +/// during address lookups when the address table is smaller. The size of the +/// address offsets in the address table is specified in the header in +/// Header.AddrOffSize. The first offset in the address table is aligned to +/// Header.AddrOffSize alignment to ensure efficient access when loaded into +/// memory. +/// +/// FUNCTION INFO OFFSETS TABLE +/// +/// The function info offsets table immediately follows the address table and +/// consists of Header.NumAddresses 32 bit file offsets: one for each address +/// in the address table. This data is aligned to a 4 byte boundary. The +/// offsets in this table are the relative offsets from the start offset of the +/// GSYM header and point to the function info data for each address in the +/// address table. Keeping this data separate from the address table helps to +/// reduce the number of pages that are touched when address lookups occur on a +/// GSYM file. +/// +/// FILE TABLE +/// +/// The file table immediately follows the function info offsets table. The +/// encoding of the FileTable is: +/// +/// struct FileTable { +/// uint32_t Count; +/// FileEntry Files[]; +/// }; +/// +/// The file table starts with a 32 bit count of the number of files that are +/// used in all of the function info, followed by that number of FileEntry +/// structures. The file table is aligned to a 4 byte boundary, Each file in +/// the file table is represented with a FileEntry structure. +/// See "llvm/DebugInfo/GSYM/FileEntry.h" for details. +/// +/// STRING TABLE +/// +/// The string table follows the file table in stand alone GSYM files and +/// contains all strings for everything contained in the GSYM file. Any string +/// data should be added to the string table and any references to strings +/// inside GSYM information must be stored as 32 bit string table offsets into +/// this string table. The string table always starts with an empty string at +/// offset zero and is followed by any strings needed by the GSYM information. +/// The start of the string table is not aligned to any boundary. +/// +/// FUNCTION INFO DATA +/// +/// The function info data is the payload that contains information about the +/// address that is being looked up. It contains all of the encoded +/// FunctionInfo objects. Each encoded FunctionInfo's data is pointed to by an +/// entry in the Function Info Offsets Table. For details on the exact encoding +/// of FunctionInfo objects, see "llvm/DebugInfo/GSYM/FunctionInfo.h". +class GsymCreator { + // Private member variables require Mutex protections + mutable std::mutex Mutex; + std::vector<FunctionInfo> Funcs; + StringTableBuilder StrTab; + StringSet<> StringStorage; + DenseMap<llvm::gsym::FileEntry, uint32_t> FileEntryToIndex; + std::vector<llvm::gsym::FileEntry> Files; + std::vector<uint8_t> UUID; + std::optional<AddressRanges> ValidTextRanges; + AddressRanges Ranges; + std::optional<uint64_t> BaseAddress; + bool Finalized = false; + bool Quiet; + +public: + GsymCreator(bool Quiet = false); + + /// Save a GSYM file to a stand alone file. + /// + /// \param Path The file path to save the GSYM file to. + /// \param ByteOrder The endianness to use when saving the file. + /// \returns An error object that indicates success or failure of the save. + llvm::Error save(StringRef Path, llvm::support::endianness ByteOrder) const; + + /// Encode a GSYM into the file writer stream at the current position. + /// + /// \param O The stream to save the binary data to + /// \returns An error object that indicates success or failure of the save. + llvm::Error encode(FileWriter &O) const; + + /// Insert a string into the GSYM string table. + /// + /// All strings used by GSYM files must be uniqued by adding them to this + /// string pool and using the returned offset for any string values. + /// + /// \param S The string to insert into the string table. + /// \param Copy If true, then make a backing copy of the string. If false, + /// the string is owned by another object that will stay around + /// long enough for the GsymCreator to save the GSYM file. + /// \returns The unique 32 bit offset into the string table. + uint32_t insertString(StringRef S, bool Copy = true); + + /// Insert a file into this GSYM creator. + /// + /// Inserts a file by adding a FileEntry into the "Files" member variable if + /// the file has not already been added. The file path is split into + /// directory and filename which are both added to the string table. This + /// allows paths to be stored efficiently by reusing the directories that are + /// common between multiple files. + /// + /// \param Path The path to the file to insert. + /// \param Style The path style for the "Path" parameter. + /// \returns The unique file index for the inserted file. + uint32_t insertFile(StringRef Path, + sys::path::Style Style = sys::path::Style::native); + + /// Add a function info to this GSYM creator. + /// + /// All information in the FunctionInfo object must use the + /// GsymCreator::insertString(...) function when creating string table + /// offsets for names and other strings. + /// + /// \param FI The function info object to emplace into our functions list. + void addFunctionInfo(FunctionInfo &&FI); + + /// Finalize the data in the GSYM creator prior to saving the data out. + /// + /// Finalize must be called after all FunctionInfo objects have been added + /// and before GsymCreator::save() is called. + /// + /// \param OS Output stream to report duplicate function infos, overlapping + /// function infos, and function infos that were merged or removed. + /// \returns An error object that indicates success or failure of the + /// finalize. + llvm::Error finalize(llvm::raw_ostream &OS); + + /// Set the UUID value. + /// + /// \param UUIDBytes The new UUID bytes. + void setUUID(llvm::ArrayRef<uint8_t> UUIDBytes) { + UUID.assign(UUIDBytes.begin(), UUIDBytes.end()); + } + + /// Thread safe iteration over all function infos. + /// + /// \param Callback A callback function that will get called with each + /// FunctionInfo. If the callback returns false, stop iterating. + void forEachFunctionInfo( + std::function<bool(FunctionInfo &)> const &Callback); + + /// Thread safe const iteration over all function infos. + /// + /// \param Callback A callback function that will get called with each + /// FunctionInfo. If the callback returns false, stop iterating. + void forEachFunctionInfo( + std::function<bool(const FunctionInfo &)> const &Callback) const; + + /// Get the current number of FunctionInfo objects contained in this + /// object. + size_t getNumFunctionInfos() const; + + /// Check if an address has already been added as a function info. + /// + /// FunctionInfo data can come from many sources: debug info, symbol tables, + /// exception information, and more. Symbol tables should be added after + /// debug info and can use this function to see if a symbol's start address + /// has already been added to the GsymReader. Calling this before adding + /// a function info from a source other than debug info avoids clients adding + /// many redundant FunctionInfo objects from many sources only for them to be + /// removed during the finalize() call. + bool hasFunctionInfoForAddress(uint64_t Addr) const; + + /// Set valid .text address ranges that all functions must be contained in. + void SetValidTextRanges(AddressRanges &TextRanges) { + ValidTextRanges = TextRanges; + } + + /// Get the valid text ranges. + const std::optional<AddressRanges> GetValidTextRanges() const { + return ValidTextRanges; + } + + /// Check if an address is a valid code address. + /// + /// Any functions whose addresses do not exist within these function bounds + /// will not be converted into the final GSYM. This allows the object file + /// to figure out the valid file address ranges of all the code sections + /// and ensure we don't add invalid functions to the final output. Many + /// linkers have issues when dead stripping functions from DWARF debug info + /// where they set the DW_AT_low_pc to zero, but newer DWARF has the + /// DW_AT_high_pc as an offset from the DW_AT_low_pc and these size + /// attributes have no relocations that can be applied. This results in DWARF + /// where many functions have an DW_AT_low_pc of zero and a valid offset size + /// for DW_AT_high_pc. If we extract all valid ranges from an object file + /// that are marked with executable permissions, we can properly ensure that + /// these functions are removed. + /// + /// \param Addr An address to check. + /// + /// \returns True if the address is in the valid text ranges or if no valid + /// text ranges have been set, false otherwise. + bool IsValidTextAddress(uint64_t Addr) const; + + /// Set the base address to use for the GSYM file. + /// + /// Setting the base address to use for the GSYM file. Object files typically + /// get loaded from a base address when the OS loads them into memory. Using + /// GSYM files for symbolication becomes easier if the base address in the + /// GSYM header is the same address as it allows addresses to be easily slid + /// and allows symbolication without needing to find the original base + /// address in the original object file. + /// + /// \param Addr The address to use as the base address of the GSYM file + /// when it is saved to disk. + void setBaseAddress(uint64_t Addr) { + BaseAddress = Addr; + } + + /// Whether the transformation should be quiet, i.e. not output warnings. + bool isQuiet() const { return Quiet; } +}; + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/GsymReader.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/GsymReader.h new file mode 100644 index 0000000000..4ecfbc0da0 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/GsymReader.h @@ -0,0 +1,322 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- GsymReader.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_GSYMREADER_H +#define LLVM_DEBUGINFO_GSYM_GSYMREADER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/GSYM/FileEntry.h" +#include "llvm/DebugInfo/GSYM/FunctionInfo.h" +#include "llvm/DebugInfo/GSYM/Header.h" +#include "llvm/DebugInfo/GSYM/LineEntry.h" +#include "llvm/DebugInfo/GSYM/StringTable.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/ErrorOr.h" +#include <inttypes.h> +#include <memory> +#include <stdint.h> +#include <vector> + +namespace llvm { +class MemoryBuffer; +class raw_ostream; + +namespace gsym { + +/// GsymReader is used to read GSYM data from a file or buffer. +/// +/// This class is optimized for very quick lookups when the endianness matches +/// the host system. The Header, address table, address info offsets, and file +/// table is designed to be mmap'ed as read only into memory and used without +/// any parsing needed. If the endianness doesn't match, we swap these objects +/// and tables into GsymReader::SwappedData and then point our header and +/// ArrayRefs to this swapped internal data. +/// +/// GsymReader objects must use one of the static functions to create an +/// instance: GsymReader::openFile(...) and GsymReader::copyBuffer(...). + +class GsymReader { + GsymReader(std::unique_ptr<MemoryBuffer> Buffer); + llvm::Error parse(); + + std::unique_ptr<MemoryBuffer> MemBuffer; + StringRef GsymBytes; + llvm::support::endianness Endian; + const Header *Hdr = nullptr; + ArrayRef<uint8_t> AddrOffsets; + ArrayRef<uint32_t> AddrInfoOffsets; + ArrayRef<FileEntry> Files; + StringTable StrTab; + /// When the GSYM file's endianness doesn't match the host system then + /// we must decode all data structures that need to be swapped into + /// local storage and set point the ArrayRef objects above to these swapped + /// copies. + struct SwappedData { + Header Hdr; + std::vector<uint8_t> AddrOffsets; + std::vector<uint32_t> AddrInfoOffsets; + std::vector<FileEntry> Files; + }; + std::unique_ptr<SwappedData> Swap; + +public: + GsymReader(GsymReader &&RHS); + ~GsymReader(); + + /// Construct a GsymReader from a file on disk. + /// + /// \param Path The file path the GSYM file to read. + /// \returns An expected GsymReader that contains the object or an error + /// object that indicates reason for failing to read the GSYM. + static llvm::Expected<GsymReader> openFile(StringRef Path); + + /// Construct a GsymReader from a buffer. + /// + /// \param Bytes A set of bytes that will be copied and owned by the + /// returned object on success. + /// \returns An expected GsymReader that contains the object or an error + /// object that indicates reason for failing to read the GSYM. + static llvm::Expected<GsymReader> copyBuffer(StringRef Bytes); + + /// Access the GSYM header. + /// \returns A native endian version of the GSYM header. + const Header &getHeader() const; + + /// Get the full function info for an address. + /// + /// This should be called when a client will store a copy of the complete + /// FunctionInfo for a given address. For one off lookups, use the lookup() + /// function below. + /// + /// Symbolication server processes might want to parse the entire function + /// info for a given address and cache it if the process stays around to + /// service many symbolication addresses, like for parsing profiling + /// information. + /// + /// \param Addr A virtual address from the orignal object file to lookup. + /// + /// \returns An expected FunctionInfo that contains the function info object + /// or an error object that indicates reason for failing to lookup the + /// address. + llvm::Expected<FunctionInfo> getFunctionInfo(uint64_t Addr) const; + + /// Lookup an address in the a GSYM. + /// + /// Lookup just the information needed for a specific address \a Addr. This + /// function is faster that calling getFunctionInfo() as it will only return + /// information that pertains to \a Addr and allows the parsing to skip any + /// extra information encoded for other addresses. For example the line table + /// parsing can stop when a matching LineEntry has been fouhnd, and the + /// InlineInfo can stop parsing early once a match has been found and also + /// skip information that doesn't match. This avoids memory allocations and + /// is much faster for lookups. + /// + /// \param Addr A virtual address from the orignal object file to lookup. + /// \returns An expected LookupResult that contains only the information + /// needed for the current address, or an error object that indicates reason + /// for failing to lookup the address. + llvm::Expected<LookupResult> lookup(uint64_t Addr) const; + + /// Get a string from the string table. + /// + /// \param Offset The string table offset for the string to retrieve. + /// \returns The string from the strin table. + StringRef getString(uint32_t Offset) const { return StrTab[Offset]; } + + /// Get the a file entry for the suppplied file index. + /// + /// Used to convert any file indexes in the FunctionInfo data back into + /// files. This function can be used for iteration, but is more commonly used + /// for random access when doing lookups. + /// + /// \param Index An index into the file table. + /// \returns An optional FileInfo that will be valid if the file index is + /// valid, or std::nullopt if the file index is out of bounds, + std::optional<FileEntry> getFile(uint32_t Index) const { + if (Index < Files.size()) + return Files[Index]; + return std::nullopt; + } + + /// Dump the entire Gsym data contained in this object. + /// + /// \param OS The output stream to dump to. + void dump(raw_ostream &OS); + + /// Dump a FunctionInfo object. + /// + /// This function will convert any string table indexes and file indexes + /// into human readable format. + /// + /// \param OS The output stream to dump to. + /// + /// \param FI The object to dump. + void dump(raw_ostream &OS, const FunctionInfo &FI); + + /// Dump a LineTable object. + /// + /// This function will convert any string table indexes and file indexes + /// into human readable format. + /// + /// + /// \param OS The output stream to dump to. + /// + /// \param LT The object to dump. + void dump(raw_ostream &OS, const LineTable <); + + /// Dump a InlineInfo object. + /// + /// This function will convert any string table indexes and file indexes + /// into human readable format. + /// + /// \param OS The output stream to dump to. + /// + /// \param II The object to dump. + /// + /// \param Indent The indentation as number of spaces. Used for recurive + /// dumping. + void dump(raw_ostream &OS, const InlineInfo &II, uint32_t Indent = 0); + + /// Dump a FileEntry object. + /// + /// This function will convert any string table indexes into human readable + /// format. + /// + /// \param OS The output stream to dump to. + /// + /// \param FE The object to dump. + void dump(raw_ostream &OS, std::optional<FileEntry> FE); + + /// Get the number of addresses in this Gsym file. + uint32_t getNumAddresses() const { + return Hdr->NumAddresses; + } + + /// Gets an address from the address table. + /// + /// Addresses are stored as offsets frrom the gsym::Header::BaseAddress. + /// + /// \param Index A index into the address table. + /// \returns A resolved virtual address for adddress in the address table + /// or std::nullopt if Index is out of bounds. + std::optional<uint64_t> getAddress(size_t Index) const; + +protected: + + /// Get an appropriate address info offsets array. + /// + /// The address table in the GSYM file is stored as array of 1, 2, 4 or 8 + /// byte offsets from the The gsym::Header::BaseAddress. The table is stored + /// internally as a array of bytes that are in the correct endianness. When + /// we access this table we must get an array that matches those sizes. This + /// templatized helper function is used when accessing address offsets in the + /// AddrOffsets member variable. + /// + /// \returns An ArrayRef of an appropriate address offset size. + template <class T> ArrayRef<T> + getAddrOffsets() const { + return ArrayRef<T>(reinterpret_cast<const T *>(AddrOffsets.data()), + AddrOffsets.size()/sizeof(T)); + } + + /// Get an appropriate address from the address table. + /// + /// The address table in the GSYM file is stored as array of 1, 2, 4 or 8 + /// byte address offsets from the The gsym::Header::BaseAddress. The table is + /// stored internally as a array of bytes that are in the correct endianness. + /// In order to extract an address from the address table we must access the + /// address offset using the correct size and then add it to the BaseAddress + /// in the header. + /// + /// \param Index An index into the AddrOffsets array. + /// \returns An virtual address that matches the original object file for the + /// address as the specified index, or std::nullopt if Index is out of bounds. + template <class T> + std::optional<uint64_t> addressForIndex(size_t Index) const { + ArrayRef<T> AIO = getAddrOffsets<T>(); + if (Index < AIO.size()) + return AIO[Index] + Hdr->BaseAddress; + return std::nullopt; + } + /// Lookup an address offset in the AddrOffsets table. + /// + /// Given an address offset, look it up using a binary search of the + /// AddrOffsets table. + /// + /// \param AddrOffset An address offset, that has already been computed by + /// subtracting the gsym::Header::BaseAddress. + /// \returns The matching address offset index. This index will be used to + /// extract the FunctionInfo data's offset from the AddrInfoOffsets array. + template <class T> + std::optional<uint64_t> + getAddressOffsetIndex(const uint64_t AddrOffset) const { + ArrayRef<T> AIO = getAddrOffsets<T>(); + const auto Begin = AIO.begin(); + const auto End = AIO.end(); + auto Iter = std::lower_bound(Begin, End, AddrOffset); + // Watch for addresses that fall between the gsym::Header::BaseAddress and + // the first address offset. + if (Iter == Begin && AddrOffset < *Begin) + return std::nullopt; + if (Iter == End || AddrOffset < *Iter) + --Iter; + return std::distance(Begin, Iter); + } + + /// Create a GSYM from a memory buffer. + /// + /// Called by both openFile() and copyBuffer(), this function does all of the + /// work of parsing the GSYM file and returning an error. + /// + /// \param MemBuffer A memory buffer that will transfer ownership into the + /// GsymReader. + /// \returns An expected GsymReader that contains the object or an error + /// object that indicates reason for failing to read the GSYM. + static llvm::Expected<llvm::gsym::GsymReader> + create(std::unique_ptr<MemoryBuffer> &MemBuffer); + + + /// Given an address, find the address index. + /// + /// Binary search the address table and find the matching address index. + /// + /// \param Addr A virtual address that matches the original object file + /// to lookup. + /// \returns An index into the address table. This index can be used to + /// extract the FunctionInfo data's offset from the AddrInfoOffsets array. + /// Returns an error if the address isn't in the GSYM with details of why. + Expected<uint64_t> getAddressIndex(const uint64_t Addr) const; + + /// Given an address index, get the offset for the FunctionInfo. + /// + /// Looking up an address is done by finding the corresponding address + /// index for the address. This index is then used to get the offset of the + /// FunctionInfo data that we will decode using this function. + /// + /// \param Index An index into the address table. + /// \returns An optional GSYM data offset for the offset of the FunctionInfo + /// that needs to be decoded. + std::optional<uint64_t> getAddressInfoOffset(size_t Index) const; +}; + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_GSYMREADER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/Header.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/Header.h new file mode 100644 index 0000000000..4a809bde2b --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/Header.h @@ -0,0 +1,140 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- Header.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_HEADER_H +#define LLVM_DEBUGINFO_GSYM_HEADER_H + +#include "llvm/Support/Error.h" + +#include <cstddef> +#include <cstdint> + +namespace llvm { +class raw_ostream; +class DataExtractor; + +namespace gsym { +class FileWriter; + +constexpr uint32_t GSYM_MAGIC = 0x4753594d; // 'GSYM' +constexpr uint32_t GSYM_CIGAM = 0x4d595347; // 'MYSG' +constexpr uint32_t GSYM_VERSION = 1; +constexpr size_t GSYM_MAX_UUID_SIZE = 20; + +/// The GSYM header. +/// +/// The GSYM header is found at the start of a stand alone GSYM file, or as +/// the first bytes in a section when GSYM is contained in a section of an +/// executable file (ELF, mach-o, COFF). +/// +/// The structure is encoded exactly as it appears in the structure definition +/// with no gaps between members. Alignment should not change from system to +/// system as the members were laid out so that they shouldn't align +/// differently on different architectures. +/// +/// When endianness of the system loading a GSYM file matches, the file can +/// be mmap'ed in and a pointer to the header can be cast to the first bytes +/// of the file (stand alone GSYM file) or section data (GSYM in a section). +/// When endianness is swapped, the Header::decode() function should be used to +/// decode the header. +struct Header { + /// The magic bytes should be set to GSYM_MAGIC. This helps detect if a file + /// is a GSYM file by scanning the first 4 bytes of a file or section. + /// This value might appear byte swapped + uint32_t Magic; + /// The version can number determines how the header is decoded and how each + /// InfoType in FunctionInfo is encoded/decoded. As version numbers increase, + /// "Magic" and "Version" members should always appear at offset zero and 4 + /// respectively to ensure clients figure out if they can parse the format. + uint16_t Version; + /// The size in bytes of each address offset in the address offsets table. + uint8_t AddrOffSize; + /// The size in bytes of the UUID encoded in the "UUID" member. + uint8_t UUIDSize; + /// The 64 bit base address that all address offsets in the address offsets + /// table are relative to. Storing a full 64 bit address allows our address + /// offsets table to be smaller on disk. + uint64_t BaseAddress; + /// The number of addresses stored in the address offsets table. + uint32_t NumAddresses; + /// The file relative offset of the start of the string table for strings + /// contained in the GSYM file. If the GSYM in contained in a stand alone + /// file this will be the file offset of the start of the string table. If + /// the GSYM is contained in a section within an executable file, this can + /// be the offset of the first string used in the GSYM file and can possibly + /// span one or more executable string tables. This allows the strings to + /// share string tables in an ELF or mach-o file. + uint32_t StrtabOffset; + /// The size in bytes of the string table. For a stand alone GSYM file, this + /// will be the exact size in bytes of the string table. When the GSYM data + /// is in a section within an executable file, this size can span one or more + /// sections that contains strings. This allows any strings that are already + /// stored in the executable file to be re-used, and any extra strings could + /// be added to another string table and the string table offset and size + /// can be set to span all needed string tables. + uint32_t StrtabSize; + /// The UUID of the original executable file. This is stored to allow + /// matching a GSYM file to an executable file when symbolication is + /// required. Only the first "UUIDSize" bytes of the UUID are valid. Any + /// bytes in the UUID value that appear after the first UUIDSize bytes should + /// be set to zero. + uint8_t UUID[GSYM_MAX_UUID_SIZE]; + + /// Check if a header is valid and return an error if anything is wrong. + /// + /// This function can be used prior to encoding a header to ensure it is + /// valid, or after decoding a header to ensure it is valid and supported. + /// + /// Check a correctly byte swapped header for errors: + /// - check magic value + /// - check that version number is supported + /// - check that the address offset size is supported + /// - check that the UUID size is valid + /// + /// \returns An error if anything is wrong in the header, or Error::success() + /// if there are no errors. + llvm::Error checkForError() const; + + /// Decode an object from a binary data stream. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \returns A Header or an error describing the issue that was + /// encountered during decoding. + static llvm::Expected<Header> decode(DataExtractor &Data); + + /// Encode this object into FileWriter stream. + /// + /// \param O The binary stream to write the data to at the current file + /// position. + /// + /// \returns An error object that indicates success or failure of the + /// encoding process. + llvm::Error encode(FileWriter &O) const; +}; + +bool operator==(const Header &LHS, const Header &RHS); +raw_ostream &operator<<(raw_ostream &OS, const llvm::gsym::Header &H); + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_HEADER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/InlineInfo.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/InlineInfo.h new file mode 100644 index 0000000000..bfa4d581c1 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/InlineInfo.h @@ -0,0 +1,191 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- InlineInfo.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_INLINEINFO_H +#define LLVM_DEBUGINFO_GSYM_INLINEINFO_H + +#include "llvm/DebugInfo/GSYM/ExtractRanges.h" +#include "llvm/DebugInfo/GSYM/LineEntry.h" +#include "llvm/DebugInfo/GSYM/LookupResult.h" +#include "llvm/Support/Error.h" +#include <stdint.h> +#include <vector> + +namespace llvm { +class raw_ostream; + +namespace gsym { + +class GsymReader; +/// Inline information stores the name of the inline function along with +/// an array of address ranges. It also stores the call file and call line +/// that called this inline function. This allows us to unwind inline call +/// stacks back to the inline or concrete function that called this +/// function. Inlined functions contained in this function are stored in the +/// "Children" variable. All address ranges must be sorted and all address +/// ranges of all children must be contained in the ranges of this function. +/// Any clients that encode information will need to ensure the ranges are +/// all contined correctly or lookups could fail. Add ranges in these objects +/// must be contained in the top level FunctionInfo address ranges as well. +/// +/// ENCODING +/// +/// When saved to disk, the inline info encodes all ranges to be relative to +/// a parent address range. This will be the FunctionInfo's start address if +/// the InlineInfo is directly contained in a FunctionInfo, or a the start +/// address of the containing parent InlineInfo's first "Ranges" member. This +/// allows address ranges to be efficiently encoded using ULEB128 encodings as +/// we encode the offset and size of each range instead of full addresses. This +/// also makes any encoded addresses easy to relocate as we just need to +/// relocate the FunctionInfo's start address. +/// +/// - The AddressRanges member "Ranges" is encoded using an appropriate base +/// address as described above. +/// - UINT8 boolean value that specifies if the InlineInfo object has children. +/// - UINT32 string table offset that points to the name of the inline +/// function. +/// - ULEB128 integer that specifies the file of the call site that called +/// this function. +/// - ULEB128 integer that specifies the source line of the call site that +/// called this function. +/// - if this object has children, enocode each child InlineInfo using the +/// the first address range's start address as the base address. +/// +struct InlineInfo { + + uint32_t Name; ///< String table offset in the string table. + uint32_t CallFile; ///< 1 based file index in the file table. + uint32_t CallLine; ///< Source line number. + AddressRanges Ranges; + std::vector<InlineInfo> Children; + InlineInfo() : Name(0), CallFile(0), CallLine(0) {} + void clear() { + Name = 0; + CallFile = 0; + CallLine = 0; + Ranges.clear(); + Children.clear(); + } + bool isValid() const { return !Ranges.empty(); } + + using InlineArray = std::vector<const InlineInfo *>; + + /// Lookup a single address within the inline info data. + /// + /// Clients have the option to decode an entire InlineInfo object (using + /// InlineInfo::decode() ) or just find the matching inline info using this + /// function. The benefit of using this function is that only the information + /// needed for the lookup will be extracted, other info can be skipped and + /// parsing can stop as soon as the deepest match is found. This allows + /// symbolication tools to be fast and efficient and avoid allocation costs + /// when doing lookups. + /// + /// This function will augment the SourceLocations array \a SrcLocs with any + /// inline information that pertains to \a Addr. If no inline information + /// exists for \a Addr, then \a SrcLocs will be left untouched. If there is + /// inline information for \a Addr, then \a SrcLocs will be modifiied to + /// contain the deepest most inline function's SourceLocation at index zero + /// in the array and proceed up the the concrete function source file and + /// line at the end of the array. + /// + /// \param GR The GSYM reader that contains the string and file table that + /// will be used to fill in the source locations. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the LineTable object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \param BaseAddr The base address to use when decoding the line table. + /// This will be the FunctionInfo's start address and will be used to + /// decode the correct addresses for the inline information. + /// + /// \param Addr The address to lookup. + /// + /// \param SrcLocs The inline source locations that matches \a Addr. This + /// array must be initialized with the matching line entry + /// from the line table upon entry. The name of the concrete + /// function must be supplied since it will get pushed to + /// the last SourceLocation entry and the inline information + /// will fill in the source file and line from the inline + /// information. + /// + /// \returns An error if the inline information is corrupt, or + /// Error::success() for all other cases, even when no information + /// is added to \a SrcLocs. + static llvm::Error lookup(const GsymReader &GR, DataExtractor &Data, + uint64_t BaseAddr, uint64_t Addr, + SourceLocations &SrcLocs); + + /// Lookup an address in the InlineInfo object + /// + /// This function is used to symbolicate an inline call stack and can + /// turn one address in the program into one or more inline call stacks + /// and have the stack trace show the original call site from + /// non-inlined code. + /// + /// \param Addr the address to lookup + /// + /// \returns optional vector of InlineInfo objects that describe the + /// inline call stack for a given address, false otherwise. + std::optional<InlineArray> getInlineStack(uint64_t Addr) const; + + /// Decode an InlineInfo object from a binary data stream. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the InlineInfo object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \param BaseAddr The base address to use when decoding all address ranges. + /// This will be the FunctionInfo's start address if this object is directly + /// contained in a FunctionInfo object, or the start address of the first + /// address range in an InlineInfo object of this object is a child of + /// another InlineInfo object. + /// \returns An InlineInfo or an error describing the issue that was + /// encountered during decoding. + static llvm::Expected<InlineInfo> decode(DataExtractor &Data, + uint64_t BaseAddr); + + /// Encode this InlineInfo object into FileWriter stream. + /// + /// \param O The binary stream to write the data to at the current file + /// position. + /// + /// \param BaseAddr The base address to use when encoding all address ranges. + /// This will be the FunctionInfo's start address if this object is directly + /// contained in a FunctionInfo object, or the start address of the first + /// address range in an InlineInfo object of this object is a child of + /// another InlineInfo object. + /// + /// \returns An error object that indicates success or failure or the + /// encoding process. + llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const; +}; + +inline bool operator==(const InlineInfo &LHS, const InlineInfo &RHS) { + return LHS.Name == RHS.Name && LHS.CallFile == RHS.CallFile && + LHS.CallLine == RHS.CallLine && LHS.Ranges == RHS.Ranges && + LHS.Children == RHS.Children; +} + +raw_ostream &operator<<(raw_ostream &OS, const InlineInfo &FI); + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_INLINEINFO_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LineEntry.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LineEntry.h new file mode 100644 index 0000000000..d759d8e144 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LineEntry.h @@ -0,0 +1,58 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- LineEntry.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_LINEENTRY_H +#define LLVM_DEBUGINFO_GSYM_LINEENTRY_H + +#include "llvm/DebugInfo/GSYM/ExtractRanges.h" + +namespace llvm { +namespace gsym { + +/// Line entries are used to encode the line tables in FunctionInfo objects. +/// They are stored as a sorted vector of these objects and store the +/// address, file and line of the line table row for a given address. The +/// size of a line table entry is calculated by looking at the next entry +/// in the FunctionInfo's vector of entries. +struct LineEntry { + uint64_t Addr; ///< Start address of this line entry. + uint32_t File; ///< 1 based index of file in FileTable + uint32_t Line; ///< Source line number. + LineEntry(uint64_t A = 0, uint32_t F = 0, uint32_t L = 0) + : Addr(A), File(F), Line(L) {} + bool isValid() { return File != 0; } +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const LineEntry &LE) { + return OS << "addr=" << HEX64(LE.Addr) << ", file=" << format("%3u", LE.File) + << ", line=" << format("%3u", LE.Line); +} + +inline bool operator==(const LineEntry &LHS, const LineEntry &RHS) { + return LHS.Addr == RHS.Addr && LHS.File == RHS.File && LHS.Line == RHS.Line; +} +inline bool operator!=(const LineEntry &LHS, const LineEntry &RHS) { + return !(LHS == RHS); +} +inline bool operator<(const LineEntry &LHS, const LineEntry &RHS) { + return LHS.Addr < RHS.Addr; +} +} // namespace gsym +} // namespace llvm +#endif // LLVM_DEBUGINFO_GSYM_LINEENTRY_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LineTable.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LineTable.h new file mode 100644 index 0000000000..e439c56c94 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LineTable.h @@ -0,0 +1,244 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- LineTable.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_LINETABLE_H +#define LLVM_DEBUGINFO_GSYM_LINETABLE_H + +#include "llvm/DebugInfo/GSYM/LineEntry.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> + +namespace llvm { +namespace gsym { + +struct FunctionInfo; +class FileWriter; + +/// LineTable class contains deserialized versions of line tables for each +/// function's address ranges. +/// +/// When saved to disk, the line table is encoded using a modified version of +/// the DWARF line tables that only tracks address to source file and line. +/// +/// ENCODING +/// +/// The line table starts with a small prolog that contains the following +/// values: +/// +/// ENCODING NAME DESCRIPTION +/// ======== =========== ==================================================== +/// SLEB MinDelta The min line delta for special opcodes that advance +/// the address and line number. +/// SLEB MaxDelta The max line delta for single byte opcodes that +/// advance the address and line number. +/// ULEB FirstLine The value of the first source line number to +/// initialize the LineEntry with. +/// +/// Once these prolog items are read, we initialize a LineEntry struct with +/// the start address of the function from the FunctionInfo's address range, +/// a default file index of 1, and the line number set to "FirstLine" from +/// the prolog above: +/// +/// LineEntry Row(BaseAddr, 1, FirstLine); +/// +/// The line table state machine is now initialized and ready to be parsed. +/// The stream that follows this encodes the line entries in a compact +/// form. Some opcodes cause "Row" to be modified and some opcodes may also +/// push "Row" onto the end of the "LineTable.Lines" vector. The end result +/// is a vector of LineEntry structs that is sorted in ascending address +/// order. +/// +/// NORMAL OPCODES +/// +/// The opcodes 0 through 3 are normal in opcodes. Their encoding and +/// descriptions are listed below: +/// +/// ENCODING ENUMERATION VALUE DESCRIPTION +/// ======== ================ ===== ======================================== +/// LTOC_EndSequence 0x00 Parsing is done. +/// ULEB LTOC_SetFile 0x01 Row.File = ULEB +/// ULEB LTOC_AdvancePC 0x02 Row.Addr += ULEB, push "Row". +/// SLEB LTOC_AdvanceLine 0x03 Row.Line += SLEB +/// LTOC_FirstSpecial 0x04 First special opcode (see SPECIAL +/// OPCODES below). +/// +/// SPECIAL OPCODES +/// +/// Opcodes LTOC_FirstSpecial through 255 are special opcodes that always +/// increment both the Row.Addr and Row.Line and push "Row" onto the +/// LineEntry.Lines array. They do this by using some of the bits to +/// increment/decrement the source line number, and some of the bits to +/// increment the address. Line numbers can go up or down when making line +/// tables, where addresses always only increase since line tables are sorted +/// by address. +/// +/// In order to calculate the amount to increment the line and address for +/// these special opcodes, we calculate the number of values reserved for the +/// line increment/decrement using the "MinDelta" and "MaxDelta" from the +/// prolog: +/// +/// const int64_t LineRange = MaxDelta - MinDelta + 1; +/// +/// Then we can adjust the opcode to not include any of the normal opcodes: +/// +/// const uint8_t AdjustedOp = Opcode - LTOC_FirstSpecial; +/// +/// And we can calculate the line offset, and address offset: +/// +/// const int64_t LineDelta = MinDelta + (AdjustedOp % LineRange); +/// const uint64_t AddrDelta = (AdjustedOp / LineRange); +/// +/// And use these to modify our "Row": +/// +/// Row.Line += LineDelta; +/// Row.Addr += AddrDelta; +/// +/// And push a row onto the line table: +/// +/// Lines.push_back(Row); +/// +/// This is verify similar to the way that DWARF encodes its line tables. The +/// only difference is the DWARF line tables have more normal opcodes and the +/// "Row" contains more members, like source column number, bools for end of +/// prologue, beginnging of epilogue, is statement and many others. There are +/// also more complex rules that happen for the extra normal opcodes. By +/// leaving these extra opcodes out, we leave more bits for the special +/// opcodes that allows us to encode line tables in fewer bytes than standard +/// DWARF encodings. +/// +/// Opcodes that will push "Row" onto the LineEntry.Lines include the +/// LTOC_AdvancePC opcode and all special opcodes. All other opcodes +/// only modify the current "Row", or cause the line table to end. +class LineTable { + typedef std::vector<gsym::LineEntry> Collection; + Collection Lines; ///< All line entries in the line table. +public: + /// Lookup a single address within a line table's data. + /// + /// Clients have the option to decode an entire line table using + /// LineTable::decode() or just find a single matching entry using this + /// function. The benefit of using this function is that parsed LineEntry + /// objects that do not match will not be stored in an array. This will avoid + /// memory allocation costs and parsing can stop once a match has been found. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the LineTable object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \param BaseAddr The base address to use when decoding the line table. + /// This will be the FunctionInfo's start address and will be used to + /// initialize the line table row prior to parsing any opcodes. + /// + /// \returns An LineEntry object if a match is found, error otherwise. + static Expected<LineEntry> lookup(DataExtractor &Data, uint64_t BaseAddr, + uint64_t Addr); + + /// Decode an LineTable object from a binary data stream. + /// + /// \param Data The binary stream to read the data from. This object must + /// have the data for the LineTable object starting at offset zero. The data + /// can contain more data than needed. + /// + /// \param BaseAddr The base address to use when decoding the line table. + /// This will be the FunctionInfo's start address and will be used to + /// initialize the line table row prior to parsing any opcodes. + /// + /// \returns An LineTable or an error describing the issue that was + /// encountered during decoding. + static llvm::Expected<LineTable> decode(DataExtractor &Data, + uint64_t BaseAddr); + /// Encode this LineTable object into FileWriter stream. + /// + /// \param O The binary stream to write the data to at the current file + /// position. + /// + /// \param BaseAddr The base address to use when decoding the line table. + /// This will be the FunctionInfo's start address. + /// + /// \returns An error object that indicates success or failure or the + /// encoding process. + llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const; + bool empty() const { return Lines.empty(); } + void clear() { Lines.clear(); } + /// Return the first line entry if the line table isn't empty. + /// + /// \returns An optional line entry with the first line entry if the line + /// table isn't empty, or std::nullopt if the line table is emtpy. + std::optional<LineEntry> first() const { + if (Lines.empty()) + return std::nullopt; + return Lines.front(); + } + /// Return the last line entry if the line table isn't empty. + /// + /// \returns An optional line entry with the last line entry if the line + /// table isn't empty, or std::nullopt if the line table is emtpy. + std::optional<LineEntry> last() const { + if (Lines.empty()) + return std::nullopt; + return Lines.back(); + } + void push(const LineEntry &LE) { + Lines.push_back(LE); + } + size_t isValid() const { + return !Lines.empty(); + } + size_t size() const { + return Lines.size(); + } + LineEntry &get(size_t i) { + assert(i < Lines.size()); + return Lines[i]; + } + const LineEntry &get(size_t i) const { + assert(i < Lines.size()); + return Lines[i]; + } + LineEntry &operator[](size_t i) { + return get(i); + } + const LineEntry &operator[](size_t i) const { + return get(i); + } + bool operator==(const LineTable &RHS) const { + return Lines == RHS.Lines; + } + bool operator!=(const LineTable &RHS) const { + return Lines != RHS.Lines; + } + bool operator<(const LineTable &RHS) const { + const auto LHSSize = Lines.size(); + const auto RHSSize = RHS.Lines.size(); + if (LHSSize == RHSSize) + return Lines < RHS.Lines; + return LHSSize < RHSSize; + } + Collection::const_iterator begin() const { return Lines.begin(); } + Collection::const_iterator end() const { return Lines.end(); } + +}; + +raw_ostream &operator<<(raw_ostream &OS, const gsym::LineTable <); + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_LINETABLE_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LookupResult.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LookupResult.h new file mode 100644 index 0000000000..ab2e98242d --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/LookupResult.h @@ -0,0 +1,71 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- LookupResult.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_LOOKUPRESULT_H +#define LLVM_DEBUGINFO_GSYM_LOOKUPRESULT_H + +#include "llvm/ADT/AddressRanges.h" +#include "llvm/ADT/StringRef.h" +#include <inttypes.h> +#include <vector> + +namespace llvm { +class raw_ostream; +namespace gsym { + +struct SourceLocation { + StringRef Name; ///< Function or symbol name. + StringRef Dir; ///< Line entry source file directory path. + StringRef Base; ///< Line entry source file basename. + uint32_t Line = 0; ///< Source file line number. + uint32_t Offset = 0; ///< Byte size offset within the named function. +}; + +inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) { + return LHS.Name == RHS.Name && LHS.Dir == RHS.Dir && LHS.Base == RHS.Base && + LHS.Line == RHS.Line && LHS.Offset == RHS.Offset; +} + +raw_ostream &operator<<(raw_ostream &OS, const SourceLocation &R); + +using SourceLocations = std::vector<SourceLocation>; + +struct LookupResult { + uint64_t LookupAddr = 0; ///< The address that this lookup pertains to. + AddressRange FuncRange; ///< The concrete function address range. + StringRef FuncName; ///< The concrete function name that contains LookupAddr. + /// The source locations that match this address. This information will only + /// be filled in if the FunctionInfo contains a line table. If an address is + /// for a concrete function with no inlined functions, this array will have + /// one entry. If an address points to an inline function, there will be one + /// SourceLocation for each inlined function with the last entry pointing to + /// the concrete function itself. This allows one address to generate + /// multiple locations and allows unwinding of inline call stacks. The + /// deepest inline function will appear at index zero in the source locations + /// array, and the concrete function will appear at the end of the array. + SourceLocations Locations; + std::string getSourceFile(uint32_t Index) const; +}; + +raw_ostream &operator<<(raw_ostream &OS, const LookupResult &R); + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_LOOKUPRESULT_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h new file mode 100644 index 0000000000..e75a5d8b07 --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h @@ -0,0 +1,61 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- ObjectFileTransformer.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_OBJECTFILETRANSFORMER_H +#define LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H + +#include "llvm/Support/Error.h" + +namespace llvm { + +class raw_ostream; + +namespace object { +class ObjectFile; +} + +namespace gsym { + +class GsymCreator; + +class ObjectFileTransformer { +public: + /// Extract any object file data that is needed by the GsymCreator. + /// + /// The extracted information includes the UUID of the binary and converting + /// all function symbols from any symbol tables into FunctionInfo objects. + /// + /// \param Obj The object file that contains the DWARF debug info. + /// + /// \param Log The stream to log warnings and non fatal issues to. + /// + /// \param Gsym The GSYM creator to populate with the function information + /// from the debug info. + /// + /// \returns An error indicating any fatal issues that happen when parsing + /// the DWARF, or Error::success() if all goes well. + static llvm::Error convert(const object::ObjectFile &Obj, + raw_ostream &Log, + GsymCreator &Gsym); +}; + +} // namespace gsym +} // namespace llvm + +#endif // LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/StringTable.h b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/StringTable.h new file mode 100644 index 0000000000..b0d7b2311e --- /dev/null +++ b/contrib/libs/llvm16/include/llvm/DebugInfo/GSYM/StringTable.h @@ -0,0 +1,61 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- StringTable.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_STRINGTABLE_H +#define LLVM_DEBUGINFO_GSYM_STRINGTABLE_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/GSYM/ExtractRanges.h" +#include <stdint.h> + +namespace llvm { +namespace gsym { + +/// String tables in GSYM files are required to start with an empty +/// string at offset zero. Strings must be UTF8 NULL terminated strings. +struct StringTable { + StringRef Data; + StringTable() = default; + StringTable(StringRef D) : Data(D) {} + StringRef operator[](size_t Offset) const { return getString(Offset); } + StringRef getString(uint32_t Offset) const { + if (Offset < Data.size()) { + auto End = Data.find('\0', Offset); + return Data.substr(Offset, End - Offset); + } + return StringRef(); + } + void clear() { Data = StringRef(); } +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const StringTable &S) { + OS << "String table:\n"; + uint32_t Offset = 0; + const size_t Size = S.Data.size(); + while (Offset < Size) { + StringRef Str = S.getString(Offset); + OS << HEX32(Offset) << ": \"" << Str << "\"\n"; + Offset += Str.size() + 1; + } + return OS; +} + +} // namespace gsym +} // namespace llvm +#endif // LLVM_DEBUGINFO_GSYM_STRINGTABLE_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |