[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