[llvm] [llvm-gsymutil] Replace truncated DWARF names with mangled names from symbol table (PR #184221)
Chen Li via llvm-commits
llvm-commits at lists.llvm.org
Fri May 8 13:47:30 PDT 2026
https://github.com/thechenli updated https://github.com/llvm/llvm-project/pull/184221
>From c4da0d41deb6aae2bda64b3b57aef037a3088b1d Mon Sep 17 00:00:00 2001
From: Chen Li <chenlii at fb.com>
Date: Thu, 23 Apr 2026 16:44:58 -0700
Subject: [PATCH] [llvm-gsymutil] Replace truncated DWARF names with mangled
names from symbol table
---
.../llvm/DebugInfo/GSYM/CallSiteInfo.h | 7 +
.../llvm/DebugInfo/GSYM/FunctionInfo.h | 3 +-
llvm/lib/DebugInfo/GSYM/GsymCreator.cpp | 60 ++++++--
.../X86/elf-mangled-name-replacement.yaml | 128 ++++++++++++++++
.../elf-swift-mangled-name-replacement.yaml | 128 ++++++++++++++++
llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp | 139 ++++++++++++++++++
6 files changed, 452 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/tools/llvm-gsymutil/X86/elf-mangled-name-replacement.yaml
create mode 100644 llvm/test/tools/llvm-gsymutil/X86/elf-swift-mangled-name-replacement.yaml
diff --git a/llvm/include/llvm/DebugInfo/GSYM/CallSiteInfo.h b/llvm/include/llvm/DebugInfo/GSYM/CallSiteInfo.h
index 2b72d901f2330..96e4c9adf99ad 100644
--- a/llvm/include/llvm/DebugInfo/GSYM/CallSiteInfo.h
+++ b/llvm/include/llvm/DebugInfo/GSYM/CallSiteInfo.h
@@ -78,6 +78,13 @@ struct CallSiteInfo {
struct CallSiteInfoCollection {
std::vector<CallSiteInfo> CallSites;
+ bool operator==(const CallSiteInfoCollection &RHS) const {
+ return CallSites == RHS.CallSites;
+ }
+ bool operator!=(const CallSiteInfoCollection &RHS) const {
+ return !(*this == RHS);
+ }
+
/// Decode a CallSiteInfoCollection object from a binary data stream.
///
/// \param Data The binary stream to read the data from.
diff --git a/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h b/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
index bd836e6783a97..ef074a6309788 100644
--- a/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
+++ b/llvm/include/llvm/DebugInfo/GSYM/FunctionInfo.h
@@ -217,7 +217,8 @@ struct FunctionInfo {
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;
+ LHS.OptLineTable == RHS.OptLineTable && LHS.Inline == RHS.Inline &&
+ LHS.CallSites == RHS.CallSites;
}
inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
return !(LHS == RHS);
diff --git a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
index 4b3929a532489..36e939cb647b0 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
@@ -6,6 +6,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/GSYM/GsymCreator.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/GSYM/FileWriter.h"
#include "llvm/DebugInfo/GSYM/Header.h"
#include "llvm/DebugInfo/GSYM/LineTable.h"
@@ -21,6 +22,34 @@
using namespace llvm;
using namespace gsym;
+// Keep this matching cheap: Itanium and Swift both encode identifiers as
+// <length><identifier> in the raw mangled name. Look for that token instead of
+// demangling during finalize().
+static bool isSupportedMangledPrefix(StringRef Name) {
+ return Name.starts_with("_Z") || Name.starts_with("$s") ||
+ Name.starts_with("$S");
+}
+
+static bool shouldReplaceWithMangledName(StringRef AlternateName,
+ StringRef CurrentName) {
+ // Any name is better than no name.
+ if (CurrentName.empty() && !AlternateName.empty())
+ return true;
+
+ // Keep the current name if it's already mangled, or if the alternate name
+ // is not a supported mangled name.
+ if (isSupportedMangledPrefix(CurrentName) ||
+ !isSupportedMangledPrefix(AlternateName))
+ return false;
+
+ // Confirm the alternate mangled name actually contains the current name as
+ // an Itanium/Swift identifier token (<length><identifier>).
+ SmallString<64> LengthAndName;
+ raw_svector_ostream OS(LengthAndName);
+ OS << CurrentName.size() << CurrentName;
+ return AlternateName.contains(StringRef(LengthAndName));
+}
+
GsymCreator::GsymCreator(bool Quiet)
: StrTab(StringTableBuilder::ELF), Quiet(Quiet) {
insertFile(StringRef());
@@ -180,14 +209,25 @@ llvm::Error GsymCreator::finalize(OutputAggregator &Out) {
if (ranges_equal || Prev.Range.intersects(Curr.Range)) {
// Overlapping ranges or empty identical ranges.
if (ranges_equal) {
- // Same address range. Check if one is from debug
- // info and the other is from a symbol table. If
- // so, then keep the one with debug info. Our
- // sorting guarantees that entries with matching
- // address ranges that have debug info are last in
- // the sort.
- if (!(Prev == Curr)) {
- if (Prev.hasRichInfo() && Curr.hasRichInfo())
+ // Same address range. When exactly one entry has rich info (line
+ // table, inline info, or call sites), keep that entry. DWARF often
+ // truncates a function's linkage name to its short form, so before
+ // dropping the non-rich symbol-table entry, check whether its name
+ // is a more complete mangled (Itanium or Swift) form of the rich
+ // entry's name and, if so, copy it onto the rich entry. This lets
+ // downstream tools demangle the full signature.
+ const bool PrevRich = Prev.hasRichInfo();
+ const bool CurrRich = Curr.hasRichInfo();
+ if (PrevRich != CurrRich) {
+ FunctionInfo &RichFI = PrevRich ? Prev : Curr;
+ FunctionInfo &NonRichFI = PrevRich ? Curr : Prev;
+ if (shouldReplaceWithMangledName(getString(NonRichFI.Name),
+ getString(RichFI.Name)))
+ RichFI.Name = NonRichFI.Name;
+ if (!PrevRich)
+ std::swap(Prev, Curr);
+ } else if (Prev != Curr) {
+ if (PrevRich)
Out.Report(
"Duplicate address ranges with different debug info.",
[&](raw_ostream &OS) {
@@ -197,10 +237,6 @@ llvm::Error GsymCreator::finalize(OutputAggregator &Out) {
<< Prev << "\nIn favor of this one:\n"
<< Curr << "\n";
});
-
- // We want to swap the current entry with the previous since
- // later entries with the same range always have more debug info
- // or different debug info.
std::swap(Prev, Curr);
}
} else {
diff --git a/llvm/test/tools/llvm-gsymutil/X86/elf-mangled-name-replacement.yaml b/llvm/test/tools/llvm-gsymutil/X86/elf-mangled-name-replacement.yaml
new file mode 100644
index 0000000000000..0ad50e2e3e218
--- /dev/null
+++ b/llvm/test/tools/llvm-gsymutil/X86/elf-mangled-name-replacement.yaml
@@ -0,0 +1,128 @@
+## Test that same-range dedup keeps the DWARF line table while replacing a
+## shortened DWARF function name with the full Itanium symbol-table name.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-gsymutil --convert %t -o %t.gsym 2>&1 | FileCheck %s --check-prefix=CONVERT
+# RUN: llvm-gsymutil %t.gsym 2>&1 | FileCheck %s --check-prefix=DUMP
+
+# CONVERT: Loaded 1 functions from DWARF.
+# CONVERT: Loaded 1 functions from symbol table.
+# CONVERT: Pruned 1 functions, ended with 1 total
+
+# DUMP: "_Z10make_ftypePci"
+# DUMP: LineTable:
+# DUMP: main.cpp:10
+# DUMP: main.cpp:11
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000401000
+ AddressAlign: 0x10
+ Content: 554889E531C05DC3554889E531C05DC3
+DWARF:
+ debug_str:
+ - ''
+ - main.cpp
+ - make_ftype
+ debug_abbrev:
+ - ID: 0
+ Table:
+ - Code: 0x1
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_language
+ Form: DW_FORM_udata
+ - Attribute: DW_AT_stmt_list
+ Form: DW_FORM_sec_offset
+ - Code: 0x2
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_addr
+ debug_info:
+ - Length: 0x27
+ Version: 4
+ AbbrevTableID: 0
+ AbbrOffset: 0x0
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x1
+ Values:
+ - Value: 0x1
+ - Value: 0x2
+ - Value: 0x0
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0xA
+ - Value: 0x401000
+ - Value: 0x401010
+ - AbbrCode: 0x0
+ debug_line:
+ - Length: 61
+ Version: 2
+ PrologueLength: 31
+ MinInstLength: 1
+ DefaultIsStmt: 1
+ LineBase: 251
+ LineRange: 14
+ OpcodeBase: 13
+ StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+ Files:
+ - Name: main.cpp
+ DirIdx: 0
+ ModTime: 0
+ Length: 0
+ Opcodes:
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 9
+ SubOpcode: DW_LNE_set_address
+ Data: 4198400
+ - Opcode: DW_LNS_advance_line
+ SData: 9
+ Data: 0
+ - Opcode: DW_LNS_copy
+ Data: 0
+ - Opcode: DW_LNS_advance_pc
+ Data: 8
+ - Opcode: DW_LNS_advance_line
+ SData: 1
+ Data: 0
+ - Opcode: DW_LNS_copy
+ Data: 0
+ - Opcode: DW_LNS_advance_pc
+ Data: 8
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 1
+ SubOpcode: DW_LNE_end_sequence
+ Data: 0
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ VAddr: 0x0000000000400000
+ Align: 0x1000
+ FirstSec: .text
+ LastSec: .text
+Symbols:
+ - Name: _Z10make_ftypePci
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x0000000000401000
+ Size: 0x0000000000000010
+...
diff --git a/llvm/test/tools/llvm-gsymutil/X86/elf-swift-mangled-name-replacement.yaml b/llvm/test/tools/llvm-gsymutil/X86/elf-swift-mangled-name-replacement.yaml
new file mode 100644
index 0000000000000..b706f890c6c35
--- /dev/null
+++ b/llvm/test/tools/llvm-gsymutil/X86/elf-swift-mangled-name-replacement.yaml
@@ -0,0 +1,128 @@
+## Test that same-range dedup keeps the DWARF line table while replacing a
+## shortened Swift DWARF function name with the full Swift symbol-table name.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-gsymutil --convert %t -o %t.gsym 2>&1 | FileCheck %s --check-prefix=CONVERT
+# RUN: llvm-gsymutil %t.gsym 2>&1 | FileCheck %s --check-prefix=DUMP
+
+# CONVERT: Loaded 1 functions from DWARF.
+# CONVERT: Loaded 1 functions from symbol table.
+# CONVERT: Pruned 1 functions, ended with 1 total
+
+# DUMP: "$s4main10make_ftypeyyF"
+# DUMP: LineTable:
+# DUMP: main.swift:10
+# DUMP: main.swift:11
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000401000
+ AddressAlign: 0x10
+ Content: 554889E531C05DC3554889E531C05DC3
+DWARF:
+ debug_str:
+ - ''
+ - main.swift
+ - make_ftype
+ debug_abbrev:
+ - ID: 0
+ Table:
+ - Code: 0x1
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_language
+ Form: DW_FORM_udata
+ - Attribute: DW_AT_stmt_list
+ Form: DW_FORM_sec_offset
+ - Code: 0x2
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_addr
+ debug_info:
+ - Length: 0x27
+ Version: 4
+ AbbrevTableID: 0
+ AbbrOffset: 0x0
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x1
+ Values:
+ - Value: 0x1
+ - Value: 0x1E
+ - Value: 0x0
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0xC
+ - Value: 0x401000
+ - Value: 0x401010
+ - AbbrCode: 0x0
+ debug_line:
+ - Length: 63
+ Version: 2
+ PrologueLength: 33
+ MinInstLength: 1
+ DefaultIsStmt: 1
+ LineBase: 251
+ LineRange: 14
+ OpcodeBase: 13
+ StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+ Files:
+ - Name: main.swift
+ DirIdx: 0
+ ModTime: 0
+ Length: 0
+ Opcodes:
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 9
+ SubOpcode: DW_LNE_set_address
+ Data: 4198400
+ - Opcode: DW_LNS_advance_line
+ SData: 9
+ Data: 0
+ - Opcode: DW_LNS_copy
+ Data: 0
+ - Opcode: DW_LNS_advance_pc
+ Data: 8
+ - Opcode: DW_LNS_advance_line
+ SData: 1
+ Data: 0
+ - Opcode: DW_LNS_copy
+ Data: 0
+ - Opcode: DW_LNS_advance_pc
+ Data: 8
+ - Opcode: DW_LNS_extended_op
+ ExtLen: 1
+ SubOpcode: DW_LNE_end_sequence
+ Data: 0
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ VAddr: 0x0000000000400000
+ Align: 0x1000
+ FirstSec: .text
+ LastSec: .text
+Symbols:
+ - Name: '$s4main10make_ftypeyyF'
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x0000000000401000
+ Size: 0x0000000000000010
+...
diff --git a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
index 299e19e3c896e..b937dabd927aa 100644
--- a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
+++ b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
@@ -2813,6 +2813,145 @@ FinalizeEncodeAndDecode(GsymCreator &GC) {
return GsymReader::copyBuffer(OutStrm.str());
}
+template <typename CreatorT>
+static void AddDuplicateRangePair(CreatorT &GC, uint64_t Addr,
+ gsym_strp_t RichName, gsym_strp_t NonRichName,
+ bool AddRichFirst, uint32_t FileIdx,
+ uint32_t FirstLine) {
+ FunctionInfo RichFI(Addr, 0x20, RichName);
+ RichFI.OptLineTable = LineTable();
+ RichFI.OptLineTable->push(LineEntry(Addr, FileIdx, FirstLine));
+ RichFI.OptLineTable->push(LineEntry(Addr + 0x10, FileIdx, FirstLine + 1));
+
+ FunctionInfo NonRichFI(Addr, 0x20, NonRichName);
+ if (AddRichFirst) {
+ GC.addFunctionInfo(std::move(RichFI));
+ GC.addFunctionInfo(std::move(NonRichFI));
+ } else {
+ GC.addFunctionInfo(std::move(NonRichFI));
+ GC.addFunctionInfo(std::move(RichFI));
+ }
+}
+
+static void VerifyDuplicateRangeResult(const GsymReader &GR, uint64_t Addr,
+ StringRef ExpectedName,
+ uint32_t ExpectedFileIdx,
+ uint32_t FirstLine) {
+ auto ExpFI = GR.getFunctionInfo(Addr);
+ ASSERT_THAT_EXPECTED(ExpFI, Succeeded());
+ EXPECT_EQ(GR.getString(ExpFI->Name), ExpectedName);
+ ASSERT_TRUE(ExpFI->OptLineTable.has_value());
+ ASSERT_EQ(ExpFI->OptLineTable->size(), 2u);
+ EXPECT_EQ((*ExpFI->OptLineTable)[0],
+ LineEntry(Addr, ExpectedFileIdx, FirstLine));
+ EXPECT_EQ((*ExpFI->OptLineTable)[1],
+ LineEntry(Addr + 0x10, ExpectedFileIdx, FirstLine + 1));
+}
+
+template <typename CreatorT> static void TestMangledNameReplacement() {
+ CreatorT GC;
+ const uint32_t FileIdx = GC.insertFile("/tmp/main.cpp");
+ const gsym_strp_t ShortName = GC.insertString("make_ftype");
+ const gsym_strp_t MangledName = GC.insertString("_Z10make_ftypePci");
+ const gsym_strp_t SwiftMangledName =
+ GC.insertString("$s4main10make_ftypeyyF");
+
+ AddDuplicateRangePair(GC, 0x1000, ShortName, MangledName,
+ /*AddRichFirst=*/false, FileIdx, 10);
+ AddDuplicateRangePair(GC, 0x2000, ShortName, MangledName,
+ /*AddRichFirst=*/true, FileIdx, 20);
+ AddDuplicateRangePair(GC, 0x3000, ShortName, SwiftMangledName,
+ /*AddRichFirst=*/false, FileIdx, 30);
+
+ auto GROrErr = FinalizeEncodeAndDecode(GC);
+ ASSERT_THAT_EXPECTED(GROrErr, Succeeded());
+ const std::unique_ptr<GsymReader> &GR = *GROrErr;
+
+ EXPECT_EQ(GR->getNumAddresses(), 3u);
+ VerifyDuplicateRangeResult(*GR, 0x1000, "_Z10make_ftypePci", FileIdx, 10);
+ VerifyDuplicateRangeResult(*GR, 0x2000, "_Z10make_ftypePci", FileIdx, 20);
+ VerifyDuplicateRangeResult(*GR, 0x3000, "$s4main10make_ftypeyyF", FileIdx,
+ 30);
+}
+
+TEST(GSYMTest, TestMangledNameReplacement) {
+ TestMangledNameReplacement<GsymCreatorV1>();
+}
+TEST(GSYMTest, TestMangledNameReplacementV2) {
+ TestMangledNameReplacement<GsymCreatorV2>();
+}
+
+template <typename CreatorT> static void TestMangledNameReplacementNegative() {
+ CreatorT GC;
+ const uint32_t FileIdx = GC.insertFile("/tmp/test.cpp");
+ const gsym_strp_t MangledA = GC.insertString("_Z3foov");
+ const gsym_strp_t MangledB = GC.insertString("_Z3barv");
+ const gsym_strp_t MangledName = GC.insertString("_Z10make_ftypePci");
+ const gsym_strp_t UnrelatedName = GC.insertString("some_other_func");
+ const gsym_strp_t SwiftShortName = GC.insertString("foo");
+ const gsym_strp_t SwiftLongerName = GC.insertString("$s5fooBaryyF");
+
+ AddDuplicateRangePair(GC, 0x3000, MangledB, MangledA,
+ /*AddRichFirst=*/false, FileIdx, 5);
+ AddDuplicateRangePair(GC, 0x4000, UnrelatedName, MangledName,
+ /*AddRichFirst=*/false, FileIdx, 15);
+ AddDuplicateRangePair(GC, 0x5000, SwiftShortName, SwiftLongerName,
+ /*AddRichFirst=*/false, FileIdx, 25);
+
+ auto GROrErr = FinalizeEncodeAndDecode(GC);
+ ASSERT_THAT_EXPECTED(GROrErr, Succeeded());
+ const std::unique_ptr<GsymReader> &GR = *GROrErr;
+
+ EXPECT_EQ(GR->getNumAddresses(), 3u);
+ VerifyDuplicateRangeResult(*GR, 0x3000, "_Z3barv", FileIdx, 5);
+ VerifyDuplicateRangeResult(*GR, 0x4000, "some_other_func", FileIdx, 15);
+ VerifyDuplicateRangeResult(*GR, 0x5000, "foo", FileIdx, 25);
+}
+
+TEST(GSYMTest, TestMangledNameReplacementNegative) {
+ TestMangledNameReplacementNegative<GsymCreatorV1>();
+}
+TEST(GSYMTest, TestMangledNameReplacementNegativeV2) {
+ TestMangledNameReplacementNegative<GsymCreatorV2>();
+}
+
+template <typename CreatorT> static void TestDuplicateRangeKeepsCallSites() {
+ CreatorT GC;
+ const gsym_strp_t FuncName = GC.insertString("foo");
+ const gsym_strp_t MatchRegex = GC.insertString("callee");
+
+ FunctionInfo NonRichFI(0x5000, 0x20, FuncName);
+ FunctionInfo RichFI(0x5000, 0x20, FuncName);
+ RichFI.CallSites = CallSiteInfoCollection();
+ CallSiteInfo CSI;
+ CSI.ReturnOffset = 0x10;
+ CSI.MatchRegex.push_back(MatchRegex);
+ RichFI.CallSites->CallSites.push_back(CSI);
+
+ GC.addFunctionInfo(std::move(NonRichFI));
+ GC.addFunctionInfo(std::move(RichFI));
+
+ auto GROrErr = FinalizeEncodeAndDecode(GC);
+ ASSERT_THAT_EXPECTED(GROrErr, Succeeded());
+ const std::unique_ptr<GsymReader> &GR = *GROrErr;
+
+ auto ExpFI = GR->getFunctionInfo(0x5000);
+ ASSERT_THAT_EXPECTED(ExpFI, Succeeded());
+ ASSERT_TRUE(ExpFI->CallSites.has_value());
+ ASSERT_EQ(ExpFI->CallSites->CallSites.size(), 1u);
+ EXPECT_EQ(ExpFI->CallSites->CallSites[0].ReturnOffset, 0x10u);
+ ASSERT_EQ(ExpFI->CallSites->CallSites[0].MatchRegex.size(), 1u);
+ EXPECT_EQ(GR->getString(ExpFI->CallSites->CallSites[0].MatchRegex[0]),
+ "callee");
+}
+
+TEST(GSYMTest, TestDuplicateRangeKeepsCallSites) {
+ TestDuplicateRangeKeepsCallSites<GsymCreatorV1>();
+}
+TEST(GSYMTest, TestDuplicateRangeKeepsCallSitesV2) {
+ TestDuplicateRangeKeepsCallSites<GsymCreatorV2>();
+}
+
template <typename CreatorT>
static void TestGsymSegmenting(uint64_t SegmentSize) {
// Test creating a GSYM file with function infos and segment the information.
More information about the llvm-commits
mailing list