Skip to content

[GSYM] Callsites: Add data format support and loading from YAML #109781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions llvm/include/llvm/DebugInfo/GSYM/CallSiteInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//===- CallSiteInfo.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_CALLSITEINFO_H
#define LLVM_DEBUGINFO_GSYM_CALLSITEINFO_H

#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Error.h"
#include <vector>

namespace llvm {
class DataExtractor;
class raw_ostream;

namespace yaml {
struct FunctionsYAML;
} // namespace yaml

namespace gsym {
class FileWriter;
class GsymCreator;
struct FunctionInfo;
struct CallSiteInfo {
enum Flags : uint8_t {
None = 0,
// This flag specifies that the call site can only call a function within
// the same link unit as the call site.
InternalCall = 1 << 0,
// This flag specifies that the call site can only call a function outside
// the link unit that the call site is in.
ExternalCall = 1 << 1,

LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ ExternalCall),
};

/// The return offset of the call site - relative to the function start.
uint64_t ReturnOffset = 0;

/// Offsets into the string table for function names regex patterns.
std::vector<uint32_t> MatchRegex;

/// Bitwise OR of CallSiteInfo::Flags values
uint8_t Flags = CallSiteInfo::Flags::None;

/// Decode a CallSiteInfo object from a binary data stream.
///
/// \param Data The binary stream to read the data from.
/// \param Offset The current offset within the data stream.
/// \returns A CallSiteInfo or an error describing the issue.
static llvm::Expected<CallSiteInfo> decode(DataExtractor &Data,
uint64_t &Offset);

/// Encode this CallSiteInfo object into a FileWriter stream.
///
/// \param O The binary stream to write the data to.
/// \returns An error object that indicates success or failure.
llvm::Error encode(FileWriter &O) const;
};

struct CallSiteInfoCollection {
std::vector<CallSiteInfo> CallSites;

/// Decode a CallSiteInfoCollection object from a binary data stream.
///
/// \param Data The binary stream to read the data from.
/// \returns A CallSiteInfoCollection or an error describing the issue.
static llvm::Expected<CallSiteInfoCollection> decode(DataExtractor &Data);

/// Encode this CallSiteInfoCollection object into a FileWriter stream.
///
/// \param O The binary stream to write the data to.
/// \returns An error object that indicates success or failure.
llvm::Error encode(FileWriter &O) const;
};

class CallSiteInfoLoader {
public:
/// Constructor that initializes the CallSiteInfoLoader with necessary data
/// structures.
///
/// \param GCreator A reference to the GsymCreator.
CallSiteInfoLoader(GsymCreator &GCreator, std::vector<FunctionInfo> &Funcs)
: GCreator(GCreator), Funcs(Funcs) {}

/// This method reads the specified YAML file, parses its content, and updates
/// the `Funcs` vector with call site information based on the YAML data.
///
/// \param Funcs A reference to a vector of FunctionInfo objects to be
/// populated.
/// \param YAMLFile A StringRef representing the path to the YAML
/// file to be loaded.
/// \returns An `llvm::Error` indicating success or describing any issues
/// encountered during the loading process.
llvm::Error loadYAML(StringRef YAMLFile);

private:
/// Builds a map from function names to FunctionInfo pointers based on the
/// provided `Funcs` vector.
///
/// \param Funcs A reference to a vector of FunctionInfo objects.
/// \returns A StringMap mapping function names (StringRef) to their
/// corresponding FunctionInfo pointers.
StringMap<FunctionInfo *> buildFunctionMap();

/// Processes the parsed YAML functions and updates the `FuncMap` accordingly.
///
/// \param FuncYAMLs A constant reference to an llvm::yaml::FunctionsYAML
/// object containing parsed YAML data.
/// \param FuncMap A reference to a StringMap mapping function names to
/// FunctionInfo pointers.
/// \returns An `llvm::Error` indicating success or describing any issues
/// encountered during processing.
llvm::Error processYAMLFunctions(const llvm::yaml::FunctionsYAML &FuncYAMLs,
StringMap<FunctionInfo *> &FuncMap);

/// Reference to the parent Gsym Creator object.
GsymCreator &GCreator;

/// Reference to the vector of FunctionInfo objects to be populated.
std::vector<FunctionInfo> &Funcs;
};

raw_ostream &operator<<(raw_ostream &OS, const CallSiteInfo &CSI);
raw_ostream &operator<<(raw_ostream &OS, const CallSiteInfoCollection &CSIC);

} // namespace gsym
} // namespace llvm

