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