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