#endif // LLVM_DEBUGINFO_GSYM_CALLSITEINFO_H
10 changes: 7 additions & 3 deletions llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H

#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/GSYM/CallSiteInfo.h"
#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
#include "llvm/DebugInfo/GSYM/InlineInfo.h"
#include "llvm/DebugInfo/GSYM/LineTable.h"
Expand Down Expand Up @@ -63,7 +64,9 @@ class GsymReader;
/// enum InfoType {
/// EndOfList = 0u,
/// LineTableInfo = 1u,
/// InlineInfo = 2u
/// InlineInfo = 2u,
/// MergedFunctionsInfo = 3u,
/// CallSiteInfo = 4u
/// };
///
/// This stream of tuples is terminated by a "InfoType" whose value is
Expand All @@ -73,7 +76,7 @@ class GsymReader;
/// 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:
/// So the function information encoding essentially looks like:
///
/// struct {
/// uint32_t Size;
Expand All @@ -92,6 +95,7 @@ struct FunctionInfo {
std::optional<LineTable> OptLineTable;
std::optional<InlineInfo> Inline;
std::optional<MergedFunctionsInfo> MergedFunctions;
std::optional<CallSiteInfoCollection> CallSites;
/// If we encode a FunctionInfo during segmenting so we know its size, we can
/// cache that encoding here so we don't need to re-encode it when saving the
/// GSYM file.
Expand All @@ -107,7 +111,7 @@ struct FunctionInfo {
/// 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; }
bool hasRichInfo() const { return OptLineTable || Inline || CallSites; }

/// Query if a FunctionInfo object is valid.
///
Expand Down
21 changes: 20 additions & 1 deletion llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,16 @@ class GsymCreator {
/// \returns The unique 32 bit offset into the string table.
uint32_t insertString(StringRef S, bool Copy = true);

/// Retrieve a string from the GSYM string table given its offset.
///
/// The offset is assumed to be a valid offset into the string table.
/// otherwise an assert will be triggered.
///
/// \param Offset The offset of the string to retrieve, previously returned by
/// insertString.
/// \returns The string at the given offset in the string table.
StringRef getString(uint32_t Offset);

/// Insert a file into this GSYM creator.
///
/// Inserts a file by adding a FileEntry into the "Files" member variable if
Expand All @@ -352,13 +362,22 @@ class GsymCreator {
/// \param FI The function info object to emplace into our functions list.
void addFunctionInfo(FunctionInfo &&FI);

/// Load call site information from a YAML file.
///
/// This function reads call site information from a specified YAML file and
/// adds it to the GSYM data.
///
/// \param YAMLFile The path to the YAML file containing call site
/// information.
llvm::Error loadCallSitesFromYAML(StringRef YAMLFile);

/// Organize merged FunctionInfo's
///
/// This method processes the list of function infos (Funcs) to identify and
/// group functions with overlapping address ranges.
///
/// \param Out Output stream to report information about how merged
/// FunctionInfo's were handeled.
/// FunctionInfo's were handled.
void prepareMergedFunctions(OutputAggregator &Out);

/// Finalize the data in the GSYM creator prior to saving the data out.
Expand Down
20 changes: 20 additions & 0 deletions llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ class GsymReader {
/// \param MFI The object to dump.
void dump(raw_ostream &OS, const MergedFunctionsInfo &MFI);

/// Dump a CallSiteInfo object.
///
/// This function will output the details of a CallSiteInfo object in a
/// human-readable format.
///
/// \param OS The output stream to dump to.
///
/// \param CSI The CallSiteInfo object to dump.
void dump(raw_ostream &OS, const CallSiteInfo &CSI);

/// Dump a CallSiteInfoCollection object.
///
/// This function will iterate over a collection of CallSiteInfo objects and
/// dump each one.
///
/// \param OS The output stream to dump to.
///
/// \param CSIC The CallSiteInfoCollection object to dump.
void dump(raw_ostream &OS, const CallSiteInfoCollection &CSIC);

/// Dump a LineTable object.
///
/// This function will convert any string table indexes and file indexes
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/DebugInfo/GSYM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_llvm_component_library(LLVMDebugInfoGSYM
InlineInfo.cpp
LineTable.cpp
LookupResult.cpp
CallSiteInfo.cpp
MergedFunctionsInfo.cpp
ObjectFileTransformer.cpp
ExtractRanges.cpp
Expand Down
Loading