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