30 return Name.starts_with(
"_Z") || Name.starts_with(
"$s") ||
31 Name.starts_with(
"$S");
37 if (CurrentName.
empty() && !AlternateName.
empty())
50 OS << CurrentName.
size() << CurrentName;
71 std::lock_guard<std::mutex> Guard(
Mutex);
72 const auto NextIndex =
Files.size();
76 Files.emplace_back(FE);
77 return R.first->second;
98 std::optional<uint64_t> SegmentSize)
const {
118 if (
Funcs.size() < 2)
123 std::vector<FunctionInfo> TopLevelFuncs;
126 TopLevelFuncs.emplace_back(std::move(
Funcs.front()));
131 for (
size_t Idx = 1; Idx <
Funcs.size(); ++Idx) {
144 std::move(MatchFunc));
147 TopLevelFuncs.emplace_back(std::move(MatchFunc));
152 if (mergedCount != 0)
153 Out <<
"Have " << mergedCount
154 <<
" merged functions as children of other functions\n";
163static std::optional<uint64_t>
166 const uint64_t SectSize = Sect.getSize();
169 const uint64_t SectAddr = Sect.getAddress();
170 if (Addr >= SectAddr && Addr < SectAddr + SectSize)
171 return SectAddr + SectSize;
178 std::lock_guard<std::mutex> Guard(
Mutex);
207 const auto NumBefore =
Funcs.size();
217 std::vector<FunctionInfo> FinalizedFuncs;
218 FinalizedFuncs.reserve(
Funcs.size());
219 FinalizedFuncs.emplace_back(std::move(
Funcs.front()));
220 for (
size_t Idx=1; Idx < NumBefore; ++Idx) {
226 const bool ranges_equal = Prev.
Range == Curr.
Range;
241 if (PrevRich != CurrRich) {
246 }
else if (Prev != Curr) {
249 "Duplicate address ranges with different debug info.",
251 OS <<
"warning: same address range contains "
253 <<
"info. Removing:\n"
254 << Prev <<
"\nIn favor of this one:\n"
260 Out.Report(
"Overlapping function ranges", [&](
raw_ostream &OS) {
262 OS <<
"warning: function ranges overlap:\n"
266 FinalizedFuncs.emplace_back(std::move(Curr));
275 FinalizedFuncs.emplace_back(std::move(Curr));
287 const uint64_t StartAddr =
Funcs.back().Range.start();
289 uint64_t EndAddr =
Range->end();
297 EndAddr = std::min(EndAddr, *SectEndAddr);
299 Funcs.back().Range = {StartAddr, EndAddr};
302 Out <<
"Pruned " << NumBefore -
Funcs.size() <<
" functions, ended with "
303 <<
Funcs.size() <<
" total\n";
322 std::lock_guard<std::mutex> Guard(
Mutex);
330 if (!
StrTab.contains(CHStr))
345 "GsymCreator::getString expects a valid offset as parameter.");
346 return I->second.val();
350 std::lock_guard<std::mutex> Guard(
Mutex);
351 Funcs.emplace_back(std::move(FI));
356 std::lock_guard<std::mutex> Guard(
Mutex);
357 for (
auto &FI :
Funcs) {
364 std::function<
bool(
const FunctionInfo &)>
const &Callback)
const {
365 std::lock_guard<std::mutex> Guard(
Mutex);
366 for (
const auto &FI :
Funcs) {
373 std::lock_guard<std::mutex> Guard(
Mutex);
389 return std::optional<uint64_t>(
Funcs.front().startAddress());
399 return std::optional<uint64_t>(
Funcs.back().startAddress());
411 case 1:
return UINT8_MAX;
412 case 2:
return UINT16_MAX;
413 case 4:
return UINT32_MAX;
423 const uint64_t AddrDelta = *LastFuncAddr - *
BaseAddress;
424 if (AddrDelta <= UINT8_MAX)
426 else if (AddrDelta <= UINT16_MAX)
428 else if (AddrDelta <= UINT32_MAX)
439 "no functions to encode");
442 "GsymCreator wasn't finalized prior to encoding");
443 if (
Funcs.size() > UINT32_MAX)
445 "too many FunctionInfos");
449 "invalid base address");
454 uint64_t BaseAddr)
const {
456 O.alignTo(AddrOffSize);
457 for (
const auto &FI :
Funcs) {
458 uint64_t AddrOffset = FI.startAddress() - BaseAddr;
463 assert(AddrOffset <= MaxAddressOffset);
464 (void)MaxAddressOffset;
465 switch (AddrOffSize) {
467 O.writeU8(
static_cast<uint8_t>(AddrOffset));
470 O.writeU16(
static_cast<uint16_t
>(AddrOffset));
473 O.writeU32(
static_cast<uint32_t>(AddrOffset));
476 O.writeU64(AddrOffset);
488 if (
Files.size() > UINT32_MAX)
491 for (
const auto &File :
Files) {
492 O.writeStringOffset(File.Dir);
493 O.writeStringOffset(File.Base);
504 for (
auto &ChildII:
II.Children)
524 const size_t NumLines = DstLT.
size();
525 for (
size_t I=0;
I<NumLines; ++
I) {
537 std::lock_guard<std::mutex> Guard(
Mutex);
538 Funcs.emplace_back(DstFI);
539 return Funcs.back().cacheEncoding(*
this);
544 uint64_t SegmentSize)
const {
545 if (SegmentSize == 0)
547 "invalid segment size zero");
550 const size_t NumFuncs =
Funcs.size();
551 while (FuncIdx < NumFuncs) {
563 std::string SegmentedGsymPath;
565 std::optional<uint64_t> FirstFuncAddr = GC->getFirstFunctionAddress();
568 Err = GC->save(SegmentedGsymPath, ByteOrder, std::nullopt);
582 if (FuncIdx >=
Funcs.size())
583 return std::unique_ptr<GsymCreator>();
585 std::unique_ptr<GsymCreator> GC =
createNew();
595 const size_t NumFuncs =
Funcs.size();
599 uint64_t SegmentFuncInfosSize = 0;
600 for (; FuncIdx < NumFuncs; ++FuncIdx) {
601 const uint64_t HeaderAndTableSize = GC->calculateHeaderAndTableSize();
602 if (HeaderAndTableSize + SegmentFuncInfosSize >= SegmentSize) {
603 if (SegmentFuncInfosSize == 0)
605 "a segment size of %" PRIu64
" is to small to "
606 "fit any function infos, specify a larger value",
611 SegmentFuncInfosSize +=
alignTo(GC->copyFunctionInfo(*
this, FuncIdx), 4);
613 return std::move(GC);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static std::optional< uint64_t > getSectionEndAddress(const object::ObjectFile &Obj, uint64_t Addr)
Find the end address of the section that contains Addr.
static bool shouldReplaceWithMangledName(StringRef AlternateName, StringRef CurrentName)
static bool isSupportedMangledPrefix(StringRef Name)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
This file defines the SmallString class.
bool intersects(const AddressRange &R) const
bool contains(uint64_t Addr) const
A container which contains a StringRef plus a precomputed hash.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
constexpr size_t size() const
Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Utility for building string tables with deduplicated suffixes.
LLVM_ABI llvm::Error loadYAML(StringRef YAMLFile)
This method reads the specified YAML file, parses its content, and updates the Funcs vector with call...
A simplified binary data writer class that doesn't require targets, target definitions,...
LLVM_ABI void addFunctionInfo(FunctionInfo &&FI)
Add a function info to this GSYM creator.
LLVM_ABI llvm::Error finalize(OutputAggregator &OS, const object::ObjectFile *Obj=nullptr)
Finalize the data in the GSYM creator prior to saving the data out.
LLVM_ABI void fixupInlineInfo(const GsymCreator &SrcGC, InlineInfo &II)
Fixup any string and file references by updating any file indexes and strings offsets in the InlineIn...
std::vector< llvm::gsym::FileEntry > Files
LLVM_ABI uint64_t copyFunctionInfo(const GsymCreator &SrcGC, size_t FuncInfoIdx)
Copy a FunctionInfo from the SrcGC GSYM creator into this creator.
LLVM_ABI llvm::Error saveSegments(StringRef Path, llvm::endianness ByteOrder, uint64_t SegmentSize) const
Save this GSYM file into segments that are roughly SegmentSize in size.
LLVM_ABI llvm::Error validateForEncoding(std::optional< uint64_t > &BaseAddr) const
Validate that the creator is ready for encoding.
LLVM_ABI gsym_strp_t copyString(const GsymCreator &SrcGC, gsym_strp_t StrOff)
Copy a string from SrcGC into this object.
std::optional< uint64_t > BaseAddress
LLVM_ABI llvm::Error encodeFileTable(FileWriter &O) const
Write the file table to the output stream.
LLVM_ABI gsym_strp_t insertString(StringRef S, bool Copy=true)
Insert a string into the GSYM string table.
LLVM_ABI llvm::Expected< std::unique_ptr< GsymCreator > > createSegment(uint64_t SegmentSize, size_t &FuncIdx) const
Create a segmented GSYM creator starting with function info index FuncIdx.
LLVM_ABI llvm::Error save(StringRef Path, llvm::endianness ByteOrder, std::optional< uint64_t > SegmentSize=std::nullopt) const
Save a GSYM file to a stand alone file.
LLVM_ABI StringRef getString(gsym_strp_t Offset)
Retrieve a string from the GSYM string table given its offset.
StringTableBuilder StrTab
LLVM_ABI void prepareMergedFunctions(OutputAggregator &Out)
Organize merged FunctionInfo's.
DenseMap< llvm::gsym::FileEntry, uint32_t > FileEntryToIndex
std::vector< uint8_t > UUID
LLVM_ABI std::optional< uint64_t > getFirstFunctionAddress() const
Get the first function start address.
std::optional< AddressRanges > ValidTextRanges
std::vector< FunctionInfo > Funcs
LLVM_ABI llvm::Error loadCallSitesFromYAML(StringRef YAMLFile)
Load call site information from a YAML file.
LLVM_ABI uint32_t insertFileEntry(FileEntry FE)
Inserts a FileEntry into the file table.
virtual uint8_t getStringOffsetSize() const =0
Get the size in bytes needed for encoding string offsets.
DenseMap< uint64_t, CachedHashStringRef > StringOffsetMap
LLVM_ABI uint64_t getMaxAddressOffset() const
Get the maximum address offset for the current address offset size.
LLVM_ABI std::optional< uint64_t > getLastFunctionAddress() const
Get the last function address.
LLVM_ABI uint32_t copyFile(const GsymCreator &SrcGC, uint32_t FileIdx)
Copy a file from SrcGC into this object.
LLVM_ABI uint32_t insertFile(StringRef Path, sys::path::Style Style=sys::path::Style::native)
Insert a file into this GSYM creator.
virtual std::unique_ptr< GsymCreator > createNew() const =0
Create a new empty creator of the same version.
virtual llvm::Error encode(FileWriter &O) const =0
Encode a GSYM into the file writer stream at the current position.
LLVM_ABI size_t getNumFunctionInfos() const
Get the current number of FunctionInfo objects contained in this object.
LLVM_ABI void encodeAddrOffsets(FileWriter &O, uint8_t AddrOffSize, uint64_t BaseAddr) const
Write the address offsets table to the output stream.
LLVM_ABI std::optional< uint64_t > getBaseAddress() const
Get the base address to use for this GSYM file.
LLVM_ABI uint8_t getAddressOffsetSize() const
Get the size of an address offset in the address offset table.
LLVM_ABI bool IsValidTextAddress(uint64_t Addr) const
Check if an address is a valid code address.
LLVM_ABI void forEachFunctionInfo(std::function< bool(FunctionInfo &)> const &Callback)
Thread safe iteration over all function infos.
LineTable class contains deserialized versions of line tables for each function's address ranges.
LineEntry & get(size_t i)
This class is the base class for all object file types.
This is a value type class that represents a single section in the list of sections in the object fil...
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t gsym_strp_t
The type of string offset used in the code.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Files in GSYM are contained in FileEntry structs where we split the directory and basename into two d...
gsym_strp_t Dir
Offsets in the string table.
Function information in GSYM files encodes information for one contiguous address range.
std::optional< InlineInfo > Inline
std::optional< MergedFunctionsInfo > MergedFunctions
bool hasRichInfo() const
Query if a FunctionInfo has rich debug info.
gsym_strp_t Name
String table offset in the string table.
std::optional< LineTable > OptLineTable
Inline information stores the name of the inline function along with an array of address ranges.
Line entries are used to encode the line tables in FunctionInfo objects.