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