Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -32,6 +32,20 @@ class OutputSection; template class SharedFile; +// This is a StringRef-like container that doesn't run strlen(). +// +// 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. +struct StringRefZ { + StringRefZ(const char *S) : Data(S), Size(-1) {} + StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {} + + const char *Data; + const uint32_t Size; +}; + // The base class for real symbol classes. class Symbol { public: @@ -49,7 +63,7 @@ InputFile *File; protected: - const char *NameStart; + const char *NameData; mutable uint32_t NameSize; public: @@ -117,9 +131,10 @@ StringRef getName() const { if (NameSize == (uint32_t)-1) - NameSize = strlen(NameStart); - return StringRef(NameStart, NameSize); + NameSize = strlen(NameData); + return {NameData, NameSize}; } + void parseSymbolVersion(); bool isInGot() const { return GotIndex != -1U; } @@ -138,11 +153,10 @@ protected: Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther, uint8_t Type) - : File(File), NameStart(Name.data()), NameSize(Name.rawSize()), - Binding(Binding), Type(Type), StOther(StOther), SymbolKind(K), - NeedsPltAddr(false), IsInGlobalMipsGot(false), Is32BitMipsGot(false), - IsInIplt(false), IsInIgot(false), IsPreemptible(false), - Used(!Config->GcSections) {} + : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding), + Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false), + IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), + IsInIgot(false), IsPreemptible(false), Used(!Config->GcSections) {} public: // True the symbol should point to its PLT entry. Index: include/lld/Common/Strings.h =================================================================== --- include/lld/Common/Strings.h +++ include/lld/Common/Strings.h @@ -26,39 +26,6 @@ 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()) {} - - const char *data() const { return Start; } - size_t rawSize() const { return 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: