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