[lld] r265293 - Don't store an Elf_Sym for most symbols.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 4 12:18:07 PDT 2016


Nice change. Thank you for doing this.

On Mon, Apr 4, 2016 at 7:04 AM, Rafael Espindola via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: rafael
> Date: Mon Apr  4 09:04:16 2016
> New Revision: 265293
>
> URL: http://llvm.org/viewvc/llvm-project?rev=265293&view=rev
> Log:
> Don't store an Elf_Sym for most symbols.
>
> Our symbol representation was redundant, and some times would get out of
> sync. It had an Elf_Sym, but some fields were copied to SymbolBody.
>
> Different parts of the code were checking the bits in SymbolBody and
> others were checking Elf_Sym.
>
> There are two general approaches to fix this:
> * Copy the required information and don't store and Elf_Sym.
> * Don't copy the information and always use the Elf_Smy.
>
> The second way sounds tempting, but has a big problem: we would have to
> template SymbolBody. I started doing it, but it requires templeting
> *everything* and creates a bit chicken and egg problem at the driver
> where we have to find ELFT before we can create an ArchiveFile for
> example.
>
> As much as possible I compared the test differences with what gold and
> bfd produce to make sure they are still valid. In most cases we are just
> adding hidden visibility to a local symbol, which is harmless.
>
> In most tests this is a small speedup. The only slowdown was scylla
> (1.006X). The largest speedup was clang with no --build-id, -O3 or
> --gc-sections (i.e.: focus on the relocations): 1.019X.
>
> Modified:
>     lld/trunk/ELF/Driver.cpp
>     lld/trunk/ELF/ICF.cpp
>     lld/trunk/ELF/InputFiles.cpp
>     lld/trunk/ELF/InputFiles.h
>     lld/trunk/ELF/InputSection.cpp
>     lld/trunk/ELF/InputSection.h
>     lld/trunk/ELF/MarkLive.cpp
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/ELF/SymbolTable.cpp
>     lld/trunk/ELF/SymbolTable.h
>     lld/trunk/ELF/Symbols.cpp
>     lld/trunk/ELF/Symbols.h
>     lld/trunk/ELF/Target.cpp
>     lld/trunk/ELF/Writer.cpp
>     lld/trunk/test/ELF/aarch64-gnu-ifunc.s
>     lld/trunk/test/ELF/basic-mips.s
>     lld/trunk/test/ELF/global_offset_table_shared.s
>     lld/trunk/test/ELF/gnu-ifunc-i386.s
>     lld/trunk/test/ELF/gnu-ifunc.s
>     lld/trunk/test/ELF/mips-gp-disp.s
>     lld/trunk/test/ELF/mips-hilo-gp-disp.s
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Mon Apr  4 09:04:16 2016
> @@ -366,17 +366,7 @@ void LinkerDriver::createFiles(opt::Inpu
>      error("no input files.");
>  }
>
> -template <class ELFT> static void initSymbols() {
> -  ElfSym<ELFT>::Etext.setBinding(STB_GLOBAL);
> -  ElfSym<ELFT>::Edata.setBinding(STB_GLOBAL);
> -  ElfSym<ELFT>::End.setBinding(STB_GLOBAL);
> -  ElfSym<ELFT>::Ignored.setBinding(STB_WEAK);
> -  ElfSym<ELFT>::Ignored.setVisibility(STV_HIDDEN);
> -}
> -
>  template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
> -  initSymbols<ELFT>();
> -
>    SymbolTable<ELFT> Symtab;
>    std::unique_ptr<TargetInfo> TI(createTarget());
>    Target = TI.get();
> @@ -390,21 +380,6 @@ template <class ELFT> void LinkerDriver:
>        Config->EMachine != EM_AMDGPU)
>      Config->Entry = Config->EMachine == EM_MIPS ? "__start" : "_start";
>
> -  // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
> -  // is magical and is used to produce a R_386_GOTPC relocation.
> -  // The R_386_GOTPC relocation value doesn't actually depend on the
> -  // symbol value, so it could use an index of STN_UNDEF which, according
> -  // to the spec, means the symbol value is 0.
> -  // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol
> in
> -  // the object file.
> -  // The situation is even stranger on x86_64 where the assembly doesn't
> -  // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
> -  // an undefined symbol in the .o files.
> -  // Given that the symbol is effectively unused, we just create a dummy
> -  // hidden one to avoid the undefined symbol error.
> -  if (!Config->Relocatable)
> -    Symtab.addIgnored("_GLOBAL_OFFSET_TABLE_");
> -
>    if (!Config->Entry.empty()) {
>      // Set either EntryAddr (if S is a number) or EntrySym (otherwise).
>      StringRef S = Config->Entry;
> @@ -413,20 +388,11 @@ template <class ELFT> void LinkerDriver:
>    }
>
>    if (Config->EMachine == EM_MIPS) {
> -    // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset
> between
> -    // start of function and 'gp' pointer into GOT.
> -    Config->MipsGpDisp = Symtab.addIgnored("_gp_disp");
> -    // The __gnu_local_gp is a magic symbol equal to the current value of
> 'gp'
> -    // pointer. This symbol is used in the code generated by .cpload
> pseudo-op
> -    // in case of using -mno-shared option.
> -    // https://sourceware.org/ml/binutils/2004-12/msg00094.html
> -    Config->MipsLocalGp = Symtab.addIgnored("__gnu_local_gp");
> -
>      // Define _gp for MIPS. st_value of _gp symbol will be updated by
> Writer
>      // so that it points to an absolute address which is relative to GOT.
>      // See "Global Data Symbols" in Chapter 6 in the following document:
>      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
> -    Symtab.addAbsolute("_gp", ElfSym<ELFT>::MipsGp);
> +    ElfSym<ELFT>::MipsGp = Symtab.addAbsolute("_gp", STV_DEFAULT);
>    }
>
>    for (std::unique_ptr<InputFile> &F : Files)
>
> Modified: lld/trunk/ELF/ICF.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/ICF.cpp (original)
> +++ lld/trunk/ELF/ICF.cpp Mon Apr  4 09:04:16 2016
> @@ -132,7 +132,7 @@ template <class ELFT> uint64_t ICF<ELFT>
>
>  // Returns true if Sec is subject of ICF.
>  template <class ELFT> bool ICF<ELFT>::isEligible(InputSectionBase<ELFT>
> *Sec) {
> -  if (!Sec || Sec == InputSection<ELFT>::Discarded || !Sec->Live)
> +  if (!Sec || Sec == &InputSection<ELFT>::Discarded || !Sec->Live)
>      return false;
>    auto *S = dyn_cast<InputSection<ELFT>>(Sec);
>    if (!S)
> @@ -270,7 +270,7 @@ bool ICF<ELFT>::variableEq(const InputSe
>      auto *DB = dyn_cast<DefinedRegular<ELFT>>(&SB);
>      if (!DA || !DB)
>        return false;
> -    if (DA->Sym.st_value != DB->Sym.st_value)
> +    if (DA->Value != DB->Value)
>        return false;
>      InputSection<ELFT> *X = dyn_cast<InputSection<ELFT>>(DA->Section);
>      InputSection<ELFT> *Y = dyn_cast<InputSection<ELFT>>(DB->Section);
>
> Modified: lld/trunk/ELF/InputFiles.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.cpp (original)
> +++ lld/trunk/ELF/InputFiles.cpp Mon Apr  4 09:04:16 2016
> @@ -175,18 +175,18 @@ void elf::ObjectFile<ELFT>::initializeSe
>    const ELFFile<ELFT> &Obj = this->ELFObj;
>    for (const Elf_Shdr &Sec : Obj.sections()) {
>      ++I;
> -    if (Sections[I] == InputSection<ELFT>::Discarded)
> +    if (Sections[I] == &InputSection<ELFT>::Discarded)
>        continue;
>
>      switch (Sec.sh_type) {
>      case SHT_GROUP:
> -      Sections[I] = InputSection<ELFT>::Discarded;
> +      Sections[I] = &InputSection<ELFT>::Discarded;
>        if (ComdatGroups.insert(getShtGroupSignature(Sec)).second)
>          continue;
>        for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
>          if (SecIndex >= Size)
>            fatal("invalid section index in group");
> -        Sections[SecIndex] = InputSection<ELFT>::Discarded;
> +        Sections[SecIndex] = &InputSection<ELFT>::Discarded;
>        }
>        break;
>      case SHT_SYMTAB:
> @@ -242,7 +242,7 @@ elf::ObjectFile<ELFT>::getRelocTarget(co
>    // Strictly speaking, a relocation section must be included in the
>    // group of the section it relocates. However, LLVM 3.3 and earlier
>    // would fail to do so, so we gracefully handle that case.
> -  if (Target == InputSection<ELFT>::Discarded)
> +  if (Target == &InputSection<ELFT>::Discarded)
>      return nullptr;
>
>    if (!Target)
> @@ -260,7 +260,7 @@ elf::ObjectFile<ELFT>::createInputSectio
>    // is controlled only by the command line option (-z execstack) in LLD,
>    // .note.GNU-stack is ignored.
>    if (Name == ".note.GNU-stack")
> -    return InputSection<ELFT>::Discarded;
> +    return &InputSection<ELFT>::Discarded;
>
>    if (Name == ".note.GNU-split-stack")
>      error("objects using splitstacks are not supported");
> @@ -299,19 +299,20 @@ elf::ObjectFile<ELFT>::getSection(const
>    if (Index >= Sections.size() || !Sections[Index])
>      fatal("invalid section index");
>    InputSectionBase<ELFT> *S = Sections[Index];
> -  if (S == InputSectionBase<ELFT>::Discarded)
> +  if (S == &InputSectionBase<ELFT>::Discarded)
>      return S;
>    return S->Repl;
>  }
>
>  template <class ELFT>
>  SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
> +  uint32_t NameOffset = Sym->st_name;
>    unsigned char Binding = Sym->getBinding();
>    InputSectionBase<ELFT> *Sec = getSection(*Sym);
>    if (Binding == STB_LOCAL) {
> -    if (Sec == InputSection<ELFT>::Discarded)
> -      Sec = nullptr;
> -    return new (Alloc) DefinedRegular<ELFT>("", *Sym, Sec);
> +    if (Sym->st_shndx == SHN_UNDEF)
> +      return new (Alloc) UndefinedElf<ELFT>(NameOffset, *Sym);
> +    return new (Alloc) DefinedRegular<ELFT>(NameOffset, *Sym, Sec);
>    }
>
>    StringRef Name = check(Sym->getName(this->StringTable));
> @@ -320,9 +321,8 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
>    case SHN_UNDEF:
>      return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
>    case SHN_COMMON:
> -    return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value,
> -                                     Sym->getBinding() ==
> llvm::ELF::STB_WEAK,
> -                                     Sym->getVisibility());
> +    return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value,
> Binding,
> +                                     Sym->st_other, Sym->getType());
>    }
>
>    switch (Binding) {
> @@ -331,7 +331,7 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
>    case STB_GLOBAL:
>    case STB_WEAK:
>    case STB_GNU_UNIQUE:
> -    if (Sec == InputSection<ELFT>::Discarded)
> +    if (Sec == &InputSection<ELFT>::Discarded)
>        return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
>      return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
>    }
> @@ -426,6 +426,9 @@ template <class ELFT> void SharedFile<EL
>    uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
>    SymbolBodies.reserve(NumSymbols);
>    for (const Elf_Sym &Sym : Syms) {
> +    // FIXME: We should probably just err if we get a local symbol in
> here.
> +    if (Sym.getBinding() == STB_LOCAL)
> +      continue;
>      StringRef Name = check(Sym.getName(this->StringTable));
>      if (Sym.isUndefined())
>        Undefs.push_back(Name);
> @@ -479,11 +482,13 @@ BitcodeFile::createSymbolBody(const Dens
>      const DataLayout &DL = M.getDataLayout();
>      uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
>      Body = new (Alloc)
> -        DefinedCommon(NameRef, Size, GV->getAlignment(), IsWeak,
> Visibility);
> +        DefinedCommon(NameRef, Size, GV->getAlignment(),
> +                      IsWeak ? STB_WEAK : STB_GLOBAL, Visibility,
> /*Type*/ 0);
>    } else {
>      Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
>    }
> -  Body->IsTls = GV->isThreadLocal();
> +  if (GV->isThreadLocal())
> +    Body->Type = STT_TLS;
>    return Body;
>  }
>
>
> Modified: lld/trunk/ELF/InputFiles.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.h (original)
> +++ lld/trunk/ELF/InputFiles.h Mon Apr  4 09:04:16 2016
> @@ -129,7 +129,7 @@ public:
>
>    // The number is the offset in the string table. It will be used as the
>    // st_name of the symbol.
> -  std::vector<std::pair<const Elf_Sym *, unsigned>> KeptLocalSyms;
> +  std::vector<std::pair<const DefinedRegular<ELFT> *, unsigned>>
> KeptLocalSyms;
>
>  private:
>    void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups);
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Mon Apr  4 09:04:16 2016
> @@ -72,8 +72,9 @@ typename ELFT::uint InputSectionBase<ELF
>  }
>
>  template <class ELFT>
> -typename ELFT::uint InputSectionBase<ELFT>::getOffset(const Elf_Sym &Sym)
> {
> -  return getOffset(Sym.st_value);
> +typename ELFT::uint
> +InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) {
> +  return getOffset(Sym.Value);
>  }
>
>  // Returns a section that Rel relocation is pointing to.
> @@ -305,7 +306,7 @@ void InputSectionBase<ELFT>::relocate(ui
>          SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc);
>        else
>          SymVA = Body.getGotVA<ELFT>() + A;
> -      if (Body.IsTls)
> +      if (Body.isTls())
>          Type = Target->getTlsGotRel(Type);
>      } else if (Target->isSizeRel(Type) && Body.isPreemptible()) {
>        // A SIZE relocation is supposed to set a symbol size, but if a
> symbol
>
> Modified: lld/trunk/ELF/InputSection.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputSection.h (original)
> +++ lld/trunk/ELF/InputSection.h Mon Apr  4 09:04:16 2016
> @@ -19,6 +19,7 @@ namespace lld {
>  namespace elf {
>
>  template <class ELFT> class ICF;
> +template <class ELFT> class DefinedRegular;
>  template <class ELFT> class ObjectFile;
>  template <class ELFT> class OutputSection;
>  template <class ELFT> class OutputSectionBase;
> @@ -40,6 +41,8 @@ public:
>    enum Kind { Regular, EHFrame, Merge, MipsReginfo };
>    Kind SectionKind;
>
> +  InputSectionBase() : Repl(this) {}
> +
>    InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
>                     Kind SectionKind);
>    OutputSectionBase<ELFT> *OutSec = nullptr;
> @@ -58,12 +61,12 @@ public:
>    // Returns the size of this section (even if this is a common or BSS.)
>    size_t getSize() const;
>
> -  static InputSectionBase<ELFT> *Discarded;
> +  static InputSectionBase<ELFT> Discarded;
>
>    StringRef getSectionName() const;
>    const Elf_Shdr *getSectionHdr() const { return Header; }
>    ObjectFile<ELFT> *getFile() const { return File; }
> -  uintX_t getOffset(const Elf_Sym &Sym);
> +  uintX_t getOffset(const DefinedRegular<ELFT> &Sym);
>
>    // Translate an offset in the input section to an offset in the output
>    // section.
> @@ -85,9 +88,7 @@ private:
>                                 const RelTy *Rel, const RelTy *End);
>  };
>
> -template <class ELFT>
> -InputSectionBase<ELFT> *
> -    InputSectionBase<ELFT>::Discarded = (InputSectionBase<ELFT> *)-1ULL;
> +template <class ELFT> InputSectionBase<ELFT>
> InputSectionBase<ELFT>::Discarded;
>
>  // Usually sections are copied to the output as atomic chunks of data,
>  // but some special types of sections are split into small pieces of data
>
> Modified: lld/trunk/ELF/MarkLive.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/MarkLive.cpp (original)
> +++ lld/trunk/ELF/MarkLive.cpp Mon Apr  4 09:04:16 2016
> @@ -124,7 +124,7 @@ template <class ELFT> void elf::markLive
>    // script KEEP command.
>    for (const std::unique_ptr<ObjectFile<ELFT>> &F :
> Symtab->getObjectFiles())
>      for (InputSectionBase<ELFT> *Sec : F->getSections())
> -      if (Sec && Sec != InputSection<ELFT>::Discarded)
> +      if (Sec && Sec != &InputSection<ELFT>::Discarded)
>          if (isReserved(Sec) || Script->shouldKeep<ELFT>(Sec))
>            Enqueue(Sec);
>
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Mon Apr  4 09:04:16 2016
> @@ -1426,22 +1426,23 @@ void SymbolTableSection<ELFT>::writeLoca
>    // Iterate over all input object files to copy their local symbols
>    // to the output symbol table pointed by Buf.
>    for (const std::unique_ptr<ObjectFile<ELFT>> &File :
> Table.getObjectFiles()) {
> -    for (const std::pair<const Elf_Sym *, size_t> &P :
> File->KeptLocalSyms) {
> -      const Elf_Sym *Sym = P.first;
> -
> +    for (const std::pair<const DefinedRegular<ELFT> *, size_t> &P :
> +         File->KeptLocalSyms) {
> +      const DefinedRegular<ELFT> &Body = *P.first;
> +      InputSectionBase<ELFT> *Section = Body.Section;
>        auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
> -      if (Sym->st_shndx == SHN_ABS) {
> +
> +      if (!Section) {
>          ESym->st_shndx = SHN_ABS;
> -        ESym->st_value = Sym->st_value;
> +        ESym->st_value = Body.Value;
>        } else {
> -        InputSectionBase<ELFT> *Section = File->getSection(*Sym);
>          const OutputSectionBase<ELFT> *OutSec = Section->OutSec;
>          ESym->st_shndx = OutSec->SectionIndex;
> -        ESym->st_value = OutSec->getVA() + Section->getOffset(*Sym);
> +        ESym->st_value = OutSec->getVA() + Section->getOffset(Body);
>        }
>        ESym->st_name = P.second;
> -      ESym->st_size = Sym->st_size;
> -      ESym->setBindingAndType(Sym->getBinding(), Sym->getType());
> +      ESym->st_size = Body.template getSize<ELFT>();
> +      ESym->setBindingAndType(Body.Binding, Body.Type);
>        Buf += sizeof(*ESym);
>      }
>    }
> @@ -1456,15 +1457,8 @@ void SymbolTableSection<ELFT>::writeGlob
>      SymbolBody *Body = P.first;
>      size_t StrOff = P.second;
>
> -    uint8_t Type = STT_NOTYPE;
> -    uintX_t Size = 0;
> -    if (const Elf_Sym *InputSym = Body->getElfSym<ELFT>()) {
> -      Type = InputSym->getType();
> -      Size = InputSym->st_size;
> -    } else if (auto *C = dyn_cast<DefinedCommon>(Body)) {
> -      Type = STT_OBJECT;
> -      Size = C->Size;
> -    }
> +    uint8_t Type = Body->Type;
> +    uintX_t Size = Body->getSize<ELFT>();
>
>      ESym->setBindingAndType(getSymbolBinding(Body), Type);
>      ESym->st_size = Size;
> @@ -1521,11 +1515,9 @@ uint8_t SymbolTableSection<ELFT>::getSym
>    uint8_t Visibility = Body->getVisibility();
>    if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
>      return STB_LOCAL;
> -  if (const Elf_Sym *ESym = Body->getElfSym<ELFT>())
> -    return ESym->getBinding();
>    if (isa<DefinedSynthetic<ELFT>>(Body))
>      return STB_LOCAL;
> -  return Body->isWeak() ? STB_WEAK : STB_GLOBAL;
> +  return Body->Binding;
>  }
>
>  template <class ELFT>
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Mon Apr  4 09:04:16 2016
> @@ -135,9 +135,10 @@ SymbolBody *SymbolTable<ELFT>::addUndefi
>  }
>
>  template <class ELFT>
> -SymbolBody *SymbolTable<ELFT>::addAbsolute(StringRef Name, Elf_Sym &ESym)
> {
> +DefinedRegular<ELFT> *SymbolTable<ELFT>::addAbsolute(StringRef Name,
> +                                                     uint8_t Visibility) {
>    // Pass nullptr because absolute symbols have no corresponding input
> sections.
> -  auto *Sym = new (Alloc) DefinedRegular<ELFT>(Name, ESym, nullptr);
> +  auto *Sym = new (Alloc) DefinedRegular<ELFT>(Name, STB_GLOBAL,
> Visibility);
>    resolve(Sym);
>    return Sym;
>  }
> @@ -152,11 +153,13 @@ SymbolBody *SymbolTable<ELFT>::addSynthe
>  }
>
>  // Add Name as an "ignored" symbol. An ignored symbol is a regular
> -// linker-synthesized defined symbol, but it is not recorded to the output
> -// file's symbol table. Such symbols are useful for some linker-defined
> symbols.
> +// linker-synthesized defined symbol, but is only defined if needed.
>  template <class ELFT>
> -SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) {
> -  return addAbsolute(Name, ElfSym<ELFT>::Ignored);
> +DefinedRegular<ELFT> *SymbolTable<ELFT>::addIgnored(StringRef Name,
> +                                                    uint8_t Visibility) {
> +  if (!find(Name))
> +    return nullptr;
> +  return addAbsolute(Name, Visibility);
>  }
>
>  // Rename SYM as __wrap_SYM. The original symbol is preserved as
> __real_SYM.
> @@ -228,7 +231,7 @@ template <class ELFT> void SymbolTable<E
>      return;
>    }
>
> -  if (New->IsTls != Existing->IsTls) {
> +  if (New->isTls() != Existing->isTls()) {
>      error("TLS attribute mismatch for symbol: " + conflictMsg(Existing,
> New));
>      return;
>    }
> @@ -286,10 +289,10 @@ void SymbolTable<ELFT>::addMemberFile(Un
>    // symbols and copy information to reduce how many special cases are
> needed.
>    if (Undef->isWeak()) {
>      L->setUsedInRegularObj();
> -    L->setWeak();
> +    L->Binding = Undef->Binding;
> +    L->Type = Undef->Type;
>
>      // FIXME: Do we need to copy more?
> -    L->IsTls |= Undef->IsTls;
>      return;
>    }
>
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Mon Apr  4 09:04:16 2016
> @@ -53,21 +53,23 @@ public:
>
>    SymbolBody *addUndefined(StringRef Name);
>    SymbolBody *addUndefinedOpt(StringRef Name);
> -  SymbolBody *addAbsolute(StringRef Name, Elf_Sym &ESym);
> +  DefinedRegular<ELFT> *addAbsolute(StringRef Name,
> +                                    uint8_t Visibility =
> llvm::ELF::STV_HIDDEN);
>    SymbolBody *addSynthetic(StringRef Name, OutputSectionBase<ELFT>
> &Section,
>                             uintX_t Value, uint8_t Visibility);
> -  SymbolBody *addIgnored(StringRef Name);
> +  DefinedRegular<ELFT> *addIgnored(StringRef Name,
> +                                   uint8_t Visibility =
> llvm::ELF::STV_HIDDEN);
>
>    void scanShlibUndefined();
>    SymbolBody *find(StringRef Name);
>    void wrap(StringRef Name);
>    InputFile *findFile(SymbolBody *B);
> +  void resolve(SymbolBody *Body);
>
>  private:
>    Symbol *insert(SymbolBody *New);
>    void addLazy(Lazy *New);
>    void addMemberFile(Undefined *Undef, Lazy *L);
> -  void resolve(SymbolBody *Body);
>

Why did you change the visibility of resolve() function?


>    std::string conflictMsg(SymbolBody *Old, SymbolBody *New);
>
>    // The order the global symbols are in is not defined. We can use an
> arbitrary
>
> Modified: lld/trunk/ELF/Symbols.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Symbols.cpp (original)
> +++ lld/trunk/ELF/Symbols.cpp Mon Apr  4 09:04:16 2016
> @@ -31,7 +31,6 @@ using namespace lld::elf;
>  template <class ELFT>
>  static typename ELFT::uint getSymVA(const SymbolBody &Body,
>                                      typename ELFT::uint &Addend) {
> -  typedef typename ELFT::Sym Elf_Sym;
>    typedef typename ELFT::uint uintX_t;
>
>    switch (Body.kind()) {
> @@ -45,18 +44,24 @@ static typename ELFT::uint getSymVA(cons
>      auto &D = cast<DefinedRegular<ELFT>>(Body);
>      InputSectionBase<ELFT> *SC = D.Section;
>
> +    // According to the ELF spec reference to a local symbol from outside
> +    // the group are not allowed. Unfortunately .eh_frame breaks that rule
> +    // and must be treated specially. For now we just replace the symbol
> with
> +    // 0.
> +    if (SC == &InputSection<ELFT>::Discarded)
> +      return 0;
> +
>      // This is an absolute symbol.
>      if (!SC)
> -      return D.Sym.st_value;
> +      return D.Value;
>
> -    const Elf_Sym &Sym = D.Sym;
> -    uintX_t Offset = Sym.st_value;
> -    if (Sym.getType() == STT_SECTION) {
> +    uintX_t Offset = D.Value;
> +    if (D.isSection()) {
>        Offset += Addend;
>        Addend = 0;
>      }
>      uintX_t VA = SC->OutSec->getVA() + SC->getOffset(Offset);
> -    if (Sym.getType() == STT_TLS)
> +    if (D.isTls())
>        return VA - Out<ELFT>::TlsPhdr->p_vaddr;
>      return VA;
>    }
> @@ -66,7 +71,7 @@ static typename ELFT::uint getSymVA(cons
>      auto &SS = cast<SharedSymbol<ELFT>>(Body);
>      if (!SS.NeedsCopyOrPltAddr)
>        return 0;
> -    if (SS.IsFunc)
> +    if (SS.isFunc())
>        return Body.getPltVA<ELFT>();
>      return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
>    }
> @@ -82,6 +87,13 @@ static typename ELFT::uint getSymVA(cons
>    llvm_unreachable("invalid symbol kind");
>  }
>
> +SymbolBody::SymbolBody(Kind K, uint32_t NameOffset, uint8_t Other,
> uint8_t Type)
> +    : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
> +      Type(Type), Binding(STB_LOCAL), Other(Other),
> NameOffset(NameOffset) {
> +  IsUsedInRegularObj =
> +      K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;
> +}
> +
>  // Returns true if a symbol can be replaced at load-time by a symbol
>  // with the same name defined in other ELF executable or DSO.
>  bool SymbolBody::isPreemptible() const {
> @@ -109,7 +121,7 @@ bool SymbolBody::isPreemptible() const {
>      return false;
>    if (getVisibility() != STV_DEFAULT)
>      return false;
> -  if (Config->Bsymbolic || (Config->BsymbolicFunctions && IsFunc))
> +  if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
>      return false;
>    return true;
>  }
> @@ -143,21 +155,17 @@ template <class ELFT> typename ELFT::uin
>  }
>
>  template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
> -  if (const typename ELFT::Sym *Sym = getElfSym<ELFT>())
> -    return Sym->st_size;
> +  if (const auto *C = dyn_cast<DefinedCommon>(this))
> +    return C->Size;
> +  if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
> +    return DR->Size;
> +  if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
> +    return S->Sym.st_size;
> +  if (const auto *U = dyn_cast<UndefinedElf<ELFT>>(this))
> +    return U->Size;
>    return 0;
>  }
>
> -template <class ELFT> const typename ELFT::Sym *SymbolBody::getElfSym()
> const {
> -  if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))
> -    return &S->Sym;
> -  if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
> -    return &S->Sym;
> -  if (auto *S = dyn_cast<UndefinedElf<ELFT>>(this))
> -    return &S->Sym;
> -  return nullptr;
> -}
> -
>  static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
>    if (VA == STV_DEFAULT)
>      return VB;
> @@ -185,8 +193,9 @@ template <class ELFT> int SymbolBody::co
>    if (L > R)
>      return -Other->compare<ELFT>(this);
>
> -  Visibility = Other->Visibility =
> -      getMinVisibility(Visibility, Other->Visibility);
> +  uint8_t V = getMinVisibility(getVisibility(), Other->getVisibility());
> +  setVisibility(V);
> +  Other->setVisibility(V);
>
>    if (IsUsedInRegularObj || Other->IsUsedInRegularObj)
>      IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
> @@ -212,48 +221,61 @@ template <class ELFT> int SymbolBody::co
>    return isCommon() ? -1 : 1;
>  }
>
> -Defined::Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal,
> -                 uint8_t Visibility, uint8_t Type)
> -    : SymbolBody(K, Name, IsWeak, IsLocal, Visibility, Type) {}
> +Defined::Defined(Kind K, StringRef Name, uint8_t Binding, uint8_t
> Visibility,
> +                 uint8_t Type)
> +    : SymbolBody(K, Name, Binding, Visibility, Type) {}
> +
> +Defined::Defined(Kind K, uint32_t NameOffset, uint8_t Visibility, uint8_t
> Type)
> +    : SymbolBody(K, NameOffset, Visibility, Type) {}
>
>  DefinedBitcode::DefinedBitcode(StringRef Name, bool IsWeak, uint8_t
> Visibility)
> -    : Defined(DefinedBitcodeKind, Name, IsWeak, false, Visibility,
> -              0 /* Type */) {}
> +    : Defined(DefinedBitcodeKind, Name, IsWeak ? STB_WEAK : STB_GLOBAL,
> +              Visibility, 0 /* Type */) {}
>
>  bool DefinedBitcode::classof(const SymbolBody *S) {
>    return S->kind() == DefinedBitcodeKind;
>  }
>
> -Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,
> +Undefined::Undefined(SymbolBody::Kind K, StringRef N, uint8_t Binding,
> +                     uint8_t Other, uint8_t Type)
> +    : SymbolBody(K, N, Binding, Other, Type), CanKeepUndefined(false) {}
> +
> +Undefined::Undefined(SymbolBody::Kind K, uint32_t NameOffset,
>                       uint8_t Visibility, uint8_t Type)
> -    : SymbolBody(K, N, IsWeak, false, Visibility, Type),
> -      CanKeepUndefined(false) {}
> +    : SymbolBody(K, NameOffset, Visibility, Type),
> CanKeepUndefined(false) {}
>
>  Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
>                       bool CanKeepUndefined)
> -    : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility, 0 /*
> Type */) {
> +    : Undefined(SymbolBody::UndefinedKind, N, IsWeak ? STB_WEAK :
> STB_GLOBAL,
> +                Visibility, 0 /* Type */) {
>    this->CanKeepUndefined = CanKeepUndefined;
>  }
>
>  template <typename ELFT>
>  UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)
> -    : Undefined(SymbolBody::UndefinedElfKind, N,
> -                Sym.getBinding() == llvm::ELF::STB_WEAK,
> Sym.getVisibility(),
> +    : Undefined(SymbolBody::UndefinedElfKind, N, Sym.getBinding(),
> Sym.st_other,
>                  Sym.getType()),
> -      Sym(Sym) {}
> +      Size(Sym.st_size) {}
> +
> +template <typename ELFT>
> +UndefinedElf<ELFT>::UndefinedElf(uint32_t NameOffset, const Elf_Sym &Sym)
> +    : Undefined(SymbolBody::UndefinedElfKind, NameOffset, Sym.st_other,
> +                Sym.getType()),
> +      Size(Sym.st_size) {
> +  assert(Sym.getBinding() == STB_LOCAL);
> +}
>
>  template <typename ELFT>
>  DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
>                                           OutputSectionBase<ELFT> &Section,
>                                           uint8_t Visibility)
> -    : Defined(SymbolBody::DefinedSyntheticKind, N, false, false,
> Visibility,
> +    : Defined(SymbolBody::DefinedSyntheticKind, N, STB_GLOBAL, Visibility,
>                0 /* Type */),
>        Value(Value), Section(Section) {}
>
>  DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t
> Alignment,
> -                             bool IsWeak, uint8_t Visibility)
> -    : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, false, Visibility,
> -              0 /* Type */),
> +                             uint8_t Binding, uint8_t Visibility, uint8_t
> Type)
> +    : Defined(SymbolBody::DefinedCommonKind, N, Binding, Visibility,
> Type),
>        Alignment(Alignment), Size(Size) {}
>
>  std::unique_ptr<InputFile> Lazy::getMember() {
> @@ -317,11 +339,6 @@ template uint32_t SymbolBody::template g
>  template uint64_t SymbolBody::template getSize<ELF64LE>() const;
>  template uint64_t SymbolBody::template getSize<ELF64BE>() const;
>
> -template const ELF32LE::Sym *SymbolBody::template getElfSym<ELF32LE>()
> const;
> -template const ELF32BE::Sym *SymbolBody::template getElfSym<ELF32BE>()
> const;
> -template const ELF64LE::Sym *SymbolBody::template getElfSym<ELF64LE>()
> const;
> -template const ELF64BE::Sym *SymbolBody::template getElfSym<ELF64BE>()
> const;
> -
>  template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
>  template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
>  template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;
>
> Modified: lld/trunk/ELF/Symbols.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Mon Apr  4 09:04:16 2016
> @@ -62,7 +62,7 @@ public:
>
>    Kind kind() const { return static_cast<Kind>(SymbolKind); }
>
> -  bool isWeak() const { return IsWeak; }
> +  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
>    bool isUndefined() const {
>      return SymbolKind == UndefinedKind || SymbolKind == UndefinedElfKind;
>    }
> @@ -70,14 +70,21 @@ public:
>    bool isCommon() const { return SymbolKind == DefinedCommonKind; }
>    bool isLazy() const { return SymbolKind == LazyKind; }
>    bool isShared() const { return SymbolKind == SharedKind; }
> -  bool isLocal() const { return IsLocal; }
> +  bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
>    bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
>    bool isPreemptible() const;
>
>    // Returns the symbol name.
> -  StringRef getName() const { return Name; }
> +  StringRef getName() const {
> +    assert(!isLocal());
> +    return Name;
> +  }
> +  uint32_t getNameOffset() const {
> +    assert(isLocal());
> +    return NameOffset;
> +  }
>
> -  uint8_t getVisibility() const { return Visibility; }
> +  uint8_t getVisibility() const { return Other & 0x3; }
>
>    unsigned DynsymIndex = 0;
>    uint32_t GlobalDynIndex = -1;
> @@ -100,7 +107,6 @@ public:
>    template <class ELFT> typename ELFT::uint getPltVA() const;
>    template <class ELFT> typename ELFT::uint getThunkVA() const;
>    template <class ELFT> typename ELFT::uint getSize() const;
> -  template <class ELFT> const typename ELFT::Sym *getElfSym() const;
>
>    // A SymbolBody has a backreference to a Symbol. Originally they are
>    // doubly-linked. A backreference will never change. But the pointer
> @@ -118,21 +124,18 @@ public:
>    template <class ELFT> int compare(SymbolBody *Other);
>
>  protected:
> -  SymbolBody(Kind K, StringRef Name, bool IsWeak, bool IsLocal,
> -             uint8_t Visibility, uint8_t Type)
> -      : SymbolKind(K), IsWeak(IsWeak), IsLocal(IsLocal),
> Visibility(Visibility),
> -        MustBeInDynSym(false), NeedsCopyOrPltAddr(false), Name(Name) {
> -    IsFunc = Type == llvm::ELF::STT_FUNC;
> -    IsTls = Type == llvm::ELF::STT_TLS;
> -    IsGnuIFunc = Type == llvm::ELF::STT_GNU_IFUNC;
> +  SymbolBody(Kind K, StringRef Name, uint8_t Binding, uint8_t Other,
> +             uint8_t Type)
> +      : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
> +        Type(Type), Binding(Binding), Other(Other), Name(Name) {
> +    assert(!isLocal());
>      IsUsedInRegularObj =
>          K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;
>    }
>
> +  SymbolBody(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type);
> +
>    const unsigned SymbolKind : 8;
> -  unsigned IsWeak : 1;
> -  unsigned IsLocal : 1;
> -  unsigned Visibility : 2;
>
>    // True if the symbol was used for linking and thus need to be
>    // added to the output file's symbol table. It is usually true,
> @@ -148,34 +151,44 @@ public:
>    // symbol or if the symbol should point to its plt entry.
>    unsigned NeedsCopyOrPltAddr : 1;
>
> -  unsigned IsTls : 1;
> -  unsigned IsFunc : 1;
> -  unsigned IsGnuIFunc : 1;
> +  uint8_t Type;
> +  uint8_t Binding;
> +  uint8_t Other;
> +  bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
> +  bool isTls() const { return Type == llvm::ELF::STT_TLS; }
> +  bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
> +  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; }
> +  void setVisibility(uint8_t V) { Other = (Other & ~0x3) | V; }
>
>  protected:
> -  StringRef Name;
> +  union {
> +    StringRef Name;
> +    uint32_t NameOffset;
> +  };
>    Symbol *Backref = nullptr;
>  };
>
>  // The base class for any defined symbols.
>  class Defined : public SymbolBody {
>  public:
> -  Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal, uint8_t
> Visibility,
> -          uint8_t Type);
> +  Defined(Kind K, StringRef Name, uint8_t Binding, uint8_t Other, uint8_t
> Type);
> +  Defined(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type);
>    static bool classof(const SymbolBody *S) { return S->isDefined(); }
>  };
>
>  // The defined symbol in LLVM bitcode files.
>  class DefinedBitcode : public Defined {
>  public:
> -  DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Visibility);
> +  DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Other);
>    static bool classof(const SymbolBody *S);
>  };
>
>  class DefinedCommon : public Defined {
>  public:
> -  DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, bool
> IsWeak,
> -                uint8_t Visibility);
> +  DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, uint8_t
> Binding,
> +                uint8_t Other, uint8_t Type);
>
>    static bool classof(const SymbolBody *S) {
>      return S->kind() == SymbolBody::DefinedCommonKind;
> @@ -194,21 +207,36 @@ public:
>  // Regular defined symbols read from object file symbol tables.
>  template <class ELFT> class DefinedRegular : public Defined {
>    typedef typename ELFT::Sym Elf_Sym;
> +  typedef typename ELFT::uint uintX_t;
>
>  public:
>    DefinedRegular(StringRef Name, const Elf_Sym &Sym,
>                   InputSectionBase<ELFT> *Section)
> -      : Defined(SymbolBody::DefinedRegularKind, Name,
> -                Sym.getBinding() == llvm::ELF::STB_WEAK,
> -                Sym.getBinding() == llvm::ELF::STB_LOCAL,
> -                Sym.getVisibility(), Sym.getType()),
> -        Sym(Sym), Section(Section ? Section->Repl : NullInputSection) {}
> +      : Defined(SymbolBody::DefinedRegularKind, Name, Sym.getBinding(),
> +                Sym.st_other, Sym.getType()),
> +        Value(Sym.st_value), Size(Sym.st_size),
> +        Section(Section ? Section->Repl : NullInputSection) {}
> +
> +  DefinedRegular(uint32_t NameOffset, const Elf_Sym &Sym,
> +                 InputSectionBase<ELFT> *Section)
> +      : Defined(SymbolBody::DefinedRegularKind, NameOffset, Sym.st_other,
> +                Sym.getType()),
> +        Value(Sym.st_value), Size(Sym.st_size),
> +        Section(Section ? Section->Repl : NullInputSection) {
> +    assert(isLocal());
> +  }
> +
> +  DefinedRegular(StringRef Name, uint8_t Binding, uint8_t Other)
> +      : Defined(SymbolBody::DefinedRegularKind, Name, Binding, Other,
> +                llvm::ELF::STT_NOTYPE),
> +        Value(0), Size(0), Section(NullInputSection) {}
>
>    static bool classof(const SymbolBody *S) {
>      return S->kind() == SymbolBody::DefinedRegularKind;
>    }
>
> -  const Elf_Sym &Sym;
> +  uintX_t Value;
> +  uintX_t Size;
>
>    // The input section this symbol belongs to. Notice that this is
>    // a reference to a pointer. We are using two levels of indirections
> @@ -231,10 +259,9 @@ InputSectionBase<ELFT> *DefinedRegular<E
>  // takes an output section to calculate output VA, etc.
>  template <class ELFT> class DefinedSynthetic : public Defined {
>  public:
> -  typedef typename ELFT::Sym Elf_Sym;
>    typedef typename ELFT::uint uintX_t;
>    DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase<ELFT>
> &Section,
> -                   uint8_t Visibility);
> +                   uint8_t Other);
>
>    static bool classof(const SymbolBody *S) {
>      return S->kind() == SymbolBody::DefinedSyntheticKind;
> @@ -254,11 +281,11 @@ class Undefined : public SymbolBody {
>    bool CanKeepUndefined;
>
>  protected:
> -  Undefined(Kind K, StringRef N, bool IsWeak, uint8_t Visibility, uint8_t
> Type);
> +  Undefined(Kind K, StringRef N, uint8_t Binding, uint8_t Other, uint8_t
> Type);
> +  Undefined(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type);
>
>  public:
> -  Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
> -            bool CanKeepUndefined);
> +  Undefined(StringRef N, bool IsWeak, uint8_t Other, bool
> CanKeepUndefined);
>
>    static bool classof(const SymbolBody *S) { return S->isUndefined(); }
>
> @@ -266,11 +293,14 @@ public:
>  };
>
>  template <class ELFT> class UndefinedElf : public Undefined {
> +  typedef typename ELFT::uint uintX_t;
>    typedef typename ELFT::Sym Elf_Sym;
>
>  public:
>    UndefinedElf(StringRef N, const Elf_Sym &Sym);
> -  const Elf_Sym &Sym;
> +  UndefinedElf(uint32_t NameOffset, const Elf_Sym &Sym);
> +
> +  uintX_t Size;
>
>    static bool classof(const SymbolBody *S) {
>      return S->kind() == SymbolBody::UndefinedElfKind;
> @@ -287,10 +317,8 @@ public:
>    }
>
>    SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)
> -      : Defined(SymbolBody::SharedKind, Name,
> -                Sym.getBinding() == llvm::ELF::STB_WEAK,
> -                Sym.getBinding() == llvm::ELF::STB_LOCAL,
> -                Sym.getVisibility(), Sym.getType()),
> +      : Defined(SymbolBody::SharedKind, Name, Sym.getBinding(),
> Sym.st_other,
> +                Sym.getType()),
>          File(F), Sym(Sym) {}
>
>    SharedFile<ELFT> *File;
> @@ -299,7 +327,7 @@ public:
>    // OffsetInBss is significant only when needsCopy() is true.
>    uintX_t OffsetInBss = 0;
>
> -  bool needsCopy() const { return this->NeedsCopyOrPltAddr &&
> !this->IsFunc; }
> +  bool needsCopy() const { return this->NeedsCopyOrPltAddr &&
> !this->isFunc(); }
>  };
>
>  // This class represents a symbol defined in an archive file. It is
> @@ -310,8 +338,8 @@ public:
>  class Lazy : public SymbolBody {
>  public:
>    Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S)
> -      : SymbolBody(LazyKind, S.getName(), false, false,
> llvm::ELF::STV_DEFAULT,
> -                   /* Type */ 0),
> +      : SymbolBody(LazyKind, S.getName(), llvm::ELF::STB_GLOBAL,
> +                   llvm::ELF::STV_DEFAULT, /* Type */ 0),
>          File(F), Sym(S) {}
>
>    static bool classof(const SymbolBody *S) { return S->kind() ==
> LazyKind; }
> @@ -320,48 +348,44 @@ public:
>    // was already returned.
>    std::unique_ptr<InputFile> getMember();
>
> -  void setWeak() { IsWeak = true; }
> -
>  private:
>    ArchiveFile *File;
>    const llvm::object::Archive::Symbol Sym;
>  };
>
>  // Some linker-generated symbols need to be created as
> -// DefinedRegular symbols, so they need Elf_Sym symbols.
> -// Here we allocate such Elf_Sym symbols statically.
> +// DefinedRegular symbols.
>  template <class ELFT> struct ElfSym {
> -  typedef typename ELFT::Sym Elf_Sym;
> -
> -  // Used to represent an undefined symbol which we don't want to add to
> the
> -  // output file's symbol table. It has weak binding and can be
> substituted.
> -  static Elf_Sym Ignored;
> -
>    // The content for _etext and etext symbols.
> -  static Elf_Sym Etext;
> +  static DefinedRegular<ELFT> *Etext;
> +  static DefinedRegular<ELFT> *Etext2;
>
>    // The content for _edata and edata symbols.
> -  static Elf_Sym Edata;
> +  static DefinedRegular<ELFT> *Edata;
> +  static DefinedRegular<ELFT> *Edata2;
>
>    // The content for _end and end symbols.
> -  static Elf_Sym End;
> +  static DefinedRegular<ELFT> *End;
> +  static DefinedRegular<ELFT> *End2;
>
>    // The content for _gp symbol for MIPS target.
> -  static Elf_Sym MipsGp;
> +  static DefinedRegular<ELFT> *MipsGp;
>
>    // __rel_iplt_start/__rel_iplt_end for signaling
>    // where R_[*]_IRELATIVE relocations do live.
> -  static Elf_Sym RelaIpltStart;
> -  static Elf_Sym RelaIpltEnd;
> +  static DefinedRegular<ELFT> *RelaIpltStart;
> +  static DefinedRegular<ELFT> *RelaIpltEnd;
>  };
>
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::Ignored;
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::Etext;
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::Edata;
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::End;
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::MipsGp;
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::RelaIpltStart;
> -template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::RelaIpltEnd;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Etext;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Etext2;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata2;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End2;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsGp;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::RelaIpltStart;
> +template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::RelaIpltEnd;
>
>  } // namespace elf
>  } // namespace lld
>
> Modified: lld/trunk/ELF/Target.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Target.cpp (original)
> +++ lld/trunk/ELF/Target.cpp Mon Apr  4 09:04:16 2016
> @@ -248,7 +248,7 @@ uint64_t TargetInfo::getImplicitAddend(c
>  }
>
>  bool TargetInfo::canRelaxTls(uint32_t Type, const SymbolBody *S) const {
> -  if (Config->Shared || (S && !S->IsTls))
> +  if (Config->Shared || (S && !S->isTls()))
>      return false;
>
>    // We know we are producing an executable.
> @@ -280,7 +280,7 @@ template <typename ELFT> static bool may
>    auto *SS = dyn_cast<SharedSymbol<ELFT>>(&S);
>    if (!SS)
>      return false;
> -  return SS->Sym.getType() == STT_OBJECT;
> +  return SS->isObject();
>  }
>
>  template <class ELFT>
> @@ -303,7 +303,7 @@ bool TargetInfo::refersToGotEntry(uint32
>
>  TargetInfo::PltNeed TargetInfo::needsPlt(uint32_t Type,
>                                           const SymbolBody &S) const {
> -  if (S.IsGnuIFunc)
> +  if (S.isGnuIFunc())
>      return Plt_Explicit;
>    if (S.isPreemptible() && needsPltImpl(Type))
>      return Plt_Explicit;
> @@ -330,7 +330,7 @@ TargetInfo::PltNeed TargetInfo::needsPlt
>    // plt. That is identified by special relocation types
> (R_X86_64_JUMP_SLOT,
>    // R_386_JMP_SLOT, etc).
>    if (S.isShared())
> -    if (!Config->Pic && S.IsFunc && !refersToGotEntry(Type))
> +    if (!Config->Pic && S.isFunc() && !refersToGotEntry(Type))
>        return Plt_Implicit;
>
>    return Plt_No;
> @@ -500,7 +500,7 @@ bool X86TargetInfo::needsCopyRelImpl(uin
>  }
>
>  bool X86TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
> -  if (S.IsTls && Type == R_386_TLS_GD)
> +  if (S.isTls() && Type == R_386_TLS_GD)
>      return Target->canRelaxTls(Type, &S) && S.isPreemptible();
>    if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)
>      return !canRelaxTls(Type, &S);
> @@ -1762,7 +1762,7 @@ bool MipsTargetInfo<ELFT>::needsThunk(ui
>    // LA25 is required if target file has PIC code
>    // or target symbol is a PIC symbol.
>    return (D->Section->getFile()->getObj().getHeader()->e_flags &
> EF_MIPS_PIC) ||
> -         (D->Sym.st_other & STO_MIPS_MIPS16) == STO_MIPS_PIC;
> +         (D->Other & STO_MIPS_MIPS16) == STO_MIPS_PIC;
>  }
>
>  template <class ELFT>
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Mon Apr  4 09:04:16 2016
> @@ -287,7 +287,7 @@ static unsigned handleTlsRelocation(uint
>      return 1;
>    }
>
> -  if (!Body.IsTls)
> +  if (!Body.isTls())
>      return 0;
>
>    if (Target->isTlsGlobalDynamicRel(Type)) {
> @@ -403,7 +403,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
>        Out<ELFT>::Plt->addEntry(Body);
>
>        uint32_t Rel;
> -      if (Body.IsGnuIFunc)
> +      if (Body.isGnuIFunc())
>          Rel = Preemptible ? Target->PltRel : Target->IRelativeRel;
>        else
>          Rel = Target->UseLazyBinding ? Target->PltRel : Target->GotRel;
> @@ -440,7 +440,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
>                      !Target->isSizeRel(Type);
>        if (Preemptible || Dynrel) {
>          uint32_t DynType;
> -        if (Body.IsTls)
> +        if (Body.isTls())
>            DynType = Target->TlsGotRel;
>          else if (Preemptible)
>            DynType = Target->GotRel;
> @@ -525,23 +525,17 @@ static void reportUndefined(SymbolTable<
>  }
>
>  template <class ELFT>
> -static bool shouldKeepInSymtab(const elf::ObjectFile<ELFT> &File,
> -                               StringRef SymName,
> -                               const typename ELFT::Sym &Sym) {
> -  if (Sym.getType() == STT_FILE)
> +static bool shouldKeepInSymtab(InputSectionBase<ELFT> *Sec, StringRef
> SymName,
> +                               const SymbolBody &B) {
> +  if (B.isFile())
>      return false;
>
>    // We keep sections in symtab for relocatable output.
> -  if (Sym.getType() == STT_SECTION)
> +  if (B.isSection())
>      return Config->Relocatable;
>
> -  // No reason to keep local undefined symbol in symtab.
> -  if (Sym.st_shndx == SHN_UNDEF)
> -    return false;
> -
> -  InputSectionBase<ELFT> *Sec = File.getSection(Sym);
>    // If sym references a section in a discarded group, don't keep it.
> -  if (Sec == InputSection<ELFT>::Discarded)
> +  if (Sec == &InputSection<ELFT>::Discarded)
>      return false;
>
>    if (Config->DiscardNone)
> @@ -568,18 +562,23 @@ template <class ELFT> void Writer<ELFT>:
>      return;
>    for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
>         Symtab.getObjectFiles()) {
> +    const char *StrTab = F->getStringTable().data();
>      for (SymbolBody *B : F->getLocalSymbols()) {
> -      const Elf_Sym &Sym = cast<DefinedRegular<ELFT>>(B)->Sym;
> -      StringRef SymName = check(Sym.getName(F->getStringTable()));
> -      if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
> +      auto *DR = dyn_cast<DefinedRegular<ELFT>>(B);
> +      // No reason to keep local undefined symbol in symtab.
> +      if (!DR)
>          continue;
> -      if (Sym.st_shndx != SHN_ABS && !F->getSection(Sym)->Live)
> +      StringRef SymName(StrTab + B->getNameOffset());
> +      InputSectionBase<ELFT> *Sec = DR->Section;
> +      if (!shouldKeepInSymtab<ELFT>(Sec, SymName, *B))
> +        continue;
> +      if (Sec && !Sec->Live)
>          continue;
>        ++Out<ELFT>::SymTab->NumLocals;
>        if (Config->Relocatable)
>          B->DynsymIndex = Out<ELFT>::SymTab->NumLocals;
> -      F->KeptLocalSyms.push_back(std::make_pair(
> -          &Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
> +      F->KeptLocalSyms.push_back(
> +          std::make_pair(DR,
> Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
>      }
>    }
>  }
> @@ -754,7 +753,7 @@ void Writer<ELFT>::addCopyRelSymbols(std
>      uintX_t Align = getAlignment(SS);
>      Off = alignTo(Off, Align);
>      SS->OffsetInBss = Off;
> -    Off += SS->Sym.st_size;
> +    Off += SS->template getSize<ELFT>();
>      MaxAlign = std::max(MaxAlign, Align);
>    }
>    Out<ELFT>::Bss->setSize(Off);
> @@ -787,7 +786,7 @@ void reportDiscarded(InputSectionBase<EL
>
>  template <class ELFT>
>  bool Writer<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) const {
> -  return !S || S == InputSection<ELFT>::Discarded || !S->Live ||
> +  return !S || S == &InputSection<ELFT>::Discarded || !S->Live ||
>           Script->isDiscarded(S);
>  }
>
> @@ -802,12 +801,10 @@ void Writer<ELFT>::addRelIpltSymbols() {
>    if (isOutputDynamic() || !Out<ELFT>::RelaPlt)
>      return;
>    StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
> -  if (Symtab.find(S))
> -    Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltStart);
> +  ElfSym<ELFT>::RelaIpltStart = Symtab.addIgnored(S);
>
>    S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
> -  if (Symtab.find(S))
> -    Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltEnd);
> +  ElfSym<ELFT>::RelaIpltEnd = Symtab.addIgnored(S);
>  }
>
>  template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
> @@ -815,9 +812,6 @@ template <class ELFT> static bool includ
>      return false;
>
>    if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B)) {
> -    // Don't include synthetic symbols like __init_array_start in every
> output.
> -    if (&D->Sym == &ElfSym<ELFT>::Ignored)
> -      return false;
>      // Exclude symbols pointing to garbage-collected sections.
>      if (D->Section && !D->Section->Live)
>        return false;
> @@ -922,6 +916,32 @@ OutputSectionFactory<ELFT>::createKey(In
>  // The linker is expected to define some symbols depending on
>  // the linking result. This function defines such symbols.
>  template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
> +  if (Config->EMachine == EM_MIPS) {
> +    // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset
> between
> +    // start of function and 'gp' pointer into GOT.
> +    Config->MipsGpDisp = Symtab.addIgnored("_gp_disp");
> +    // The __gnu_local_gp is a magic symbol equal to the current value of
> 'gp'
> +    // pointer. This symbol is used in the code generated by .cpload
> pseudo-op
> +    // in case of using -mno-shared option.
> +    // https://sourceware.org/ml/binutils/2004-12/msg00094.html
> +    Config->MipsLocalGp = Symtab.addIgnored("__gnu_local_gp");
> +  }
> +
> +  // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
> +  // is magical and is used to produce a R_386_GOTPC relocation.
> +  // The R_386_GOTPC relocation value doesn't actually depend on the
> +  // symbol value, so it could use an index of STN_UNDEF which, according
> +  // to the spec, means the symbol value is 0.
> +  // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol
> in
> +  // the object file.
> +  // The situation is even stranger on x86_64 where the assembly doesn't
> +  // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
> +  // an undefined symbol in the .o files.
> +  // Given that the symbol is effectively unused, we just create a dummy
> +  // hidden one to avoid the undefined symbol error.
> +  if (!Config->Relocatable)
> +    Symtab.addIgnored("_GLOBAL_OFFSET_TABLE_");
> +
>    // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
>    // static linking the linker is required to optimize away any
> references to
>    // __tls_get_addr, so it's not defined anywhere. Create a hidden
> definition
> @@ -929,9 +949,9 @@ template <class ELFT> void Writer<ELFT>:
>    if (!isOutputDynamic())
>      Symtab.addIgnored("__tls_get_addr");
>
> -  auto Define = [this](StringRef S, Elf_Sym &Sym) {
> -    if (Symtab.find(S))
> -      Symtab.addAbsolute(S, Sym);
> +  auto Define = [this](StringRef S, DefinedRegular<ELFT> *&Sym,
> +                       DefinedRegular<ELFT> *&Sym2) {
> +    Sym = Symtab.addIgnored(S, STV_DEFAULT);
>
>      // The name without the underscore is not a reserved name,
>      // so it is defined only when there is a reference against it.
> @@ -939,12 +959,12 @@ template <class ELFT> void Writer<ELFT>:
>      S = S.substr(1);
>      if (SymbolBody *B = Symtab.find(S))
>        if (B->isUndefined())
> -        Symtab.addAbsolute(S, Sym);
> +        Sym2 = Symtab.addAbsolute(S, STV_DEFAULT);
>    };
>
> -  Define("_end", ElfSym<ELFT>::End);
> -  Define("_etext", ElfSym<ELFT>::Etext);
> -  Define("_edata", ElfSym<ELFT>::Edata);
> +  Define("_end", ElfSym<ELFT>::End, ElfSym<ELFT>::End2);
> +  Define("_etext", ElfSym<ELFT>::Etext, ElfSym<ELFT>::Etext2);
> +  Define("_edata", ElfSym<ELFT>::Edata, ElfSym<ELFT>::Edata2);
>  }
>
>  // Sort input sections by section name suffixes for
> @@ -1467,13 +1487,15 @@ template <class ELFT> void Writer<ELFT>:
>    // to beginning or ending of .rela.plt section, respectively.
>    if (Out<ELFT>::RelaPlt) {
>      uintX_t Start = Out<ELFT>::RelaPlt->getVA();
> -    ElfSym<ELFT>::RelaIpltStart.st_value = Start;
> -    ElfSym<ELFT>::RelaIpltEnd.st_value = Start +
> Out<ELFT>::RelaPlt->getSize();
> +    if (ElfSym<ELFT>::RelaIpltStart)
> +      ElfSym<ELFT>::RelaIpltStart->Value = Start;
> +    if (ElfSym<ELFT>::RelaIpltEnd)
> +      ElfSym<ELFT>::RelaIpltEnd->Value = Start +
> Out<ELFT>::RelaPlt->getSize();
>    }
>
>    // Update MIPS _gp absolute symbol so that it points to the static data.
>    if (Config->EMachine == EM_MIPS)
> -    ElfSym<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
> +    ElfSym<ELFT>::MipsGp->Value = getMipsGpAddr<ELFT>();
>
>    // _etext is the first location after the last read-only loadable
> segment.
>    // _edata is the first location after the last read-write loadable
> segment.
> @@ -1482,12 +1504,24 @@ template <class ELFT> void Writer<ELFT>:
>      Elf_Phdr &H = P.H;
>      if (H.p_type != PT_LOAD)
>        continue;
> -    ElfSym<ELFT>::End.st_value = H.p_vaddr + H.p_memsz;
> -    uintX_t Val = H.p_vaddr + H.p_filesz;
> -    if (H.p_flags & PF_W)
> -      ElfSym<ELFT>::Edata.st_value = Val;
> -    else
> -      ElfSym<ELFT>::Etext.st_value = Val;
> +    uintX_t Val = H.p_vaddr + H.p_memsz;
> +    if (ElfSym<ELFT>::End)
> +      ElfSym<ELFT>::End->Value = Val;
> +    if (ElfSym<ELFT>::End2)
> +      ElfSym<ELFT>::End2->Value = Val;
> +
> +    Val = H.p_vaddr + H.p_filesz;
> +    if (H.p_flags & PF_W) {
> +      if (ElfSym<ELFT>::Edata)
> +        ElfSym<ELFT>::Edata->Value = Val;
> +      if (ElfSym<ELFT>::Edata2)
> +        ElfSym<ELFT>::Edata2->Value = Val;
> +    } else {
> +      if (ElfSym<ELFT>::Etext)
> +        ElfSym<ELFT>::Etext->Value = Val;
> +      if (ElfSym<ELFT>::Etext2)
> +        ElfSym<ELFT>::Etext2->Value = Val;
> +    }
>    }
>  }
>
>
> Modified: lld/trunk/test/ELF/aarch64-gnu-ifunc.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-gnu-ifunc.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/aarch64-gnu-ifunc.s (original)
> +++ lld/trunk/test/ELF/aarch64-gnu-ifunc.s Mon Apr  4 09:04:16 2016
> @@ -51,7 +51,9 @@
>  // CHECK-NEXT:    Size: 0
>  // CHECK-NEXT:    Binding: Local
>  // CHECK-NEXT:    Type: None
> -// CHECK-NEXT:    Other: 0
> +// CHECK-NEXT:    Other [
> +// CHECK-NEXT:      STV_HIDDEN
> +// CHECK-NEXT:    ]
>  // CHECK-NEXT:    Section: Absolute
>  // CHECK-NEXT:  }
>  // CHECK-NEXT:  Symbol {
> @@ -60,7 +62,9 @@
>  // CHECK-NEXT:    Size: 0
>  // CHECK-NEXT:    Binding: Local
>  // CHECK-NEXT:    Type: None
> -// CHECK-NEXT:    Other: 0
> +// CHECK-NEXT:    Other [
> +// CHECK-NEXT:      STV_HIDDEN
> +// CHECK-NEXT:    ]
>  // CHECK-NEXT:    Section: Absolute
>  // CHECK-NEXT:  }
>  // CHECK-NEXT:  Symbol {
>
> Modified: lld/trunk/test/ELF/basic-mips.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/basic-mips.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/basic-mips.s (original)
> +++ lld/trunk/test/ELF/basic-mips.s Mon Apr  4 09:04:16 2016
> @@ -187,22 +187,22 @@ __start:
>  # CHECK-NEXT:     Section: Undefined (0x0)
>  # CHECK-NEXT:   }
>  # CHECK-NEXT:   Symbol {
> -# CHECK-NEXT:     Name: _gp
> -# CHECK-NEXT:     Value: 0x0
> +# CHECK-NEXT:     Name: __start
> +# CHECK-NEXT:     Value: 0x20000
>  # CHECK-NEXT:     Size: 0
> -# CHECK-NEXT:     Binding: Local (0x0)
> +# CHECK-NEXT:     Binding: Global (0x1)
>  # CHECK-NEXT:     Type: None (0x0)
>  # CHECK-NEXT:     Other: 0
> -# CHECK-NEXT:     Section: Absolute (0xFFF1)
> +# CHECK-NEXT:     Section: .text
>  # CHECK-NEXT:   }
>  # CHECK-NEXT:   Symbol {
> -# CHECK-NEXT:     Name: __start
> -# CHECK-NEXT:     Value: 0x20000
> +# CHECK-NEXT:     Name: _gp
> +# CHECK-NEXT:     Value: 0x0
>  # CHECK-NEXT:     Size: 0
> -# CHECK-NEXT:     Binding: Global (0x1)
> +# CHECK-NEXT:     Binding: Global
>  # CHECK-NEXT:     Type: None (0x0)
>  # CHECK-NEXT:     Other: 0
> -# CHECK-NEXT:     Section: .text
> +# CHECK-NEXT:     Section: Absolute (0xFFF1)
>  # CHECK-NEXT:   }
>  # CHECK-NEXT: ]
>  # CHECK-NEXT: ProgramHeaders [
>
> Modified: lld/trunk/test/ELF/global_offset_table_shared.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global_offset_table_shared.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/global_offset_table_shared.s (original)
> +++ lld/trunk/test/ELF/global_offset_table_shared.s Mon Apr  4 09:04:16
> 2016
> @@ -3,4 +3,7 @@
>  // RUN: llvm-readobj -t %t2 | FileCheck %s
>  .long _GLOBAL_OFFSET_TABLE_
>
> -// CHECK-NOT: Name: _GLOBAL_OFFSET_TABLE_
> +// CHECK:      Name: _GLOBAL_OFFSET_TABLE_
> +// CHECK-NEXT: Value:
> +// CHECK-NEXT: Size: 0
> +// CHECK-NEXT: Binding: Local
>
> Modified: lld/trunk/test/ELF/gnu-ifunc-i386.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-i386.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/gnu-ifunc-i386.s (original)
> +++ lld/trunk/test/ELF/gnu-ifunc-i386.s Mon Apr  4 09:04:16 2016
> @@ -43,7 +43,9 @@
>  // CHECK-NEXT:   Size: 0
>  // CHECK-NEXT:   Binding: Local
>  // CHECK-NEXT:   Type: None
> -// CHECK-NEXT:   Other: 0
> +// CHECK-NEXT:   Other [
> +// CHECK-NEXT:     STV_HIDDEN
> +// CHECK-NEXT:   ]
>  // CHECK-NEXT:   Section: Absolute
>  // CHECK-NEXT: }
>  // CHECK-NEXT: Symbol {
> @@ -52,7 +54,9 @@
>  // CHECK-NEXT:   Size: 0
>  // CHECK-NEXT:   Binding: Local
>  // CHECK-NEXT:   Type: None
> -// CHECK-NEXT:   Other: 0
> +// CHECK-NEXT:   Other [
> +// CHECK-NEXT:     STV_HIDDEN
> +// CHECK-NEXT:   ]
>  // CHECK-NEXT:   Section: Absolute
>  // CHECK-NEXT: }
>  // CHECK-NEXT: Symbol {
>
> Modified: lld/trunk/test/ELF/gnu-ifunc.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/gnu-ifunc.s (original)
> +++ lld/trunk/test/ELF/gnu-ifunc.s Mon Apr  4 09:04:16 2016
> @@ -42,7 +42,9 @@
>  // CHECK-NEXT:    Size: 0
>  // CHECK-NEXT:    Binding: Local
>  // CHECK-NEXT:    Type: None
> -// CHECK-NEXT:    Other: 0
> +// CHECK-NEXT:    Other [
> +// CHECK-NEXT:      STV_HIDDEN
> +// CHECK-NEXT:    ]
>  // CHECK-NEXT:    Section: Absolute
>  // CHECK-NEXT:  }
>  // CHECK-NEXT:  Symbol {
> @@ -51,7 +53,9 @@
>  // CHECK-NEXT:    Size: 0
>  // CHECK-NEXT:    Binding: Local
>  // CHECK-NEXT:    Type: None
> -// CHECK-NEXT:    Other: 0
> +// CHECK-NEXT:    Other [
> +// CHECK-NEXT:      STV_HIDDEN
> +// CHECK-NEXT:    ]
>  // CHECK-NEXT:    Section: Absolute
>  // CHECK-NEXT:  }
>  // CHECK-NEXT:  Symbol {
>
> Modified: lld/trunk/test/ELF/mips-gp-disp.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-gp-disp.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/mips-gp-disp.s (original)
> +++ lld/trunk/test/ELF/mips-gp-disp.s Mon Apr  4 09:04:16 2016
> @@ -11,7 +11,10 @@
>
>  # REQUIRES: mips
>
> -# INT-SO-NOT:  Name: _gp_disp
> +# INT-SO:      Name: _gp_disp
> +# INT-SO-NEXT: Value:
> +# INT-SO-NEXT: Size:
> +# INT-SO-NEXT: Binding: Local
>
>  # EXT-SO:      Name: _gp_disp
>  # EXT-SO-NEXT: Value: 0x20010
>
> Modified: lld/trunk/test/ELF/mips-hilo-gp-disp.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-hilo-gp-disp.s?rev=265293&r1=265292&r2=265293&view=diff
>
> ==============================================================================
> --- lld/trunk/test/ELF/mips-hilo-gp-disp.s (original)
> +++ lld/trunk/test/ELF/mips-hilo-gp-disp.s Mon Apr  4 09:04:16 2016
> @@ -25,8 +25,8 @@ __start:
>  #                                                  ^--
> %lo(0x37ff0-0x20004+4)
>
>  # EXE: SYMBOL TABLE:
> -# EXE: 00037ff0     *ABS*   00000000 _gp
>  # EXE: 00020000     .text   00000000 __start
> +# EXE: 00037ff0     *ABS*   00000000 _gp
>  # EXE: 00020010     .text   00000000 _foo
>
>  # SO:      Disassembly of section .text:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160404/e439d218/attachment.html>


More information about the llvm-commits mailing list