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