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 #define LLDB_USE_BUILTIN_DEMANGLER 17 #elif defined (__FreeBSD__) 18 #define LLDB_USE_BUILTIN_DEMANGLER 19 #else 20 #include <cxxabi.h> 21 #endif 22 23 #ifdef LLDB_USE_BUILTIN_DEMANGLER 24 25 // Provide a fast-path demangler implemented in FastDemangle.cpp until it can 26 // replace the existing C++ demangler with a complete implementation 27 #include "lldb/Core/FastDemangle.h" 28 #include "lldb/Core/CxaDemangle.h" 29 30 #endif 31 32 33 #include "llvm/ADT/DenseMap.h" 34 35 #include "lldb/Core/ConstString.h" 36 #include "lldb/Core/Mangled.h" 37 #include "lldb/Core/RegularExpression.h" 38 #include "lldb/Core/Stream.h" 39 #include "lldb/Core/Timer.h" 40 #include "lldb/Target/CPPLanguageRuntime.h" 41 #include <ctype.h> 42 #include <string.h> 43 #include <stdlib.h> 44 45 46 using namespace lldb_private; 47 48 static inline Mangled::ManglingScheme 49 cstring_mangling_scheme(const char *s) 50 { 51 if (s) 52 { 53 if (s[0] == '?') 54 return Mangled::eManglingSchemeMSVC; 55 if (s[0] == '_' && s[1] == 'Z') 56 return Mangled::eManglingSchemeItanium; 57 } 58 return Mangled::eManglingSchemeNone; 59 } 60 61 static inline bool 62 cstring_is_mangled(const char *s) 63 { 64 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone; 65 } 66 67 static const ConstString & 68 get_demangled_name_without_arguments (const Mangled *obj) 69 { 70 // This pair is <mangled name, demangled name without function arguments> 71 static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args; 72 73 // Need to have the mangled & demangled names we're currently examining as statics 74 // so we can return a const ref to them at the end of the func if we don't have 75 // anything better. 76 static ConstString g_last_mangled; 77 static ConstString g_last_demangled; 78 79 ConstString mangled = obj->GetMangledName (); 80 ConstString demangled = obj->GetDemangledName (); 81 82 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) 83 { 84 return g_most_recent_mangled_to_name_sans_args.second; 85 } 86 87 g_last_demangled = demangled; 88 g_last_mangled = mangled; 89 90 const char *mangled_name_cstr = mangled.GetCString(); 91 92 if (demangled && mangled_name_cstr && mangled_name_cstr[0]) 93 { 94 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' && 95 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name 96 mangled_name_cstr[2] != 'G' && // avoid guard variables 97 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back) 98 { 99 CPPLanguageRuntime::MethodName cxx_method (demangled); 100 if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty()) 101 { 102 std::string shortname = cxx_method.GetContext().str(); 103 shortname += "::"; 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(ePreferMangled), a.GetName(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 () 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 bool 342 Mangled::NameMatches (const RegularExpression& regex) const 343 { 344 if (m_mangled && regex.Execute (m_mangled.AsCString())) 345 return true; 346 347 if (GetDemangledName() && regex.Execute (m_demangled.AsCString())) 348 return true; 349 return false; 350 } 351 352 //---------------------------------------------------------------------- 353 // Get the demangled name if there is one, else return the mangled name. 354 //---------------------------------------------------------------------- 355 const ConstString& 356 Mangled::GetName (Mangled::NamePreference preference) const 357 { 358 if (preference == ePreferDemangledWithoutArguments) 359 { 360 // Call the accessor to make sure we get a demangled name in case 361 // it hasn't been demangled yet... 362 GetDemangledName(); 363 364 return get_demangled_name_without_arguments (this); 365 } 366 if (preference == ePreferDemangled) 367 { 368 // Call the accessor to make sure we get a demangled name in case 369 // it hasn't been demangled yet... 370 if (GetDemangledName()) 371 return m_demangled; 372 return m_mangled; 373 } 374 else 375 { 376 if (m_mangled) 377 return m_mangled; 378 return GetDemangledName(); 379 } 380 } 381 382 //---------------------------------------------------------------------- 383 // Dump a Mangled object to stream "s". We don't force our 384 // demangled name to be computed currently (we don't use the accessor). 385 //---------------------------------------------------------------------- 386 void 387 Mangled::Dump (Stream *s) const 388 { 389 if (m_mangled) 390 { 391 *s << ", mangled = " << m_mangled; 392 } 393 if (m_demangled) 394 { 395 const char * demangled = m_demangled.AsCString(); 396 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>"); 397 } 398 } 399 400 //---------------------------------------------------------------------- 401 // Dumps a debug version of this string with extra object and state 402 // information to stream "s". 403 //---------------------------------------------------------------------- 404 void 405 Mangled::DumpDebug (Stream *s) const 406 { 407 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2), 408 static_cast<const void*>(this)); 409 m_mangled.DumpDebug(s); 410 s->Printf(", demangled = "); 411 m_demangled.DumpDebug(s); 412 } 413 414 //---------------------------------------------------------------------- 415 // Return the size in byte that this object takes in memory. The size 416 // includes the size of the objects it owns, and not the strings that 417 // it references because they are shared strings. 418 //---------------------------------------------------------------------- 419 size_t 420 Mangled::MemorySize () const 421 { 422 return m_mangled.MemorySize() + m_demangled.MemorySize(); 423 } 424 425 lldb::LanguageType 426 Mangled::GuessLanguage () const 427 { 428 ConstString mangled = GetMangledName(); 429 if (mangled) 430 { 431 if (GetDemangledName()) 432 { 433 if (cstring_is_mangled(mangled.GetCString())) 434 return lldb::eLanguageTypeC_plus_plus; 435 } 436 } 437 return lldb::eLanguageTypeUnknown; 438 } 439 440 //---------------------------------------------------------------------- 441 // Dump OBJ to the supplied stream S. 442 //---------------------------------------------------------------------- 443 Stream& 444 operator << (Stream& s, const Mangled& obj) 445 { 446 if (obj.GetMangledName()) 447 s << "mangled = '" << obj.GetMangledName() << "'"; 448 449 const ConstString& demangled = obj.GetDemangledName(); 450 if (demangled) 451 s << ", demangled = '" << demangled << '\''; 452 else 453 s << ", demangled = <error>"; 454 return s; 455 } 456