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 "lldb/Target/CPPLanguageRuntime.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 CPPLanguageRuntime::MethodName cxx_method (demangled); 98 if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty()) 99 { 100 std::string shortname = cxx_method.GetContext().str(); 101 shortname += "::"; 102 shortname += cxx_method.GetBasename().str(); 103 ConstString result(shortname.c_str()); 104 g_most_recent_mangled_to_name_sans_args.first = mangled; 105 g_most_recent_mangled_to_name_sans_args.second = result; 106 return g_most_recent_mangled_to_name_sans_args.second; 107 } 108 } 109 } 110 111 if (demangled) 112 return g_last_demangled; 113 return g_last_mangled; 114 } 115 116 #pragma mark Mangled 117 //---------------------------------------------------------------------- 118 // Default constructor 119 //---------------------------------------------------------------------- 120 Mangled::Mangled () : 121 m_mangled(), 122 m_demangled() 123 { 124 } 125 126 //---------------------------------------------------------------------- 127 // Constructor with an optional string and a boolean indicating if it is 128 // the mangled version. 129 //---------------------------------------------------------------------- 130 Mangled::Mangled (const ConstString &s, bool mangled) : 131 m_mangled(), 132 m_demangled() 133 { 134 if (s) 135 SetValue(s, mangled); 136 } 137 138 Mangled::Mangled (const ConstString &s) : 139 m_mangled(), 140 m_demangled() 141 { 142 if (s) 143 SetValue(s); 144 } 145 146 //---------------------------------------------------------------------- 147 // Destructor 148 //---------------------------------------------------------------------- 149 Mangled::~Mangled () 150 { 151 } 152 153 //---------------------------------------------------------------------- 154 // Convert to pointer operator. This allows code to check any Mangled 155 // objects to see if they contain anything valid using code such as: 156 // 157 // Mangled mangled(...); 158 // if (mangled) 159 // { ... 160 //---------------------------------------------------------------------- 161 Mangled::operator void* () const 162 { 163 return (m_mangled) ? const_cast<Mangled*>(this) : NULL; 164 } 165 166 //---------------------------------------------------------------------- 167 // Logical NOT operator. This allows code to check any Mangled 168 // objects to see if they are invalid using code such as: 169 // 170 // Mangled mangled(...); 171 // if (!file_spec) 172 // { ... 173 //---------------------------------------------------------------------- 174 bool 175 Mangled::operator! () const 176 { 177 return !m_mangled; 178 } 179 180 //---------------------------------------------------------------------- 181 // Clear the mangled and demangled values. 182 //---------------------------------------------------------------------- 183 void 184 Mangled::Clear () 185 { 186 m_mangled.Clear(); 187 m_demangled.Clear(); 188 } 189 190 191 //---------------------------------------------------------------------- 192 // Compare the string values. 193 //---------------------------------------------------------------------- 194 int 195 Mangled::Compare (const Mangled& a, const Mangled& b) 196 { 197 return ConstString::Compare(a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); 198 } 199 200 201 202 //---------------------------------------------------------------------- 203 // Set the string value in this objects. If "mangled" is true, then 204 // the mangled named is set with the new value in "s", else the 205 // demangled name is set. 206 //---------------------------------------------------------------------- 207 void 208 Mangled::SetValue (const ConstString &s, bool mangled) 209 { 210 if (s) 211 { 212 if (mangled) 213 { 214 m_demangled.Clear(); 215 m_mangled = s; 216 } 217 else 218 { 219 m_demangled = s; 220 m_mangled.Clear(); 221 } 222 } 223 else 224 { 225 m_demangled.Clear(); 226 m_mangled.Clear(); 227 } 228 } 229 230 void 231 Mangled::SetValue (const ConstString &name) 232 { 233 if (name) 234 { 235 if (cstring_is_mangled(name.GetCString())) 236 { 237 m_demangled.Clear(); 238 m_mangled = name; 239 } 240 else 241 { 242 m_demangled = name; 243 m_mangled.Clear(); 244 } 245 } 246 else 247 { 248 m_demangled.Clear(); 249 m_mangled.Clear(); 250 } 251 } 252 253 //---------------------------------------------------------------------- 254 // Generate the demangled name on demand using this accessor. Code in 255 // this class will need to use this accessor if it wishes to decode 256 // the demangled name. The result is cached and will be kept until a 257 // new string value is supplied to this object, or until the end of the 258 // object's lifetime. 259 //---------------------------------------------------------------------- 260 const ConstString& 261 Mangled::GetDemangledName (lldb::LanguageType language) const 262 { 263 // Check to make sure we have a valid mangled name and that we 264 // haven't already decoded our mangled name. 265 if (m_mangled && !m_demangled) 266 { 267 // We need to generate and cache the demangled name. 268 Timer scoped_timer (__PRETTY_FUNCTION__, 269 "Mangled::GetDemangledName (m_mangled = %s)", 270 m_mangled.GetCString()); 271 272 // Don't bother running anything that isn't mangled 273 const char *mangled_name = m_mangled.GetCString(); 274 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)}; 275 if (mangling_scheme != eManglingSchemeNone && 276 !m_mangled.GetMangledCounterpart(m_demangled)) 277 { 278 // We didn't already mangle this name, demangle it and if all goes well 279 // add it to our map. 280 char *demangled_name = nullptr; 281 switch (mangling_scheme) 282 { 283 case eManglingSchemeMSVC: 284 { 285 #if defined(_MSC_VER) 286 const size_t demangled_length = 2048; 287 demangled_name = static_cast<char *>(::malloc(demangled_length)); 288 ::ZeroMemory(demangled_name, demangled_length); 289 DWORD result = ::UnDecorateSymbolName(mangled_name, demangled_name, demangled_length, 290 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords 291 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords 292 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications 293 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers 294 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords 295 ); 296 if (result == 0) 297 { 298 free(demangled_name); 299 demangled_name = nullptr; 300 } 301 #endif 302 break; 303 } 304 case eManglingSchemeItanium: 305 { 306 #ifdef LLDB_USE_BUILTIN_DEMANGLER 307 // Try to use the fast-path demangler first for the 308 // performance win, falling back to the full demangler only 309 // when necessary 310 demangled_name = FastDemangle(mangled_name, m_mangled.GetLength()); 311 if (!demangled_name) 312 demangled_name = __cxa_demangle(mangled_name, NULL, NULL, NULL); 313 #else 314 demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL); 315 #endif 316 break; 317 } 318 case eManglingSchemeNone: 319 break; 320 } 321 if (demangled_name) 322 { 323 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); 324 free(demangled_name); 325 } 326 } 327 if (!m_demangled) 328 { 329 // Set the demangled string to the empty string to indicate we 330 // tried to parse it once and failed. 331 m_demangled.SetCString(""); 332 } 333 } 334 335 return m_demangled; 336 } 337 338 339 ConstString 340 Mangled::GetDisplayDemangledName (lldb::LanguageType language) const 341 { 342 return GetDemangledName(language); 343 } 344 345 bool 346 Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType language) const 347 { 348 if (m_mangled && regex.Execute (m_mangled.AsCString())) 349 return true; 350 351 ConstString demangled = GetDemangledName(language); 352 if (demangled && regex.Execute (demangled.AsCString())) 353 return true; 354 return false; 355 } 356 357 //---------------------------------------------------------------------- 358 // Get the demangled name if there is one, else return the mangled name. 359 //---------------------------------------------------------------------- 360 ConstString 361 Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preference) const 362 { 363 ConstString demangled = GetDemangledName(language); 364 365 if (preference == ePreferDemangledWithoutArguments) 366 { 367 return get_demangled_name_without_arguments (m_mangled, demangled); 368 } 369 if (preference == ePreferDemangled) 370 { 371 // Call the accessor to make sure we get a demangled name in case 372 // it hasn't been demangled yet... 373 if (demangled) 374 return demangled; 375 return m_mangled; 376 } 377 else 378 { 379 if (m_mangled) 380 return m_mangled; 381 return demangled; 382 } 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 lldb::LanguageType 429 Mangled::GuessLanguage () const 430 { 431 ConstString mangled = GetMangledName(); 432 if (mangled) 433 { 434 if (GetDemangledName(lldb::eLanguageTypeUnknown)) 435 { 436 if (cstring_is_mangled(mangled.GetCString())) 437 return lldb::eLanguageTypeC_plus_plus; 438 } 439 } 440 return lldb::eLanguageTypeUnknown; 441 } 442 443 //---------------------------------------------------------------------- 444 // Dump OBJ to the supplied stream S. 445 //---------------------------------------------------------------------- 446 Stream& 447 operator << (Stream& s, const Mangled& obj) 448 { 449 if (obj.GetMangledName()) 450 s << "mangled = '" << obj.GetMangledName() << "'"; 451 452 const ConstString& demangled = obj.GetDemangledName(lldb::eLanguageTypeUnknown); 453 if (demangled) 454 s << ", demangled = '" << demangled << '\''; 455 else 456 s << ", demangled = <error>"; 457 return s; 458 } 459