[lld] r275711 - Handle versioned symbols efficiently.
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 18 15:04:27 PDT 2016
I cannot reproduce these numbers.
I could not test scylla and firefox because of pr28605, but the times
I got with the rest are attached. The ratios are from the previous
value.
Can you upload the --reproduce of the testcase you used somewhere?
Thanks,
Rafael
On 17 July 2016 at 13:23, Rui Ueyama via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: ruiu
> Date: Sun Jul 17 12:23:17 2016
> New Revision: 275711
>
> URL: http://llvm.org/viewvc/llvm-project?rev=275711&view=rev
> Log:
> Handle versioned symbols efficiently.
>
> Versions can be assigned to symbols in two different ways.
> One is the usual version scripts, and the other is special
> symbol suffix '@'. If a symbol contains '@', the string after
> that is considered to specify a version name.
>
> Previously, we look for '@' for all symbols.
>
> Anything that works on every symbol can be expensive because
> the linker has to handle a lot of symbols. The search for '@'
> was not an exception.
>
> In this patch, I made two optimizations.
>
> The first optimization is to handle '@' only when at least one
> version is defined. If no versions are defined, no versions can
> be assigned to any symbols, so it's waste of time to search for '@'.
>
> The second optimization is to scan only suffixes of symbol names
> instead of entire symbol names. Symbol names can be very long, but
> symbol versions are usually short, so scanning entire symbol names
> is waste of time, too.
>
> There are some error cases which we no longer be able to detect
> with this patch. I don't think it's a major drawback because they
> are minor errors. Speed is more important.
>
> This change improves LLD with debug info self-link time from
> 6.6993 seconds to 6.3426 seconds (or -5.3%).
>
> Differential Revision: https://reviews.llvm.org/D22433
>
> Removed:
> lld/trunk/test/ELF/verdef-executable.s
> Modified:
> lld/trunk/ELF/Config.h
> lld/trunk/ELF/Driver.cpp
> lld/trunk/ELF/SymbolTable.cpp
> lld/trunk/ELF/SymbolTable.h
> lld/trunk/ELF/Symbols.cpp
> lld/trunk/ELF/Symbols.h
> lld/trunk/test/ELF/verdef-defaultver.s
>
> Modified: lld/trunk/ELF/Config.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Config.h (original)
> +++ lld/trunk/ELF/Config.h Sun Jul 17 12:23:17 2016
> @@ -90,7 +90,6 @@ struct Configuration {
> bool FatalWarnings;
> bool GcSections;
> bool GnuHash = false;
> - bool HasVersionScript = false;
> bool ICF;
> bool Mips64EL = false;
> bool NoGnuUnique;
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Sun Jul 17 12:23:17 2016
> @@ -443,11 +443,9 @@ void LinkerDriver::readConfigs(opt::Inpu
> for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
> Config->DynamicList.push_back(Arg->getValue());
>
> - if (auto *Arg = Args.getLastArg(OPT_version_script)) {
> - Config->HasVersionScript = true;
> + if (auto *Arg = Args.getLastArg(OPT_version_script))
> if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
> parseVersionScript(*Buffer);
> - }
>
> for (auto *Arg : Args.filtered(OPT_trace_symbol))
> Config->TraceSymbol.insert(Arg->getValue());
> @@ -557,6 +555,7 @@ template <class ELFT> void LinkerDriver:
> Symtab.scanShlibUndefined();
> Symtab.scanDynamicList();
> Symtab.scanVersionScript();
> + Symtab.scanSymbolVersions();
> Symtab.traceDefined();
>
> Symtab.addCombinedLtoObject();
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Sun Jul 17 12:23:17 2016
> @@ -165,39 +165,6 @@ static uint8_t getMinVisibility(uint8_t
> return std::min(VA, VB);
> }
>
> -// A symbol version may be included in a symbol name as a suffix after '@'.
> -// This function parses that part and returns a version ID number.
> -static uint16_t getVersionId(Symbol *Sym, StringRef Name) {
> - size_t VersionBegin = Name.find('@');
> - if (VersionBegin == StringRef::npos)
> - return Config->DefaultSymbolVersion;
> -
> - // If symbol name contains '@' or '@@' we can assign its version id right
> - // here. '@@' means the default version. It is usually the most recent one.
> - // VERSYM_HIDDEN flag should be set for all non-default versions.
> - StringRef Version = Name.drop_front(VersionBegin + 1);
> - bool Default = Version.startswith("@");
> - if (Default)
> - Version = Version.drop_front();
> -
> - for (VersionDefinition &V : Config->VersionDefinitions)
> - if (V.Name == Version)
> - return Default ? V.Id : (V.Id | VERSYM_HIDDEN);
> -
> -
> - // If we are not building shared and version script
> - // is not specified, then it is not a error, it is
> - // in common not to use script for linking executables.
> - // In this case we just create new version.
> - if (!Config->Shared && !Config->HasVersionScript) {
> - size_t Id = defineSymbolVersion(Version);
> - return Default ? Id : (Id | VERSYM_HIDDEN);
> - }
> -
> - error("symbol " + Name + " has undefined version " + Version);
> - return 0;
> -}
> -
> // Find an existing symbol or create and insert a new one.
> template <class ELFT>
> std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
> @@ -210,9 +177,7 @@ std::pair<Symbol *, bool> SymbolTable<EL
> Sym->Visibility = STV_DEFAULT;
> Sym->IsUsedInRegularObj = false;
> Sym->ExportDynamic = false;
> - Sym->VersionId = getVersionId(Sym, Name);
> - Sym->VersionedName =
> - Sym->VersionId != VER_NDX_LOCAL && Sym->VersionId != VER_NDX_GLOBAL;
> + Sym->VersionId = Config->DefaultSymbolVersion;
> SymVector.push_back(Sym);
> } else {
> Sym = SymVector[P.first->second];
> @@ -646,6 +611,84 @@ template <class ELFT> void SymbolTable<E
> }
> }
>
> +// Returns the size of the longest version name.
> +static int getMaxVersionLen() {
> + size_t Len = 0;
> + for (VersionDefinition &V : Config->VersionDefinitions)
> + Len = std::max(Len, V.Name.size());
> + return Len;
> +}
> +
> +// Parses a symbol name in the form of <name>@<version> or <name>@@<version>.
> +static std::pair<StringRef, uint16_t>
> +getSymbolVersion(SymbolBody *B, int MaxVersionLen) {
> + StringRef S = B->getName();
> +
> + // MaxVersionLen was passed so that we don't need to scan
> + // all characters in a symbol name. It is effective because
> + // versions are usually short and symbol names can be very long.
> + size_t Pos = S.find('@', std::max(0, int(S.size()) - MaxVersionLen - 2));
> + if (Pos == 0 || Pos == StringRef::npos)
> + return {"", 0};
> +
> + StringRef Name = S.substr(0, Pos);
> + StringRef Verstr = S.substr(Pos + 1);
> + if (Verstr.empty())
> + return {"", 0};
> +
> + // '@@' in a symbol name means the default version.
> + // It is usually the most recent one.
> + bool IsDefault = (Verstr[0] == '@');
> + if (IsDefault)
> + Verstr = Verstr.substr(1);
> +
> + for (VersionDefinition &V : Config->VersionDefinitions) {
> + if (V.Name == Verstr)
> + return {Name, IsDefault ? V.Id : (V.Id | VERSYM_HIDDEN)};
> + }
> +
> + // It is an error if the specified version was not defined.
> + error("symbol " + S + " has undefined version " + Verstr);
> + return {"", 0};
> +}
> +
> +// Versions are usually assigned to symbols using version scripts,
> +// but there's another way to assign versions to symbols.
> +// If a symbol name contains '@', the string after it is not
> +// actually a part of the symbol name but specifies a version.
> +// This function takes care of it.
> +template <class ELFT> void SymbolTable<ELFT>::scanSymbolVersions() {
> + if (Config->VersionDefinitions.empty())
> + return;
> +
> + int MaxVersionLen = getMaxVersionLen();
> +
> + // Unfortunately there's no way other than iterating over all
> + // symbols to look for '@' characters in symbol names.
> + // So this is inherently slow. A good news is that we do this
> + // only when versions have been defined.
> + for (Symbol *Sym : SymVector) {
> + // Symbol versions for exported symbols are by nature
> + // only for defined global symbols.
> + SymbolBody *B = Sym->body();
> + if (!B->isDefined())
> + continue;
> + uint8_t Visibility = B->getVisibility();
> + if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
> + continue;
> +
> + // Look for '@' in the symbol name.
> + StringRef Name;
> + uint16_t Version;
> + std::tie(Name, Version) = getSymbolVersion(B, MaxVersionLen);
> + if (Name.empty())
> + continue;
> +
> + B->setName(Name);
> + Sym->VersionId = Version;
> + }
> +}
> +
> // Print the module names which define the notified
> // symbols provided through -y or --trace-symbol option.
> template <class ELFT> void SymbolTable<ELFT>::traceDefined() {
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Sun Jul 17 12:23:17 2016
> @@ -82,6 +82,7 @@ public:
> void scanShlibUndefined();
> void scanDynamicList();
> void scanVersionScript();
> + void scanSymbolVersions();
> void traceDefined();
>
> SymbolBody *find(StringRef Name);
>
> Modified: lld/trunk/ELF/Symbols.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Symbols.cpp (original)
> +++ lld/trunk/ELF/Symbols.cpp Sun Jul 17 12:23:17 2016
> @@ -98,10 +98,12 @@ SymbolBody::SymbolBody(Kind K, StringRef
>
> StringRef SymbolBody::getName() const {
> assert(!isLocal());
> - StringRef S = StringRef(Name.S, Name.Len);
> - if (!symbol()->VersionedName)
> - return S;
> - return S.substr(0, S.find('@'));
> + return StringRef(Name.S, Name.Len);
> +}
> +
> +void SymbolBody::setName(StringRef S) {
> + Name.S = S.data();
> + Name.Len = S.size();
> }
>
> // Returns true if a symbol can be replaced at load-time by a symbol
>
> Modified: lld/trunk/ELF/Symbols.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Sun Jul 17 12:23:17 2016
> @@ -70,8 +70,9 @@ public:
> bool isLocal() const { return IsLocal; }
> bool isPreemptible() const;
>
> - // Returns the symbol name.
> StringRef getName() const;
> + void setName(StringRef S);
> +
> uint32_t getNameOffset() const {
> assert(isLocal());
> return NameOffset;
> @@ -419,11 +420,6 @@ struct Symbol {
> // --export-dynamic, and by dynamic lists.
> unsigned ExportDynamic : 1;
>
> - // If this flag is true then symbol name also contains version name. Such
> - // name can have single or double symbol @. Double means that version is
> - // used as default. Single signals about depricated symbol version.
> - unsigned VersionedName : 1;
> -
> bool includeInDynsym() const;
> bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
>
>
> Modified: lld/trunk/test/ELF/verdef-defaultver.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/verdef-defaultver.s?rev=275711&r1=275710&r2=275711&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/verdef-defaultver.s (original)
> +++ lld/trunk/test/ELF/verdef-defaultver.s Sun Jul 17 12:23:17 2016
> @@ -198,10 +198,6 @@
> # EXE-NEXT: }
> # EXE-NEXT: }
>
> -# RUN: not ld.lld -shared %t1 -o %terr.so 2>&1 | \
> -# RUN: FileCheck -check-prefix=ERR1 %s
> -# ERR1: symbol b@@LIBSAMPLE_2.0 has undefined version LIBSAMPLE_2.0
> -
> .globl _start
> _start:
> callq a
>
> Removed: lld/trunk/test/ELF/verdef-executable.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/verdef-executable.s?rev=275710&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/verdef-executable.s (original)
> +++ lld/trunk/test/ELF/verdef-executable.s (removed)
> @@ -1,269 +0,0 @@
> -# REQUIRES: x86
> -
> -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
> -# RUN: ld.lld %t1 -o %t
> -# RUN: llvm-readobj -t -V -dyn-symbols %t | FileCheck --check-prefix=EXE %s
> -
> -# EXE: Symbols [
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name:
> -# EXE-NEXT: Value: 0x0
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Local
> -# EXE-NEXT: Type: None (0x0)
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: Undefined (0x0)
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: _start
> -# EXE-NEXT: Value: 0x11004
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: None
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: a
> -# EXE-NEXT: Value: 0x11000
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: Function
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: b
> -# EXE-NEXT: Value: 0x11002
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: Function
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: b
> -# EXE-NEXT: Value: 0x11001
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: Function
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: b_1
> -# EXE-NEXT: Value: 0x11001
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: Function
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: b_2
> -# EXE-NEXT: Value: 0x11002
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: Function
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: Symbol {
> -# EXE-NEXT: Name: c
> -# EXE-NEXT: Value: 0x11003
> -# EXE-NEXT: Size: 0
> -# EXE-NEXT: Binding: Global
> -# EXE-NEXT: Type: Function
> -# EXE-NEXT: Other: 0
> -# EXE-NEXT: Section: .text
> -# EXE-NEXT: }
> -# EXE-NEXT: ]
> -# EXE-NEXT: DynamicSymbols [
> -# EXE-NEXT: ]
> -# EXE-NEXT: Version symbols {
> -# EXE-NEXT: }
> -# EXE-NEXT: SHT_GNU_verdef {
> -# EXE-NEXT: }
> -# EXE-NEXT: SHT_GNU_verneed {
> -# EXE-NEXT: }
> -
> -# RUN: ld.lld -pie --export-dynamic %t1 -o %t2
> -# RUN: llvm-readobj -t -V -dyn-symbols %t2 | \
> -# RUN: FileCheck --check-prefix=EXEDYN %s
> -
> -# EXEDYN: DynamicSymbols [
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: @
> -# EXEDYN-NEXT: Value: 0x0
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Local
> -# EXEDYN-NEXT: Type: None
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: Undefined
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: _start@
> -# EXEDYN-NEXT: Value: 0x1004
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: None
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: a@
> -# EXEDYN-NEXT: Value: 0x1000
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: Function
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: b@@LIBSAMPLE_2.0
> -# EXEDYN-NEXT: Value: 0x1002
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: Function
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: b at LIBSAMPLE_1.0
> -# EXEDYN-NEXT: Value: 0x1001
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: Function
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: b_1@
> -# EXEDYN-NEXT: Value: 0x1001
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: Function
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: b_2@
> -# EXEDYN-NEXT: Value: 0x1002
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: Function
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Name: c@
> -# EXEDYN-NEXT: Value: 0x1003
> -# EXEDYN-NEXT: Size: 0
> -# EXEDYN-NEXT: Binding: Global
> -# EXEDYN-NEXT: Type: Function
> -# EXEDYN-NEXT: Other: 0
> -# EXEDYN-NEXT: Section: .text
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: ]
> -# EXEDYN-NEXT: Version symbols {
> -# EXEDYN-NEXT: Section Name: .gnu.version
> -# EXEDYN-NEXT: Address: 0x288
> -# EXEDYN-NEXT: Offset: 0x288
> -# EXEDYN-NEXT: Link: 1
> -# EXEDYN-NEXT: Symbols [
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 0
> -# EXEDYN-NEXT: Name: @
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Name: _start@
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Name: a@
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 2
> -# EXEDYN-NEXT: Name: b@@LIBSAMPLE_2.0
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 3
> -# EXEDYN-NEXT: Name: b at LIBSAMPLE_1.0
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Name: b_1@
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Name: b_2@
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Symbol {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Name: c@
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: ]
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: SHT_GNU_verdef {
> -# EXEDYN-NEXT: Definition {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Flags: Base
> -# EXEDYN-NEXT: Index: 1
> -# EXEDYN-NEXT: Hash:
> -# EXEDYN-NEXT: Name:
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Definition {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Flags: 0x0
> -# EXEDYN-NEXT: Index: 2
> -# EXEDYN-NEXT: Hash: 98456416
> -# EXEDYN-NEXT: Name: LIBSAMPLE_2.0
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: Definition {
> -# EXEDYN-NEXT: Version: 1
> -# EXEDYN-NEXT: Flags: 0x0
> -# EXEDYN-NEXT: Index: 3
> -# EXEDYN-NEXT: Hash: 98457184
> -# EXEDYN-NEXT: Name: LIBSAMPLE_1.0
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: }
> -# EXEDYN-NEXT: SHT_GNU_verneed {
> -# EXEDYN-NEXT: }
> -
> -## Check when linking executable that error produced if version script
> -## was specified and there are symbols with version in name that
> -## is absent in script.
> -# RUN: echo "VERSION { \
> -# RUN: global: foo; \
> -# RUN: local: *; }; " > %t.script
> -# RUN: not ld.lld --version-script %t.script %t1 -o %t3 2>&1 | \
> -# RUN: FileCheck -check-prefix=ERR %s
> -# ERR: symbol b at LIBSAMPLE_1.0 has undefined version LIBSAMPLE_1.0
> -
> -b at LIBSAMPLE_1.0 = b_1
> -b@@LIBSAMPLE_2.0 = b_2
> -
> -.globl a
> -.type a, at function
> -a:
> -retq
> -
> -.globl b_1
> -.type b_1, at function
> -b_1:
> -retq
> -
> -.globl b_2
> -.type b_2, at function
> -b_2:
> -retq
> -
> -.globl c
> -.type c, at function
> -c:
> -retq
> -
> -.globl _start
> -_start:
> - nop
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: times
Type: application/octet-stream
Size: 1127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160718/2b5f6418/attachment.obj>
More information about the llvm-commits
mailing list