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