Skip to content

Commit ac48f2c

Browse files
author
Alex B
committed
[GSYM] Callsites: Add data format support and loading from YAML
1 parent f41f6ea commit ac48f2c

File tree

15 files changed

+2471
-7
lines changed

15 files changed

+2471
-7
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
//===- CallSiteInfo.h -------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_DEBUGINFO_GSYM_CALLSITEINFO_H
10+
#define LLVM_DEBUGINFO_GSYM_CALLSITEINFO_H
11+
12+
#include "llvm/ADT/DenseMap.h"
13+
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/ADT/StringSet.h"
15+
#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
16+
#include "llvm/Support/YAMLParser.h"
17+
#include <string>
18+
#include <unordered_map>
19+
#include <vector>
20+
21+
namespace llvm {
22+
class DataExtractor;
23+
class raw_ostream;
24+
class StringTableBuilder;
25+
class CachedHashStringRef;
26+
27+
namespace yaml {
28+
struct CallSiteYAML;
29+
struct FunctionYAML;
30+
struct FunctionsYAML;
31+
} // namespace yaml
32+
33+
namespace gsym {
34+
class FileWriter;
35+
struct FunctionInfo;
36+
struct CallSiteInfo {
37+
public:
38+
enum Flags : uint8_t {
39+
None = 0,
40+
// This flag specifies that the call site can only call a function within
41+
// the same link unit as the call site.
42+
InternalCall = 1 << 0,
43+
// This flag specifies that the call site can only call a function outside
44+
// the link unit that the call site is in.
45+
ExternalCall = 1 << 1,
46+
};
47+
48+
/// The return address of the call site.
49+
uint64_t ReturnAddress;
50+
51+
/// Offsets into the string table for function names regex patterns.
52+
std::vector<uint32_t> MatchRegex;
53+
54+
/// Bitwise OR of CallSiteInfo::Flags values
55+
uint8_t Flags;
56+
57+
/// Decode a CallSiteInfo object from a binary data stream.
58+
///
59+
/// \param Data The binary stream to read the data from.
60+
/// \param Offset The current offset within the data stream.
61+
/// \param BaseAddr The base address for decoding (unused here but included
62+
/// for consistency).
63+
///
64+
/// \returns A CallSiteInfo or an error describing the issue.
65+
static llvm::Expected<CallSiteInfo>
66+
decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr);
67+
68+
/// Encode this CallSiteInfo object into a FileWriter stream.
69+
///
70+
/// \param O The binary stream to write the data to.
71+
/// \returns An error object that indicates success or failure.
72+
llvm::Error encode(FileWriter &O) const;
73+
};
74+
75+
struct CallSiteInfoCollection {
76+
public:
77+
std::vector<CallSiteInfo> CallSites;
78+
79+
void clear() { CallSites.clear(); }
80+
81+
/// Query if a CallSiteInfoCollection object is valid.
82+
///
83+
/// \returns True if the collection is not empty.
84+
bool isValid() const { return !CallSites.empty(); }
85+
86+
/// Decode a CallSiteInfoCollection object from a binary data stream.
87+
///
88+
/// \param Data The binary stream to read the data from.
89+
/// \param BaseAddr The base address for decoding (unused here but included
90+
/// for consistency).
91+
///
92+
/// \returns A CallSiteInfoCollection or an error describing the issue.
93+
static llvm::Expected<CallSiteInfoCollection> decode(DataExtractor &Data,
94+
uint64_t BaseAddr);
95+
96+
/// Encode this CallSiteInfoCollection object into a FileWriter stream.
97+
///
98+
/// \param O The binary stream to write the data to.
99+
/// \returns An error object that indicates success or failure.
100+
llvm::Error encode(FileWriter &O) const;
101+
};
102+
103+
bool operator==(const CallSiteInfoCollection &LHS,
104+
const CallSiteInfoCollection &RHS);
105+
106+
bool operator==(const CallSiteInfo &LHS, const CallSiteInfo &RHS);
107+
108+
class CallSiteInfoLoader {
109+
public:
110+
/// Constructor that initializes the CallSiteInfoLoader with necessary data
111+
/// structures.
112+
///
113+
/// \param StringOffsetMap A reference to a DenseMap that maps existing string
114+
/// offsets to CachedHashStringRef. \param StrTab A reference to a
115+
/// StringTableBuilder used for managing looking up and creating new strings.
116+
/// \param StringStorage A reference to a StringSet for storing the data for
117+
/// generated strings.
118+
CallSiteInfoLoader(DenseMap<uint64_t, CachedHashStringRef> &StringOffsetMap,
119+
StringTableBuilder &StrTab, StringSet<> &StringStorage)
120+
: StringOffsetMap(StringOffsetMap), StrTab(StrTab),
121+
StringStorage(StringStorage) {}
122+
123+
/// Loads call site information from a YAML file and populates the provided
124+
/// FunctionInfo vector.
125+
///
126+
/// This method reads the specified YAML file, parses its content, and updates
127+
/// the `Funcs` vector with call site information based on the YAML data.
128+
///
129+
/// \param Funcs A reference to a vector of FunctionInfo objects to be
130+
/// populated.
131+
/// \param YAMLFile A StringRef representing the path to the YAML
132+
/// file to be loaded.
133+
///
134+
/// \returns An `llvm::Error` indicating success or describing any issues
135+
/// encountered during the loading process.
136+
llvm::Error loadYAML(std::vector<FunctionInfo> &Funcs, StringRef YAMLFile);
137+
138+
private:
139+
/// Retrieves an existing string from the StringOffsetMap using the provided
140+
/// offset.
141+
///
142+
/// \param offset A 32-bit unsigned integer representing the offset of the
143+
/// string.
144+
///
145+
/// \returns A StringRef corresponding to the string for the given offset.
146+
///
147+
/// \note This method asserts that the offset exists in the StringOffsetMap.
148+
StringRef stringFromOffset(uint32_t offset) const;
149+
150+
/// Obtains the offset corresponding to a given string in the StrTab. If the
151+
/// string does not already exist, it is created.
152+
///
153+
/// \param str A StringRef representing the string for which the offset is
154+
/// requested.
155+
///
156+
/// \returns A 32-bit unsigned integer representing the offset of the string.
157+
uint32_t offsetFromString(StringRef str);
158+
159+
/// Reads the content of the YAML file specified by `YAMLFile` into
160+
/// `yamlContent`.
161+
///
162+
/// \param YAMLFile A StringRef representing the path to the YAML file.
163+
/// \param Buffer The memory buffer containing the YAML content.
164+
///
165+
/// \returns An `llvm::Error` indicating success or describing any issues
166+
/// encountered while reading the file.
167+
llvm::Error readYAMLFile(StringRef YAMLFile,
168+
std::unique_ptr<llvm::MemoryBuffer> &Buffer);
169+
170+
/// Parses the YAML content and populates `functionsYAML` with the parsed
171+
/// data.
172+
///
173+
/// \param Buffer The memory buffer containing the YAML content.
174+
/// \param functionsYAML A reference to an llvm::yaml::FunctionsYAML object to
175+
/// be populated.
176+
///
177+
/// \returns An `llvm::Error` indicating success or describing any issues
178+
/// encountered during parsing.
179+
llvm::Error parseYAML(llvm::MemoryBuffer &Buffer,
180+
llvm::yaml::FunctionsYAML &functionsYAML);
181+
182+
/// Builds a map from function names to FunctionInfo pointers based on the
183+
/// provided `Funcs` vector.
184+
///
185+
/// \param Funcs A reference to a vector of FunctionInfo objects.
186+
///
187+
/// \returns An unordered_map mapping function names (std::string) to their
188+
/// corresponding FunctionInfo pointers.
189+
std::unordered_map<std::string, FunctionInfo *>
190+
buildFunctionMap(std::vector<FunctionInfo> &Funcs);
191+
192+
/// Processes the parsed YAML functions and updates the `FuncMap` accordingly.
193+
///
194+
/// \param functionsYAML A constant reference to an llvm::yaml::FunctionsYAML
195+
/// object containing parsed YAML data.
196+
/// \param FuncMap A reference to an unordered_map mapping function names to
197+
/// FunctionInfo pointers.
198+
/// \param YAMLFile A StringRef representing the name of the YAML file (used
199+
/// for error messages).
200+
///
201+
/// \returns An `llvm::Error` indicating success or describing any issues
202+
/// encountered during processing.
203+
llvm::Error
204+
processYAMLFunctions(const llvm::yaml::FunctionsYAML &functionsYAML,
205+
std::unordered_map<std::string, FunctionInfo *> &FuncMap,
206+
StringRef YAMLFile);
207+
208+
/// Map of existing string offsets to CachedHashStringRef.
209+
DenseMap<uint64_t, CachedHashStringRef> &StringOffsetMap;
210+
211+
/// The gSYM string table builder.
212+
StringTableBuilder &StrTab;
213+
214+
/// The gSYM string storage - we store generated strings here.
215+
StringSet<> &StringStorage;
216+
};
217+
218+
raw_ostream &operator<<(raw_ostream &OS, const CallSiteInfo &CSI);
219+
raw_ostream &operator<<(raw_ostream &OS, const CallSiteInfoCollection &CSIC);
220+
221+
} // namespace gsym
222+
} // namespace llvm
223+
224+
#endif // LLVM_DEBUGINFO_GSYM_CALLSITEINFO_H

llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
1111

1212
#include "llvm/ADT/SmallString.h"
13+
#include "llvm/DebugInfo/GSYM/CallSiteInfo.h"
1314
#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
1415
#include "llvm/DebugInfo/GSYM/InlineInfo.h"
1516
#include "llvm/DebugInfo/GSYM/LineTable.h"
@@ -63,7 +64,9 @@ class GsymReader;
6364
/// enum InfoType {
6465
/// EndOfList = 0u,
6566
/// LineTableInfo = 1u,
66-
/// InlineInfo = 2u
67+
/// InlineInfo = 2u,
68+
/// MergedFunctionsInfo = 3u,
69+
/// CallSiteInfo = 4u
6770
/// };
6871
///
6972
/// This stream of tuples is terminated by a "InfoType" whose value is
@@ -73,7 +76,7 @@ class GsymReader;
7376
/// clients to still parse the format and skip over any data that they don't
7477
/// understand or want to parse.
7578
///
76-
/// So the function information encoding essientially looks like:
79+
/// So the function information encoding essentially looks like:
7780
///
7881
/// struct {
7982
/// uint32_t Size;
@@ -92,6 +95,7 @@ struct FunctionInfo {
9295
std::optional<LineTable> OptLineTable;
9396
std::optional<InlineInfo> Inline;
9497
std::optional<MergedFunctionsInfo> MergedFunctions;
98+
std::optional<CallSiteInfoCollection> CallSites;
9599
/// If we encode a FunctionInfo during segmenting so we know its size, we can
96100
/// cache that encoding here so we don't need to re-encode it when saving the
97101
/// GSYM file.
@@ -107,7 +111,7 @@ struct FunctionInfo {
107111
/// debug info, we might end up with multiple FunctionInfo objects for the
108112
/// same range and we need to be able to tell which one is the better object
109113
/// to use.
110-
bool hasRichInfo() const { return OptLineTable || Inline; }
114+
bool hasRichInfo() const { return OptLineTable || Inline || CallSites; }
111115

112116
/// Query if a FunctionInfo object is valid.
113117
///

llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,22 @@ class GsymCreator {
352352
/// \param FI The function info object to emplace into our functions list.
353353
void addFunctionInfo(FunctionInfo &&FI);
354354

355+
/// Load call site information from a YAML file.
356+
///
357+
/// This function reads call site information from a specified YAML file and
358+
/// adds it to the GSYM data.
359+
///
360+
/// \param YAMLFile The path to the YAML file containing call site
361+
/// information.
362+
llvm::Error loadCallSitesFromYAML(StringRef YAMLFile);
363+
355364
/// Organize merged FunctionInfo's
356365
///
357366
/// This method processes the list of function infos (Funcs) to identify and
358367
/// group functions with overlapping address ranges.
359368
///
360369
/// \param Out Output stream to report information about how merged
361-
/// FunctionInfo's were handeled.
370+
/// FunctionInfo's were handled.
362371
void prepareMergedFunctions(OutputAggregator &Out);
363372

364373
/// Finalize the data in the GSYM creator prior to saving the data out.

llvm/include/llvm/DebugInfo/GSYM/GsymReader.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ class GsymReader {
181181
/// \param MFI The object to dump.
182182
void dump(raw_ostream &OS, const MergedFunctionsInfo &MFI);
183183

184+
/// Dump a CallSiteInfo object.
185+
///
186+
/// This function will output the details of a CallSiteInfo object in a
187+
/// human-readable format.
188+
///
189+
/// \param OS The output stream to dump to.
190+
///
191+
/// \param CSI The CallSiteInfo object to dump.
192+
void dump(raw_ostream &OS, const CallSiteInfo &CSI);
193+
194+
/// Dump a CallSiteInfoCollection object.
195+
///
196+
/// This function will iterate over a collection of CallSiteInfo objects and
197+
/// dump each one.
198+
///
199+
/// \param OS The output stream to dump to.
200+
///
201+
/// \param CSIC The CallSiteInfoCollection object to dump.
202+
void dump(raw_ostream &OS, const CallSiteInfoCollection &CSIC);
203+
184204
/// Dump a LineTable object.
185205
///
186206
/// This function will convert any string table indexes and file indexes

llvm/lib/DebugInfo/GSYM/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_llvm_component_library(LLVMDebugInfoGSYM
88
InlineInfo.cpp
99
LineTable.cpp
1010
LookupResult.cpp
11+
CallSiteInfo.cpp
1112
MergedFunctionsInfo.cpp
1213
ObjectFileTransformer.cpp
1314
ExtractRanges.cpp

0 commit comments

Comments
 (0)