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