[llvm] [gSYM] Add support merged functions in gSYM format (PR #101604)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 1 20:15:33 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: None (alx32)
<details>
<summary>Changes</summary>
This patch introduces support for storing debug info for merged functions in the GSYM debug info. It allows GSYM to represent multiple functions that share the same address range, which occur when multiple functions are merged during linker ICF.
The core of this functionality is the new `MergedFunctionsInfo` class, which is integrated into the existing `FunctionInfo` structure. During GSYM creation, functions with identical address ranges are now grouped together, with one function serving as the "master" and the others becoming "merged" functions. This organization is preserved in the GSYM format and can be read back and displayed when dumping GSYM information.
Old readers will only see the master function, and ther "merged" functions will not be processed.
Note: This patch just adds the functionality to the gSYM format - additional changes to the gsym format and algorithmic changes to logic existing tooling are needed to take advantage of this data.
Exact output of `llvm-gsymutil --verify --verbose` for the included test: [gist](https://gist.github.com/alx32/b9c104d7f87c0b3e7b4171399fc2dca3)
---
Patch is 42.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/101604.diff
11 Files Affected:
- (modified) llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h (+10-1)
- (modified) llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h (+9)
- (modified) llvm/include/llvm/DebugInfo/GSYM/GsymReader.h (+18-2)
- (added) llvm/include/llvm/DebugInfo/GSYM/MergedFunctionsInfo.h (+61)
- (modified) llvm/lib/DebugInfo/GSYM/CMakeLists.txt (+1)
- (modified) llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp (+34-5)
- (modified) llvm/lib/DebugInfo/GSYM/GsymCreator.cpp (+38)
- (modified) llvm/lib/DebugInfo/GSYM/GsymReader.cpp (+20-4)
- (added) llvm/lib/DebugInfo/GSYM/MergedFunctionsInfo.cpp (+57)
- (added) llvm/test/tools/llvm-gsymutil/ARM_AArch64/macho-merged-funcs-dwarf.yaml (+740)
- (modified) llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp (+5)
``````````diff
diff --git a/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h b/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
index 12788b0d4feea..71209b6b5c9cd 100644
--- a/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
+++ b/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/GSYM/InlineInfo.h"
#include "llvm/DebugInfo/GSYM/LineTable.h"
#include "llvm/DebugInfo/GSYM/LookupResult.h"
+#include "llvm/DebugInfo/GSYM/MergedFunctionsInfo.h"
#include "llvm/DebugInfo/GSYM/StringTable.h"
#include <cstdint>
@@ -90,6 +91,7 @@ struct FunctionInfo {
uint32_t Name; ///< String table offset in the string table.
std::optional<LineTable> OptLineTable;
std::optional<InlineInfo> Inline;
+ std::optional<MergedFunctionsInfo> MergedFunctions;
/// 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.
@@ -140,9 +142,16 @@ struct FunctionInfo {
/// \param O The binary stream to write the data to at the current file
/// position.
///
+ /// \param NoPadding Directly write the FunctionInfo data, without any padding
+ /// By default, FunctionInfo will be 4-byte aligned by padding with
+ /// 0's at the start. This is OK since the function will return the offset of
+ /// actual data in the stream. However when writing FunctionInfo's as a
+ /// stream, the padding will break the decoding of the data - since the offset
+ /// where the FunctionInfo starts is not kept in this scenario.
+ ///
/// \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;
+ llvm::Expected<uint64_t> encode(FileWriter &O, bool NoPadding = false) const;
/// Encode this function info into the internal byte cache and return the size
/// in bytes.
diff --git a/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h b/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
index 855a275725c4a..48808fb7b71e1 100644
--- a/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
+++ b/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
@@ -352,6 +352,15 @@ class GsymCreator {
/// \param FI The function info object to emplace into our functions list.
void addFunctionInfo(FunctionInfo &&FI);
+ /// 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.
+ void prepareMergedFunctions(OutputAggregator &Out);
+
/// Finalize the data in the GSYM creator prior to saving the data out.
///
/// Finalize must be called after all FunctionInfo objects have been added
diff --git a/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h b/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
index c1bdc68d808c7..89f8c043b9151 100644
--- a/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
+++ b/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
@@ -166,7 +166,20 @@ class GsymReader {
/// \param OS The output stream to dump to.
///
/// \param FI The object to dump.
- void dump(raw_ostream &OS, const FunctionInfo &FI);
+ ///
+ /// \param Indent The indentation as number of spaces. Used when dumping as an
+ /// item within MergedFunctionsInfo.
+ void dump(raw_ostream &OS, const FunctionInfo &FI, uint32_t Indent = 0);
+
+ /// Dump a MergedFunctionsInfo object.
+ ///
+ /// This function will dump a MergedFunctionsInfo object - basically by
+ /// dumping the contained FunctionInfo objects with indentation.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param MFI The object to dump.
+ void dump(raw_ostream &OS, const MergedFunctionsInfo &MFI);
/// Dump a LineTable object.
///
@@ -177,7 +190,10 @@ class GsymReader {
/// \param OS The output stream to dump to.
///
/// \param LT The object to dump.
- void dump(raw_ostream &OS, const LineTable <);
+ ///
+ /// \param Indent The indentation as number of spaces. Used when dumping as an
+ /// item from within MergedFunctionsInfo.
+ void dump(raw_ostream &OS, const LineTable <, uint32_t Indent = 0);
/// Dump a InlineInfo object.
///
diff --git a/llvm/include/llvm/DebugInfo/GSYM/MergedFunctionsInfo.h b/llvm/include/llvm/DebugInfo/GSYM/MergedFunctionsInfo.h
new file mode 100644
index 0000000000000..1cb5e0a9e557a
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/GSYM/MergedFunctionsInfo.h
@@ -0,0 +1,61 @@
+//===- MergedFunctionsInfo.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_MERGEDFUNCTIONSINFO_H
+#define LLVM_DEBUGINFO_GSYM_MERGEDFUNCTIONSINFO_H
+
+#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
+#include "llvm/Support/Error.h"
+#include <stdint.h>
+#include <vector>
+
+namespace llvm {
+class raw_ostream;
+
+namespace gsym {
+
+class GsymReader;
+struct FunctionInfo;
+struct MergedFunctionsInfo {
+ std::vector<FunctionInfo> MergedFunctions;
+
+ void clear() { MergedFunctions.clear(); }
+
+ /// Query if a MergedFunctionsInfo object is valid.
+ ///
+ /// \returns A boolean indicating if this FunctionInfo is valid.
+ bool isValid() { return true; }
+
+ /// Decode an MergedFunctionsInfo object from a binary data stream.
+ ///
+ /// \param Data The binary stream to read the data from. This object must have
+ /// the data for the MergedFunctionsInfo object starting at offset zero. The
+ /// data can contain more data than needed.
+ ///
+ /// \param BaseAddr The base address to use when encoding all address ranges.
+ ///
+ /// \returns An MergedFunctionsInfo or an error describing the issue that was
+ /// encountered during decoding.
+ static llvm::Expected<MergedFunctionsInfo> decode(DataExtractor &Data,
+ uint64_t BaseAddr);
+
+ /// Encode this MergedFunctionsInfo 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 for the
+ /// encoding process.
+ llvm::Error encode(FileWriter &O) const;
+};
+
+bool operator==(const MergedFunctionsInfo &LHS, const MergedFunctionsInfo &RHS);
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_GSYM_MERGEDFUNCTIONSINFO_H
diff --git a/llvm/lib/DebugInfo/GSYM/CMakeLists.txt b/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
index 5447030e903da..be90bfdaa7fd2 100644
--- a/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
@@ -8,6 +8,7 @@ add_llvm_component_library(LLVMDebugInfoGSYM
InlineInfo.cpp
LineTable.cpp
LookupResult.cpp
+ MergedFunctionsInfo.cpp
ObjectFileTransformer.cpp
ExtractRanges.cpp
diff --git a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
index 07303d551af50..2cd85ef2398f9 100644
--- a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
+++ b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
@@ -22,7 +22,8 @@ using namespace gsym;
enum InfoType : uint32_t {
EndOfList = 0u,
LineTableInfo = 1u,
- InlineInfo = 2u
+ InlineInfo = 2u,
+ MergedFunctionsInfo = 3u,
};
raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const FunctionInfo &FI) {
@@ -86,6 +87,14 @@ llvm::Expected<FunctionInfo> FunctionInfo::decode(DataExtractor &Data,
return II.takeError();
break;
+ case InfoType::MergedFunctionsInfo:
+ if (Expected<MergedFunctionsInfo> MI =
+ MergedFunctionsInfo::decode(InfoData, BaseAddr))
+ FI.MergedFunctions = std::move(MI.get());
+ else
+ return MI.takeError();
+ break;
+
default:
return createStringError(std::errc::io_error,
"0x%8.8" PRIx64 ": unsupported InfoType %u",
@@ -111,12 +120,14 @@ uint64_t FunctionInfo::cacheEncoding() {
return EncodingCache.size();
}
-llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &Out) const {
+llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &Out,
+ bool NoPadding) const {
if (!isValid())
return createStringError(std::errc::invalid_argument,
"attempted to encode invalid FunctionInfo object");
- // Align FunctionInfo data to a 4 byte alignment.
- Out.alignTo(4);
+ // Align FunctionInfo data to a 4 byte alignment, if padding is allowed
+ if (NoPadding == false)
+ Out.alignTo(4);
const uint64_t FuncInfoOffset = Out.tell();
// Check if we have already encoded this function info into EncodingCache.
// This will be non empty when creating segmented GSYM files as we need to
@@ -170,13 +181,31 @@ llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &Out) const {
Out.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
}
+ // Write out the merged functions info if we have any and if it is valid.
+ if (MergedFunctions) {
+ Out.writeU32(InfoType::MergedFunctionsInfo);
+ // Write a uint32_t length as zero for now, we will fix this up after
+ // writing the LineTable out with the number of bytes that were written.
+ Out.writeU32(0);
+ const auto StartOffset = Out.tell();
+ llvm::Error err = MergedFunctions->encode(Out);
+ if (err)
+ return std::move(err);
+ const auto Length = Out.tell() - StartOffset;
+ if (Length > UINT32_MAX)
+ return createStringError(
+ std::errc::invalid_argument,
+ "MergedFunctionsInfo length is greater than UINT32_MAX");
+ // Fixup the size of the MergedFunctionsInfo data with the correct size.
+ Out.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
+ }
+
// Terminate the data chunks with and end of list with zero size
Out.writeU32(InfoType::EndOfList);
Out.writeU32(0);
return FuncInfoOffset;
}
-
llvm::Expected<LookupResult> FunctionInfo::lookup(DataExtractor &Data,
const GsymReader &GR,
uint64_t FuncAddr,
diff --git a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
index deedaeea2fe23..06c9846408395 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
@@ -189,6 +189,44 @@ llvm::Error GsymCreator::encode(FileWriter &O) const {
return ErrorSuccess();
}
+void GsymCreator::prepareMergedFunctions(OutputAggregator &Out) {
+ // Nothing to do if we have less than 2 functions.
+ if (Funcs.size() < 2)
+ return;
+
+ // Sort the function infos by address range first
+ llvm::sort(Funcs);
+ std::vector<FunctionInfo> TopLevelFuncs;
+
+ // Add the first function info to the top level functions
+ TopLevelFuncs.emplace_back(std::move(Funcs.front()));
+
+ // Now if the next function info has the same address range as the top level,
+ // then merge it into the top level function, otherwise add it to the top
+ // level.
+ for (size_t Idx = 1; Idx < Funcs.size(); ++Idx) {
+ FunctionInfo &TopFunc = TopLevelFuncs.back();
+ FunctionInfo &MatchFunc = Funcs[Idx];
+ if (TopFunc.Range == MatchFunc.Range) {
+ // Both have the same range - add the 2nd func as a child of the 1st func
+ if (!TopFunc.MergedFunctions)
+ TopFunc.MergedFunctions = MergedFunctionsInfo();
+ TopFunc.MergedFunctions->MergedFunctions.emplace_back(
+ std::move(MatchFunc));
+ } else
+ // No match, add the function as a top-level function
+ TopLevelFuncs.emplace_back(std::move(MatchFunc));
+ }
+
+ uint32_t mergedCount = Funcs.size() - TopLevelFuncs.size();
+ // If any functions were merged, print a message about it.
+ if (mergedCount != 0)
+ Out << "Have " << mergedCount
+ << " merged functions as children of other functions\n";
+
+ std::swap(Funcs, TopLevelFuncs);
+}
+
llvm::Error GsymCreator::finalize(OutputAggregator &Out) {
std::lock_guard<std::mutex> Guard(Mutex);
if (Finalized)
diff --git a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
index 4b1b352466175..ddfc92e1a8a40 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
@@ -398,17 +398,33 @@ void GsymReader::dump(raw_ostream &OS) {
}
}
-void GsymReader::dump(raw_ostream &OS, const FunctionInfo &FI) {
+void GsymReader::dump(raw_ostream &OS, const FunctionInfo &FI,
+ uint32_t Indent) {
+ OS.indent(Indent);
OS << FI.Range << " \"" << getString(FI.Name) << "\"\n";
if (FI.OptLineTable)
- dump(OS, *FI.OptLineTable);
+ dump(OS, *FI.OptLineTable, Indent);
if (FI.Inline)
- dump(OS, *FI.Inline);
+ dump(OS, *FI.Inline, Indent);
+
+ if (FI.MergedFunctions) {
+ assert(Indent == 0 && "MergedFunctionsInfo should only exist at top level");
+ dump(OS, *FI.MergedFunctions);
+ }
+}
+
+void GsymReader::dump(raw_ostream &OS, const MergedFunctionsInfo &MFI) {
+ for (uint32_t inx = 0; inx < MFI.MergedFunctions.size(); inx++) {
+ OS << "++ Merged FunctionInfos[" << inx << "]:\n";
+ dump(OS, MFI.MergedFunctions[inx], 4);
+ }
}
-void GsymReader::dump(raw_ostream &OS, const LineTable <) {
+void GsymReader::dump(raw_ostream &OS, const LineTable <, uint32_t Indent) {
+ OS.indent(Indent);
OS << "LineTable:\n";
for (auto &LE: LT) {
+ OS.indent(Indent);
OS << " " << HEX64(LE.Addr) << ' ';
if (LE.File)
dump(OS, getFile(LE.File));
diff --git a/llvm/lib/DebugInfo/GSYM/MergedFunctionsInfo.cpp b/llvm/lib/DebugInfo/GSYM/MergedFunctionsInfo.cpp
new file mode 100644
index 0000000000000..41e74840510b8
--- /dev/null
+++ b/llvm/lib/DebugInfo/GSYM/MergedFunctionsInfo.cpp
@@ -0,0 +1,57 @@
+//===- LineTable.cpp --------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/MergedFunctionsInfo.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/Support/DataExtractor.h"
+
+using namespace llvm;
+using namespace gsym;
+
+llvm::Error MergedFunctionsInfo::encode(FileWriter &Out) const {
+ Out.writeU32(MergedFunctions.size());
+ for (const auto &F : MergedFunctions) {
+ Out.writeU32(0);
+ const auto StartOffset = Out.tell();
+ // Encode the FunctionInfo with no padding so later we can just read them
+ // one after the other without knowing the offset in the stream for each.
+ llvm::Expected<uint64_t> result = F.encode(Out, /*NoPadding =*/true);
+ if (!result)
+ return result.takeError();
+ const auto Length = Out.tell() - StartOffset;
+ Out.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
+ }
+ return Error::success();
+}
+
+llvm::Expected<MergedFunctionsInfo>
+MergedFunctionsInfo::decode(DataExtractor &Data, uint64_t BaseAddr) {
+ MergedFunctionsInfo MFI;
+ uint64_t Offset = 0;
+ uint32_t Count = Data.getU32(&Offset);
+
+ for (uint32_t i = 0; i < Count; ++i) {
+ uint32_t FnSize = Data.getU32(&Offset);
+ DataExtractor FnData(Data.getData().substr(Offset, FnSize),
+ Data.isLittleEndian(), Data.getAddressSize());
+ llvm::Expected<FunctionInfo> FI =
+ FunctionInfo::decode(FnData, BaseAddr + Offset);
+ if (!FI)
+ return FI.takeError();
+ MFI.MergedFunctions.push_back(std::move(*FI));
+ Offset += FnSize;
+ }
+
+ return MFI;
+}
+
+bool operator==(const MergedFunctionsInfo &LHS,
+ const MergedFunctionsInfo &RHS) {
+ return LHS.MergedFunctions == RHS.MergedFunctions;
+}
diff --git a/llvm/test/tools/llvm-gsymutil/ARM_AArch64/macho-merged-funcs-dwarf.yaml b/llvm/test/tools/llvm-gsymutil/ARM_AArch64/macho-merged-funcs-dwarf.yaml
new file mode 100644
index 0000000000000..3be64524a3d5b
--- /dev/null
+++ b/llvm/test/tools/llvm-gsymutil/ARM_AArch64/macho-merged-funcs-dwarf.yaml
@@ -0,0 +1,740 @@
+# RUN: yaml2obj %s -o %t.dSYM
+# RUN: llvm-gsymutil --convert %t.dSYM --out-file=%t.gSYM
+# RUN: llvm-gsymutil --verify --verbose %t.gSYM | FileCheck --check-prefix=CHECK-GSYM %s
+
+## Note: For identical functions, the dSYM / gSYM cannot be counted on to be deterministic.
+## So we can only match the general structure, not exact function names / offsets
+
+
+# CHECK-GSYM: Address Table:
+# CHECK-GSYM-NEXT: INDEX OFFSET16 (ADDRESS)
+# CHECK-GSYM-NEXT: ====== ===============================
+# CHECK-GSYM-NEXT: [ 0] 0x{{[0-9a-fA-F]+}}
+
+# CHECK-GSYM: Address Info Offsets:
+# CHECK-GSYM-NEXT: INDEX Offset
+# CHECK-GSYM-NEXT: ====== ==========
+# CHECK-GSYM-NEXT: [ 0] 0x{{[0-9a-fA-F]+}}
+
+# CHECK-GSYM: Files:
+# CHECK-GSYM-NEXT: INDEX DIRECTORY BASENAME PATH
+# CHECK-GSYM-NEXT: ====== ========== ========== ==============================
+# CHECK-GSYM-NEXT: [ 0] 0x{{[0-9a-fA-F]+}} 0x{{[0-9a-fA-F]+}}
+# CHECK-GSYM-NEXT: [ 1] 0x{{[0-9a-fA-F]+}} 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp
+# CHECK-GSYM-NEXT: [ 2] 0x{{[0-9a-fA-F]+}} 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp
+# CHECK-GSYM-NEXT: [ 3] 0x{{[0-9a-fA-F]+}} 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp
+
+# CHECK-GSYM: FunctionInfo @ 0x{{[0-9a-fA-F]+}}: [0x{{[0-9a-fA-F]+}} - 0x{{[0-9a-fA-F]+}}) "my_func_0{{[1-3]}}"
+# CHECK-GSYM-NEXT: LineTable:
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:5
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:7
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:9
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:8
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:11
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:10
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:6
+# CHECK-GSYM-NEXT: ++ Merged FunctionInfos[0]:
+# CHECK-GSYM-NEXT: [0x{{[0-9a-fA-F]+}} - 0x{{[0-9a-fA-F]+}}) "my_func_0{{[1-3]}}"
+# CHECK-GSYM-NEXT: LineTable:
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:5
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:7
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:9
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:8
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:11
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:10
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:6
+# CHECK-GSYM-NEXT: ++ Merged FunctionInfos[1]:
+# CHECK-GSYM-NEXT: [0x{{[0-9a-fA-F]+}} - 0x{{[0-9a-fA-F]+}}) "my_func_0{{[1-3]}}"
+# CHECK-GSYM-NEXT: LineTable:
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:5
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:7
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:9
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:8
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:11
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:10
+# CHECK-GSYM-NEXT: 0x{{[0-9a-fA-F]+}} /tmp/test_gsym_yaml/out/file_0{{[1-3]}}.cpp:6
+
+
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0xA
+ ncmds: 6
+ sizeofcmds: 1168
+ flags: 0x0
+ reserved: 0x0
+LoadCommands:
+ - cmd: ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/101604
More information about the llvm-commits
mailing list