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