Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -45,6 +45,23 @@ Kind kind() const { return static_cast(SymbolKind); } + // The file from which this symbol was created. + InputFile *File; + +protected: + const char *NameStart; + mutable uint32_t NameSize; + +public: + uint32_t DynsymIndex = 0; + uint32_t GotIndex = -1; + uint32_t GotPltIndex = -1; + uint32_t PltIndex = -1; + uint32_t GlobalDynIndex = -1; + + // Version definition index. + uint16_t VersionId; + // Symbol binding. This is not overwritten by replaceSymbol to track // changes during resolution. In particular: // - An undefined weak is still weak when it resolves to a shared library. @@ -52,8 +69,11 @@ // remember it is weak. uint8_t Binding; - // Version definition index. - uint16_t VersionId; + // The following fields have the same meaning as the ELF symbol attributes. + uint8_t Type; // symbol type + uint8_t StOther; // st_other field value + + const uint8_t SymbolKind; // Symbol visibility. This is the computed minimum visibility of all // observed non-DSO symbols. @@ -79,9 +99,6 @@ // True if this symbol is specified by --trace-symbol option. unsigned Traced : 1; - // The file from which this symbol was created. - InputFile *File; - bool includeInDynsym() const; uint8_t computeBinding() const; bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } @@ -98,7 +115,11 @@ // True if this is an undefined weak symbol. bool isUndefWeak() const { return isWeak() && isUndefined(); } - StringRef getName() const { return Name; } + StringRef getName() const { + if (NameSize == (uint32_t)-1) + NameSize = strlen(NameStart); + return StringRef(NameStart, NameSize); + } void parseSymbolVersion(); bool isInGot() const { return GotIndex != -1U; } @@ -114,21 +135,14 @@ uint64_t getSize() const; OutputSection *getOutputSection() const; - uint32_t DynsymIndex = 0; - uint32_t GotIndex = -1; - uint32_t GotPltIndex = -1; - uint32_t PltIndex = -1; - uint32_t GlobalDynIndex = -1; - protected: Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther, uint8_t Type) - : Binding(Binding), File(File), SymbolKind(K), NeedsPltAddr(false), - IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), - IsInIgot(false), IsPreemptible(false), Used(!Config->GcSections), - Type(Type), StOther(StOther), Name(Name) {} - - const unsigned SymbolKind : 8; + : 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) {} public: // True the symbol should point to its PLT entry. @@ -152,10 +166,6 @@ // True if an undefined or shared symbol is used from a live section. unsigned Used : 1; - // The following fields have the same meaning as the ELF symbol attributes. - uint8_t Type; // symbol type - uint8_t StOther; // st_other field value - // The Type field may also have this value. It means that we have not yet seen // a non-Lazy symbol with this name, so we don't know what its type is. The // Type field is normally set to this value for Lazy symbols unless we saw a @@ -169,9 +179,6 @@ bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; } bool isObject() const { return Type == llvm::ELF::STT_OBJECT; } bool isFile() const { return Type == llvm::ELF::STT_FILE; } - -protected: - StringRefZ Name; }; // Represents a symbol that is defined in the current output file. Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -177,7 +177,7 @@ return; // Truncate the symbol name so that it doesn't include the version string. - Name = {S.data(), Pos}; + NameSize = Pos; // If this is not in this DSO, it is not a definition. if (!isDefined()) Index: include/lld/Common/Strings.h =================================================================== --- include/lld/Common/Strings.h +++ include/lld/Common/Strings.h @@ -45,6 +45,9 @@ /*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);