[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