Index: lld/trunk/COFF/CMakeLists.txt =================================================================== --- lld/trunk/COFF/CMakeLists.txt +++ lld/trunk/COFF/CMakeLists.txt @@ -18,7 +18,6 @@ MarkLive.cpp MinGW.cpp PDB.cpp - Strings.cpp SymbolTable.cpp Symbols.cpp Writer.cpp Index: lld/trunk/COFF/Strings.h =================================================================== --- lld/trunk/COFF/Strings.h +++ lld/trunk/COFF/Strings.h @@ -1,23 +0,0 @@ -//===- Strings.h ------------------------------------------------*- C++ -*-===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_COFF_STRINGS_H -#define LLD_COFF_STRINGS_H - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringRef.h" -#include - -namespace lld { -namespace coff { -llvm::Optional demangleMSVC(llvm::StringRef S); -} -} - -#endif Index: lld/trunk/COFF/Strings.cpp =================================================================== --- lld/trunk/COFF/Strings.cpp +++ lld/trunk/COFF/Strings.cpp @@ -1,35 +0,0 @@ -//===- Strings.cpp -------------------------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Strings.h" -#include - -#if defined(_MSC_VER) -#include -#include -#pragma comment(lib, "dbghelp.lib") -#endif - -using namespace lld; -using namespace lld::coff; -using namespace llvm; - -Optional coff::demangleMSVC(StringRef S) { -#if defined(_MSC_VER) - // UnDecorateSymbolName is not thread-safe, so we need a mutex. - static std::mutex Mu; - std::lock_guard Lock(Mu); - - char Buf[4096]; - if (S.startswith("?")) - if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0)) - return std::string(Buf, Len); -#endif - return None; -} Index: lld/trunk/COFF/Symbols.cpp =================================================================== --- lld/trunk/COFF/Symbols.cpp +++ lld/trunk/COFF/Symbols.cpp @@ -9,9 +9,9 @@ #include "Symbols.h" #include "InputFiles.h" -#include "Strings.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -21,7 +21,7 @@ // Returns a symbol name for an error message. std::string lld::toString(coff::Symbol &B) { - if (Optional S = coff::demangleMSVC(B.getName())) + if (Optional S = lld::demangleMSVC(B.getName())) return ("\"" + *S + "\" (" + B.getName() + ")").str(); return B.getName(); } Index: lld/trunk/Common/Strings.cpp =================================================================== --- lld/trunk/Common/Strings.cpp +++ lld/trunk/Common/Strings.cpp @@ -8,7 +8,19 @@ //===----------------------------------------------------------------------===// #include "lld/Common/Strings.h" +#include "lld/Common/ErrorHandler.h" +#include "lld/Common/LLVM.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/Support/GlobPattern.h" +#include +#include +#include + +#if defined(_MSC_VER) +#include +#include +#pragma comment(lib, "dbghelp.lib") +#endif using namespace llvm; using namespace lld; @@ -30,3 +42,57 @@ free(Buf); return S; } + +Optional lld::demangleMSVC(StringRef S) { +#if defined(_MSC_VER) + // UnDecorateSymbolName is not thread-safe, so we need a mutex. + static std::mutex Mu; + std::lock_guard Lock(Mu); + + char Buf[4096]; + if (S.startswith("?")) + if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0)) + return std::string(Buf, Len); +#endif + return None; +} + +StringMatcher::StringMatcher(ArrayRef Pat) { + for (StringRef S : Pat) { + Expected Pat = GlobPattern::create(S); + if (!Pat) + error(toString(Pat.takeError())); + else + Patterns.push_back(*Pat); + } +} + +bool StringMatcher::match(StringRef S) const { + for (const GlobPattern &Pat : Patterns) + if (Pat.match(S)) + return true; + return false; +} + +// Converts a hex string (e.g. "deadbeef") to a vector. +std::vector lld::parseHex(StringRef S) { + std::vector Hex; + while (!S.empty()) { + StringRef B = S.substr(0, 2); + S = S.substr(2); + uint8_t H; + if (!to_integer(B, H, 16)) { + error("not a hexadecimal value: " + B); + return {}; + } + Hex.push_back(H); + } + return Hex; +} + +// Returns true if S is valid as a C language identifier. +bool lld::isValidCIdentifier(StringRef S) { + return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && + std::all_of(S.begin() + 1, S.end(), + [](char C) { return C == '_' || isAlnum(C); }); +} Index: lld/trunk/ELF/AArch64ErrataFix.cpp =================================================================== --- lld/trunk/ELF/AArch64ErrataFix.cpp +++ lld/trunk/ELF/AArch64ErrataFix.cpp @@ -34,11 +34,11 @@ #include "LinkerScript.h" #include "OutputSections.h" #include "Relocations.h" -#include "Strings.h" #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "llvm/Support/Endian.h" #include "llvm/Support/raw_ostream.h" #include Index: lld/trunk/ELF/CMakeLists.txt =================================================================== --- lld/trunk/ELF/CMakeLists.txt +++ lld/trunk/ELF/CMakeLists.txt @@ -35,7 +35,6 @@ Relocations.cpp ScriptLexer.cpp ScriptParser.cpp - Strings.cpp SymbolTable.cpp Symbols.cpp SyntheticSections.cpp Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -33,7 +33,6 @@ #include "MarkLive.h" #include "OutputSections.h" #include "ScriptParser.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" @@ -43,6 +42,7 @@ #include "lld/Common/Driver.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "lld/Common/TargetOptionsCommandFlags.h" #include "lld/Common/Threads.h" #include "lld/Common/Version.h" Index: lld/trunk/ELF/EhFrame.cpp =================================================================== --- lld/trunk/ELF/EhFrame.cpp +++ lld/trunk/ELF/EhFrame.cpp @@ -20,8 +20,8 @@ #include "Config.h" #include "InputSection.h" #include "Relocations.h" -#include "Strings.h" #include "lld/Common/ErrorHandler.h" +#include "lld/Common/Strings.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Object/ELF.h" #include "llvm/Support/Endian.h" Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -11,9 +11,9 @@ #define LLD_ELF_LINKER_SCRIPT_H #include "Config.h" -#include "Strings.h" #include "Writer.h" #include "lld/Common/LLVM.h" +#include "lld/Common/Strings.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -15,13 +15,13 @@ #include "Config.h" #include "InputSection.h" #include "OutputSections.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" #include "Writer.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "lld/Common/Threads.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" Index: lld/trunk/ELF/MapFile.cpp =================================================================== --- lld/trunk/ELF/MapFile.cpp +++ lld/trunk/ELF/MapFile.cpp @@ -23,10 +23,10 @@ #include "InputFiles.h" #include "LinkerScript.h" #include "OutputSections.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" +#include "lld/Common/Strings.h" #include "lld/Common/Threads.h" #include "llvm/Support/raw_ostream.h" Index: lld/trunk/ELF/MarkLive.cpp =================================================================== --- lld/trunk/ELF/MarkLive.cpp +++ lld/trunk/ELF/MarkLive.cpp @@ -24,11 +24,11 @@ #include "InputSection.h" #include "LinkerScript.h" #include "OutputSections.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "Target.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Object/ELF.h" #include Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -10,11 +10,11 @@ #include "OutputSections.h" #include "Config.h" #include "LinkerScript.h" -#include "Strings.h" #include "SymbolTable.h" #include "SyntheticSections.h" #include "Target.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "lld/Common/Threads.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/Compression.h" Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -45,13 +45,13 @@ #include "Config.h" #include "LinkerScript.h" #include "OutputSections.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" #include "Thunks.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "llvm/Support/Endian.h" #include "llvm/Support/raw_ostream.h" #include Index: lld/trunk/ELF/Strings.h =================================================================== --- lld/trunk/ELF/Strings.h +++ lld/trunk/ELF/Strings.h @@ -1,75 +0,0 @@ -//===- Strings.h ------------------------------------------------*- C++ -*-===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_ELF_STRINGS_H -#define LLD_ELF_STRINGS_H - -#include "lld/Common/LLVM.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/GlobPattern.h" -#include - -namespace lld { -namespace elf { - -std::vector parseHex(StringRef S); -bool isValidCIdentifier(StringRef S); - -// This is a lazy version of StringRef. String size is computed lazily -// when it is needed. It is more efficient than StringRef to instantiate -// if you have a string whose size is unknown. -// -// ELF string tables contain a lot of null-terminated strings. -// Most of them are not necessary for the linker because they are names -// of local symbols and the linker doesn't use local symbol names for -// name resolution. So, we use this class to represents strings read -// from string tables. -class StringRefZ { -public: - StringRefZ() : Start(nullptr), Size(0) {} - StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {} - - /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {} - - /*implicit*/ StringRefZ(llvm::StringRef S) - : Start(S.data()), Size(S.size()) {} - - operator llvm::StringRef() const { - if (Size == (size_t)-1) - Size = strlen(Start); - return {Start, Size}; - } - -private: - const char *Start; - mutable size_t Size; -}; - -// This class represents multiple glob patterns. -class StringMatcher { -public: - StringMatcher() = default; - explicit StringMatcher(ArrayRef Pat); - - bool match(StringRef S) const; - -private: - std::vector Patterns; -}; - -inline ArrayRef toArrayRef(StringRef S) { - return {(const uint8_t *)S.data(), S.size()}; -} -} // namespace elf -} // namespace lld - -#endif Index: lld/trunk/ELF/Strings.cpp =================================================================== --- lld/trunk/ELF/Strings.cpp +++ lld/trunk/ELF/Strings.cpp @@ -1,60 +0,0 @@ -//===- Strings.cpp -------------------------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Strings.h" -#include "Config.h" -#include "lld/Common/ErrorHandler.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Demangle/Demangle.h" -#include -#include - -using namespace llvm; -using namespace lld; -using namespace lld::elf; - -StringMatcher::StringMatcher(ArrayRef Pat) { - for (StringRef S : Pat) { - Expected Pat = GlobPattern::create(S); - if (!Pat) - error(toString(Pat.takeError())); - else - Patterns.push_back(*Pat); - } -} - -bool StringMatcher::match(StringRef S) const { - for (const GlobPattern &Pat : Patterns) - if (Pat.match(S)) - return true; - return false; -} - -// Converts a hex string (e.g. "deadbeef") to a vector. -std::vector elf::parseHex(StringRef S) { - std::vector Hex; - while (!S.empty()) { - StringRef B = S.substr(0, 2); - S = S.substr(2); - uint8_t H; - if (!to_integer(B, H, 16)) { - error("not a hexadecimal value: " + B); - return {}; - } - Hex.push_back(H); - } - return Hex; -} - -// Returns true if S is valid as a C language identifier. -bool elf::isValidCIdentifier(StringRef S) { - return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && - std::all_of(S.begin() + 1, S.end(), - [](char C) { return C == '_' || isAlnum(C); }); -} Index: lld/trunk/ELF/SymbolTable.h =================================================================== --- lld/trunk/ELF/SymbolTable.h +++ lld/trunk/ELF/SymbolTable.h @@ -12,7 +12,7 @@ #include "InputFiles.h" #include "LTO.h" -#include "Strings.h" +#include "lld/Common/Strings.h" #include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseMap.h" Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -16,8 +16,8 @@ #define LLD_ELF_SYMBOLS_H #include "InputSection.h" -#include "Strings.h" #include "lld/Common/LLVM.h" +#include "lld/Common/Strings.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ELF.h" Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -20,13 +20,13 @@ #include "InputFiles.h" #include "LinkerScript.h" #include "OutputSections.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "Target.h" #include "Writer.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "lld/Common/Threads.h" #include "lld/Common/Version.h" #include "llvm/BinaryFormat/Dwarf.h" Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -15,12 +15,12 @@ #include "MapFile.h" #include "OutputSections.h" #include "Relocations.h" -#include "Strings.h" #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" #include "lld/Common/Memory.h" +#include "lld/Common/Strings.h" #include "lld/Common/Threads.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" Index: lld/trunk/include/lld/Common/Strings.h =================================================================== --- lld/trunk/include/lld/Common/Strings.h +++ lld/trunk/include/lld/Common/Strings.h @@ -10,14 +10,67 @@ #ifndef LLD_STRINGS_H #define LLD_STRINGS_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/GlobPattern.h" #include +#include namespace lld { // Returns a demangled C++ symbol name. If Name is not a mangled // name, it returns Optional::None. llvm::Optional demangleItanium(llvm::StringRef Name); +llvm::Optional demangleMSVC(llvm::StringRef S); + +std::vector parseHex(llvm::StringRef S); +bool isValidCIdentifier(llvm::StringRef S); + +// This is a lazy version of StringRef. String size is computed lazily +// when it is needed. It is more efficient than StringRef to instantiate +// if you have a string whose size is unknown. +// +// COFF and ELF string tables contain a lot of null-terminated strings. +// Most of them are not necessary for the linker because they are names +// of local symbols and the linker doesn't use local symbol names for +// name resolution. So, we use this class to represents strings read +// from string tables. +class StringRefZ { +public: + StringRefZ() : Start(nullptr), Size(0) {} + StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {} + + /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {} + + /*implicit*/ StringRefZ(llvm::StringRef S) + : Start(S.data()), Size(S.size()) {} + + operator llvm::StringRef() const { + if (Size == (size_t)-1) + Size = strlen(Start); + return {Start, Size}; + } + +private: + const char *Start; + mutable size_t Size; +}; + +// This class represents multiple glob patterns. +class StringMatcher { +public: + StringMatcher() = default; + explicit StringMatcher(llvm::ArrayRef Pat); + + bool match(llvm::StringRef S) const; + +private: + std::vector Patterns; +}; + +inline llvm::ArrayRef toArrayRef(llvm::StringRef S) { + return {reinterpret_cast(S.data()), S.size()}; +} } #endif