1 //===- Strings.cpp -------------------------------------------------------===// 2 // 3 // The LLVM Linker 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 "lld/Common/Strings.h" 11 #include "lld/Common/ErrorHandler.h" 12 #include "lld/Common/LLVM.h" 13 #include "llvm/Demangle/Demangle.h" 14 #include "llvm/Support/GlobPattern.h" 15 #include <algorithm> 16 #include <mutex> 17 #include <vector> 18 19 #if defined(_MSC_VER) 20 #include <Windows.h> 21 22 // DbgHelp.h must be included after Windows.h. 23 #include <DbgHelp.h> 24 #pragma comment(lib, "dbghelp.lib") 25 #endif 26 27 using namespace llvm; 28 using namespace lld; 29 30 // Returns the demangled C++ symbol name for Name. 31 Optional<std::string> lld::demangleItanium(StringRef Name) { 32 // itaniumDemangle can be used to demangle strings other than symbol 33 // names which do not necessarily start with "_Z". Name can be 34 // either a C or C++ symbol. Don't call itaniumDemangle if the name 35 // does not look like a C++ symbol name to avoid getting unexpected 36 // result for a C symbol that happens to match a mangled type name. 37 if (!Name.startswith("_Z")) 38 return None; 39 40 char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); 41 if (!Buf) 42 return None; 43 std::string S(Buf); 44 free(Buf); 45 return S; 46 } 47 48 Optional<std::string> lld::demangleMSVC(StringRef S) { 49 #if defined(_MSC_VER) 50 // UnDecorateSymbolName is not thread-safe, so we need a mutex. 51 static std::mutex Mu; 52 std::lock_guard<std::mutex> Lock(Mu); 53 54 char Buf[4096]; 55 if (S.startswith("?")) 56 if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0)) 57 return std::string(Buf, Len); 58 #endif 59 return None; 60 } 61 62 StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) { 63 for (StringRef S : Pat) { 64 Expected<GlobPattern> Pat = GlobPattern::create(S); 65 if (!Pat) 66 error(toString(Pat.takeError())); 67 else 68 Patterns.push_back(*Pat); 69 } 70 } 71 72 bool StringMatcher::match(StringRef S) const { 73 for (const GlobPattern &Pat : Patterns) 74 if (Pat.match(S)) 75 return true; 76 return false; 77 } 78 79 // Converts a hex string (e.g. "deadbeef") to a vector. 80 std::vector<uint8_t> lld::parseHex(StringRef S) { 81 std::vector<uint8_t> Hex; 82 while (!S.empty()) { 83 StringRef B = S.substr(0, 2); 84 S = S.substr(2); 85 uint8_t H; 86 if (!to_integer(B, H, 16)) { 87 error("not a hexadecimal value: " + B); 88 return {}; 89 } 90 Hex.push_back(H); 91 } 92 return Hex; 93 } 94 95 // Returns true if S is valid as a C language identifier. 96 bool lld::isValidCIdentifier(StringRef S) { 97 return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && 98 std::all_of(S.begin() + 1, S.end(), 99 [](char C) { return C == '_' || isAlnum(C); }); 100 } 101