Index: lld/ELF/Symbols.h =================================================================== --- lld/ELF/Symbols.h +++ lld/ELF/Symbols.h @@ -32,6 +32,21 @@ class OutputSection; template class SharedFile; +// This is a StringRef-like container that doesn't run strlen() automatically. +// +// 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(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 +64,7 @@ InputFile *File; protected: - const char *NameStart; + const char *NameData; mutable uint32_t NameSize; public: @@ -117,8 +132,8 @@ StringRef getName() const { if (NameSize == (uint32_t)-1) - NameSize = strlen(NameStart); - return StringRef(NameStart, NameSize); + NameSize = strlen(NameData); + return StringRef(NameData, NameSize); } void parseSymbolVersion(); @@ -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: lld/include/lld/Common/Strings.h =================================================================== --- lld/include/lld/Common/Strings.h +++ lld/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: