1 //===-- Mangled.cpp ---------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 // FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
12 #include <cstddef>
13 #if defined(_MSC_VER)
14 #include "lldb/Host/windows/windows.h"
15 #include <Dbghelp.h>
16 #pragma comment(lib, "dbghelp.lib")
17 #define LLDB_USE_BUILTIN_DEMANGLER
18 #elif defined (__FreeBSD__)
19 #define LLDB_USE_BUILTIN_DEMANGLER
20 #else
21 #include <cxxabi.h>
22 #endif
23 
24 #ifdef LLDB_USE_BUILTIN_DEMANGLER
25 
26 // Provide a fast-path demangler implemented in FastDemangle.cpp until it can
27 // replace the existing C++ demangler with a complete implementation
28 #include "lldb/Core/FastDemangle.h"
29 #include "lldb/Core/CxaDemangle.h"
30 
31 #endif
32 
33 
34 #include "llvm/ADT/DenseMap.h"
35 
36 #include "lldb/Core/ConstString.h"
37 #include "lldb/Core/Mangled.h"
38 #include "lldb/Core/RegularExpression.h"
39 #include "lldb/Core/Stream.h"
40 #include "lldb/Core/Timer.h"
41 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
42 #include "Plugins/Language/ObjC/ObjCLanguage.h"
43 #include <ctype.h>
44 #include <string.h>
45 #include <stdlib.h>
46 
47 
48 using namespace lldb_private;
49 
50 static inline Mangled::ManglingScheme
51 cstring_mangling_scheme(const char *s)
52 {
53     if (s)
54     {
55         if (s[0] == '?')
56             return Mangled::eManglingSchemeMSVC;
57         if (s[0] == '_' && s[1] == 'Z')
58             return Mangled::eManglingSchemeItanium;
59     }
60     return Mangled::eManglingSchemeNone;
61 }
62 
63 static inline bool
64 cstring_is_mangled(const char *s)
65 {
66     return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
67 }
68 
69 static const ConstString &
70 get_demangled_name_without_arguments (ConstString mangled, ConstString demangled)
71 {
72     // This pair is <mangled name, demangled name without function arguments>
73     static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;
74 
75     // Need to have the mangled & demangled names we're currently examining as statics
76     // so we can return a const ref to them at the end of the func if we don't have
77     // anything better.
78     static ConstString g_last_mangled;
79     static ConstString g_last_demangled;
80 
81     if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
82     {
83         return g_most_recent_mangled_to_name_sans_args.second;
84     }
85 
86     g_last_demangled = demangled;
87     g_last_mangled = mangled;
88 
89     const char *mangled_name_cstr = mangled.GetCString();
90 
91     if (demangled && mangled_name_cstr && mangled_name_cstr[0])
92     {
93         if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
94             (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
95             mangled_name_cstr[2] != 'G' && // avoid guard variables
96             mangled_name_cstr[2] != 'Z'))  // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
97         {
98             CPlusPlusLanguage::MethodName cxx_method (demangled);
99             if (!cxx_method.GetBasename().empty())
100             {
101                 std::string shortname;
102                 if (!cxx_method.GetContext().empty())
103                     shortname = cxx_method.GetContext().str() + "::";
104                 shortname += cxx_method.GetBasename().str();
105                 ConstString result(shortname.c_str());
106                 g_most_recent_mangled_to_name_sans_args.first = mangled;
107                 g_most_recent_mangled_to_name_sans_args.second = result;
108                 return g_most_recent_mangled_to_name_sans_args.second;
109             }
110         }
111     }
112 
113     if (demangled)
114         return g_last_demangled;
115     return g_last_mangled;
116 }
117 
118 #pragma mark Mangled
119 //----------------------------------------------------------------------
120 // Default constructor
121 //----------------------------------------------------------------------
122 Mangled::Mangled () :
123     m_mangled(),
124     m_demangled()
125 {
126 }
127 
128 //----------------------------------------------------------------------
129 // Constructor with an optional string and a boolean indicating if it is
130 // the mangled version.
131 //----------------------------------------------------------------------
132 Mangled::Mangled (const ConstString &s, bool mangled) :
133     m_mangled(),
134     m_demangled()
135 {
136     if (s)
137         SetValue(s, mangled);
138 }
139 
140 Mangled::Mangled (const ConstString &s) :
141     m_mangled(),
142     m_demangled()
143 {
144     if (s)
145         SetValue(s);
146 }
147 
148 //----------------------------------------------------------------------
149 // Destructor
150 //----------------------------------------------------------------------
151 Mangled::~Mangled ()
152 {
153 }
154 
155 //----------------------------------------------------------------------
156 // Convert to pointer operator. This allows code to check any Mangled
157 // objects to see if they contain anything valid using code such as:
158 //
159 //  Mangled mangled(...);
160 //  if (mangled)
161 //  { ...
162 //----------------------------------------------------------------------
163 Mangled::operator void* () const
164 {
165     return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
166 }
167 
168 //----------------------------------------------------------------------
169 // Logical NOT operator. This allows code to check any Mangled
170 // objects to see if they are invalid using code such as:
171 //
172 //  Mangled mangled(...);
173 //  if (!file_spec)
174 //  { ...
175 //----------------------------------------------------------------------
176 bool
177 Mangled::operator! () const
178 {
179     return !m_mangled;
180 }
181 
182 //----------------------------------------------------------------------
183 // Clear the mangled and demangled values.
184 //----------------------------------------------------------------------
185 void
186 Mangled::Clear ()
187 {
188     m_mangled.Clear();
189     m_demangled.Clear();
190 }
191 
192 
193 //----------------------------------------------------------------------
194 // Compare the string values.
195 //----------------------------------------------------------------------
196 int
197 Mangled::Compare (const Mangled& a, const Mangled& b)
198 {
199     return ConstString::Compare(a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
200 }
201 
202 
203 
204 //----------------------------------------------------------------------
205 // Set the string value in this objects. If "mangled" is true, then
206 // the mangled named is set with the new value in "s", else the
207 // demangled name is set.
208 //----------------------------------------------------------------------
209 void
210 Mangled::SetValue (const ConstString &s, bool mangled)
211 {
212     if (s)
213     {
214         if (mangled)
215         {
216             m_demangled.Clear();
217             m_mangled = s;
218         }
219         else
220         {
221             m_demangled = s;
222             m_mangled.Clear();
223         }
224     }
225     else
226     {
227         m_demangled.Clear();
228         m_mangled.Clear();
229     }
230 }
231 
232 void
233 Mangled::SetValue (const ConstString &name)
234 {
235     if (name)
236     {
237         if (cstring_is_mangled(name.GetCString()))
238         {
239             m_demangled.Clear();
240             m_mangled = name;
241         }
242         else
243         {
244             m_demangled = name;
245             m_mangled.Clear();
246         }
247     }
248     else
249     {
250         m_demangled.Clear();
251         m_mangled.Clear();
252     }
253 }
254 
255 //----------------------------------------------------------------------
256 // Generate the demangled name on demand using this accessor. Code in
257 // this class will need to use this accessor if it wishes to decode
258 // the demangled name. The result is cached and will be kept until a
259 // new string value is supplied to this object, or until the end of the
260 // object's lifetime.
261 //----------------------------------------------------------------------
262 const ConstString&
263 Mangled::GetDemangledName (lldb::LanguageType language) const
264 {
265     // Check to make sure we have a valid mangled name and that we
266     // haven't already decoded our mangled name.
267     if (m_mangled && !m_demangled)
268     {
269         // We need to generate and cache the demangled name.
270         Timer scoped_timer (__PRETTY_FUNCTION__,
271                             "Mangled::GetDemangledName (m_mangled = %s)",
272                             m_mangled.GetCString());
273 
274         // Don't bother running anything that isn't mangled
275         const char *mangled_name = m_mangled.GetCString();
276         ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
277         if (mangling_scheme != eManglingSchemeNone &&
278             !m_mangled.GetMangledCounterpart(m_demangled))
279         {
280             // We didn't already mangle this name, demangle it and if all goes well
281             // add it to our map.
282             char *demangled_name = nullptr;
283             switch (mangling_scheme)
284             {
285                 case eManglingSchemeMSVC:
286                 {
287 #if defined(_MSC_VER)
288                     const size_t demangled_length = 2048;
289                     demangled_name = static_cast<char *>(::malloc(demangled_length));
290                     ::ZeroMemory(demangled_name, demangled_length);
291                     DWORD result = ::UnDecorateSymbolName(mangled_name, demangled_name, demangled_length,
292                             UNDNAME_NO_ACCESS_SPECIFIERS   | // Strip public, private, protected keywords
293                             UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords
294                             UNDNAME_NO_THROW_SIGNATURES    | // Strip throw() specifications
295                             UNDNAME_NO_MEMBER_TYPE         | // Strip virtual, static, etc specifiers
296                             UNDNAME_NO_MS_KEYWORDS           // Strip all MS extension keywords
297                         );
298                     if (result == 0)
299                     {
300                         free(demangled_name);
301                         demangled_name = nullptr;
302                     }
303 #endif
304                     break;
305                 }
306                 case eManglingSchemeItanium:
307                 {
308 #ifdef LLDB_USE_BUILTIN_DEMANGLER
309                     // Try to use the fast-path demangler first for the
310                     // performance win, falling back to the full demangler only
311                     // when necessary
312                     demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
313                     if (!demangled_name)
314                         demangled_name = __cxa_demangle(mangled_name, NULL, NULL, NULL);
315 #else
316                     demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
317 #endif
318                     break;
319                 }
320                 case eManglingSchemeNone:
321                     break;
322             }
323             if (demangled_name)
324             {
325                 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
326                 free(demangled_name);
327             }
328         }
329         if (!m_demangled)
330         {
331             // Set the demangled string to the empty string to indicate we
332             // tried to parse it once and failed.
333             m_demangled.SetCString("");
334         }
335     }
336 
337     return m_demangled;
338 }
339 
340 
341 ConstString
342 Mangled::GetDisplayDemangledName (lldb::LanguageType language) const
343 {
344     return GetDemangledName(language);
345 }
346 
347 bool
348 Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType language) const
349 {
350     if (m_mangled && regex.Execute (m_mangled.AsCString()))
351         return true;
352 
353     ConstString demangled = GetDemangledName(language);
354     if (demangled && regex.Execute (demangled.AsCString()))
355         return true;
356     return false;
357 }
358 
359 //----------------------------------------------------------------------
360 // Get the demangled name if there is one, else return the mangled name.
361 //----------------------------------------------------------------------
362 ConstString
363 Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preference) const
364 {
365     if (preference == ePreferMangled && m_mangled)
366         return m_mangled;
367 
368     ConstString demangled = GetDemangledName(language);
369 
370     if (preference == ePreferDemangledWithoutArguments)
371     {
372         return get_demangled_name_without_arguments (m_mangled, demangled);
373     }
374     if (preference == ePreferDemangled)
375     {
376         // Call the accessor to make sure we get a demangled name in case
377         // it hasn't been demangled yet...
378         if (demangled)
379             return demangled;
380         return m_mangled;
381     }
382     return demangled;
383 }
384 
385 //----------------------------------------------------------------------
386 // Dump a Mangled object to stream "s". We don't force our
387 // demangled name to be computed currently (we don't use the accessor).
388 //----------------------------------------------------------------------
389 void
390 Mangled::Dump (Stream *s) const
391 {
392     if (m_mangled)
393     {
394         *s << ", mangled = " << m_mangled;
395     }
396     if (m_demangled)
397     {
398         const char * demangled = m_demangled.AsCString();
399         s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
400     }
401 }
402 
403 //----------------------------------------------------------------------
404 // Dumps a debug version of this string with extra object and state
405 // information to stream "s".
406 //----------------------------------------------------------------------
407 void
408 Mangled::DumpDebug (Stream *s) const
409 {
410     s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),
411               static_cast<const void*>(this));
412     m_mangled.DumpDebug(s);
413     s->Printf(", demangled = ");
414     m_demangled.DumpDebug(s);
415 }
416 
417 //----------------------------------------------------------------------
418 // Return the size in byte that this object takes in memory. The size
419 // includes the size of the objects it owns, and not the strings that
420 // it references because they are shared strings.
421 //----------------------------------------------------------------------
422 size_t
423 Mangled::MemorySize () const
424 {
425     return m_mangled.MemorySize() + m_demangled.MemorySize();
426 }
427 
428 //----------------------------------------------------------------------
429 // We "guess" the language because we can't determine a symbol's language
430 // from it's name.  For example, a Pascal symbol can be mangled using the
431 // C++ Itanium scheme, and defined in a compilation unit within the same
432 // module as other C++ units.  In addition, different targets could have
433 // different ways of mangling names from a given language, likewise the
434 // compilation units within those targets.
435 //----------------------------------------------------------------------
436 lldb::LanguageType
437 Mangled::GuessLanguage () const
438 {
439     ConstString mangled = GetMangledName();
440     if (mangled)
441     {
442         if (GetDemangledName(lldb::eLanguageTypeUnknown))
443         {
444             const char *mangled_name = mangled.GetCString();
445             if (CPlusPlusLanguage::IsCPPMangledName(mangled_name))
446                 return lldb::eLanguageTypeC_plus_plus;
447             else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
448                 return lldb::eLanguageTypeObjC;
449         }
450     }
451     return lldb::eLanguageTypeUnknown;
452 }
453 
454 //----------------------------------------------------------------------
455 // Dump OBJ to the supplied stream S.
456 //----------------------------------------------------------------------
457 Stream&
458 operator << (Stream& s, const Mangled& obj)
459 {
460     if (obj.GetMangledName())
461         s << "mangled = '" << obj.GetMangledName() << "'";
462 
463     const ConstString& demangled = obj.GetDemangledName(lldb::eLanguageTypeUnknown);
464     if (demangled)
465         s << ", demangled = '" << demangled << '\'';
466     else
467         s << ", demangled = <error>";
468     return s;
469 }
470