xref: /llvm-project/lldb/unittests/Core/MangledTest.cpp (revision 1ad655e255090620705eb4ce85d869a54d971912)
1 //===-- MangledTest.cpp -----------------------------------------*- 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 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
10 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
11 #include "TestingSupport/TestUtilities.h"
12 
13 #include "lldb/Core/Mangled.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Host/FileSystem.h"
17 #include "lldb/Host/HostInfo.h"
18 #include "lldb/Symbol/SymbolContext.h"
19 
20 #include "llvm/Support/FileUtilities.h"
21 #include "llvm/Support/Path.h"
22 #include "llvm/Support/Program.h"
23 #include "llvm/Testing/Support/Error.h"
24 
25 #include "gtest/gtest.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 TEST(MangledTest, ResultForValidName) {
31   ConstString MangledName("_ZN1a1b1cIiiiEEvm");
32   Mangled TheMangled(MangledName);
33   ConstString TheDemangled =
34       TheMangled.GetDemangledName(eLanguageTypeC_plus_plus);
35 
36   ConstString ExpectedResult("void a::b::c<int, int, int>(unsigned long)");
37   EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());
38 }
39 
40 TEST(MangledTest, EmptyForInvalidName) {
41   ConstString MangledName("_ZN1a1b1cmxktpEEvm");
42   Mangled TheMangled(MangledName);
43   ConstString TheDemangled =
44       TheMangled.GetDemangledName(eLanguageTypeC_plus_plus);
45 
46   EXPECT_STREQ("", TheDemangled.GetCString());
47 }
48 
49 TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
50   FileSystem::Initialize();
51   HostInfo::Initialize();
52   ObjectFileELF::Initialize();
53   SymbolFileSymtab::Initialize();
54 
55   auto ExpectedFile = TestFile::fromYaml(R"(
56 --- !ELF
57 FileHeader:
58   Class:           ELFCLASS64
59   Data:            ELFDATA2LSB
60   Type:            ET_EXEC
61   Machine:         EM_X86_64
62 Sections:
63   - Name:            .text
64     Type:            SHT_PROGBITS
65     Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
66     AddressAlign:    0x0000000000000010
67     Size:            0x20
68   - Name:            .anothertext
69     Type:            SHT_PROGBITS
70     Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
71     Address:         0x0000000000000010
72     AddressAlign:    0x0000000000000010
73     Size:            0x40
74   - Name:            .data
75     Type:            SHT_PROGBITS
76     Flags:           [ SHF_WRITE, SHF_ALLOC ]
77     Address:         0x00000000000000A8
78     AddressAlign:    0x0000000000000004
79     Content:         '01000000'
80 Symbols:
81   - Name:            somedata
82     Type:            STT_OBJECT
83     Section:         .anothertext
84     Value:           0x0000000000000045
85     Binding:         STB_GLOBAL
86   - Name:            main
87     Type:            STT_FUNC
88     Section:         .anothertext
89     Value:           0x0000000000000010
90     Size:            0x000000000000003F
91     Binding:         STB_GLOBAL
92   - Name:            _Z3foov
93     Type:            STT_FUNC
94     Section:         .text
95     Size:            0x000000000000000D
96     Binding:         STB_GLOBAL
97   - Name:            puts@GLIBC_2.5
98     Type:            STT_FUNC
99     Section:         .text
100     Size:            0x000000000000000D
101     Binding:         STB_GLOBAL
102   - Name:            puts@GLIBC_2.6
103     Type:            STT_FUNC
104     Section:         .text
105     Size:            0x000000000000000D
106     Binding:         STB_GLOBAL
107   - Name:            _Z5annotv@VERSION3
108     Type:            STT_FUNC
109     Section:         .text
110     Size:            0x000000000000000D
111     Binding:         STB_GLOBAL
112   - Name:            _ZN1AC2Ev
113     Type:            STT_FUNC
114     Section:         .text
115     Size:            0x000000000000000D
116     Binding:         STB_GLOBAL
117   - Name:            _ZN1AD2Ev
118     Type:            STT_FUNC
119     Section:         .text
120     Size:            0x000000000000000D
121     Binding:         STB_GLOBAL
122   - Name:            _ZN1A3barEv
123     Type:            STT_FUNC
124     Section:         .text
125     Size:            0x000000000000000D
126     Binding:         STB_GLOBAL
127   - Name:            _ZGVZN4llvm4dbgsEvE7thestrm
128     Type:            STT_FUNC
129     Section:         .text
130     Size:            0x000000000000000D
131     Binding:         STB_GLOBAL
132   - Name:            _ZZN4llvm4dbgsEvE7thestrm
133     Type:            STT_FUNC
134     Section:         .text
135     Size:            0x000000000000000D
136     Binding:         STB_GLOBAL
137   - Name:            _ZTVN5clang4DeclE
138     Type:            STT_FUNC
139     Section:         .text
140     Size:            0x000000000000000D
141     Binding:         STB_GLOBAL
142   - Name:            -[ObjCfoo]
143     Type:            STT_FUNC
144     Section:         .text
145     Size:            0x000000000000000D
146     Binding:         STB_GLOBAL
147   - Name:            +[B ObjCbar(WithCategory)]
148     Type:            STT_FUNC
149     Section:         .text
150     Size:            0x000000000000000D
151     Binding:         STB_GLOBAL
152   - Name:            _Z12undemangableEvx42
153     Type:            STT_FUNC
154     Section:         .text
155     Size:            0x000000000000000D
156     Binding:         STB_GLOBAL
157 ...
158 )");
159   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
160 
161   ModuleSpec Spec{FileSpec(ExpectedFile->name())};
162   auto M = std::make_shared<Module>(Spec);
163 
164   auto Count = [M](const char *Name, FunctionNameType Type) -> int {
165     SymbolContextList SymList;
166     M->FindFunctionSymbols(ConstString(Name), Type, SymList);
167     return SymList.GetSize();
168   };
169 
170   // Unmangled
171   EXPECT_EQ(1, Count("main", eFunctionNameTypeFull));
172   EXPECT_EQ(1, Count("main", eFunctionNameTypeBase));
173   EXPECT_EQ(0, Count("main", eFunctionNameTypeMethod));
174 
175   // Itanium mangled
176   EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeFull));
177   EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeBase));
178   EXPECT_EQ(1, Count("foo", eFunctionNameTypeBase));
179   EXPECT_EQ(0, Count("foo", eFunctionNameTypeMethod));
180 
181   // Unmangled with linker annotation
182   EXPECT_EQ(1, Count("puts@GLIBC_2.5", eFunctionNameTypeFull));
183   EXPECT_EQ(1, Count("puts@GLIBC_2.6", eFunctionNameTypeFull));
184   EXPECT_EQ(2, Count("puts", eFunctionNameTypeFull));
185   EXPECT_EQ(2, Count("puts", eFunctionNameTypeBase));
186   EXPECT_EQ(0, Count("puts", eFunctionNameTypeMethod));
187 
188   // Itanium mangled with linker annotation
189   EXPECT_EQ(1, Count("_Z5annotv@VERSION3", eFunctionNameTypeFull));
190   EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeFull));
191   EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeBase));
192   EXPECT_EQ(0, Count("annot", eFunctionNameTypeBase));
193   EXPECT_EQ(0, Count("annot", eFunctionNameTypeMethod));
194 
195   // Itanium mangled ctor A::A()
196   EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeFull));
197   EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeBase));
198   EXPECT_EQ(1, Count("A", eFunctionNameTypeMethod));
199   EXPECT_EQ(0, Count("A", eFunctionNameTypeBase));
200 
201   // Itanium mangled dtor A::~A()
202   EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeFull));
203   EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeBase));
204   EXPECT_EQ(1, Count("~A", eFunctionNameTypeMethod));
205   EXPECT_EQ(0, Count("~A", eFunctionNameTypeBase));
206 
207   // Itanium mangled method A::bar()
208   EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeFull));
209   EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeBase));
210   EXPECT_EQ(1, Count("bar", eFunctionNameTypeMethod));
211   EXPECT_EQ(0, Count("bar", eFunctionNameTypeBase));
212 
213   // Itanium mangled names that are explicitly excluded from parsing
214   EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull));
215   EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase));
216   EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod));
217   EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase));
218   EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull));
219   EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase));
220   EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod));
221   EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase));
222   EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeFull));
223   EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeBase));
224   EXPECT_EQ(0, Count("Decl", eFunctionNameTypeMethod));
225   EXPECT_EQ(0, Count("Decl", eFunctionNameTypeBase));
226 
227   // ObjC mangled static
228   EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeFull));
229   EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeBase));
230   EXPECT_EQ(0, Count("ObjCfoo", eFunctionNameTypeMethod));
231 
232   // ObjC mangled method with category
233   EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeFull));
234   EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeBase));
235   EXPECT_EQ(0, Count("ObjCbar", eFunctionNameTypeMethod));
236 
237   // Invalid things: unable to decode but still possible to find by full name
238   EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeFull));
239   EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeBase));
240   EXPECT_EQ(0, Count("_Z12undemangableEvx42", eFunctionNameTypeMethod));
241   EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeBase));
242   EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeMethod));
243 
244   SymbolFileSymtab::Terminate();
245   ObjectFileELF::Terminate();
246   HostInfo::Terminate();
247   FileSystem::Terminate();
248 }
249