[lld] r249406 - Handle strong undefined symbols fetching members after a weak undefined.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 11:25:29 PDT 2015


So, we don't want weak undefined symbols to fetch archive members, which
sounds fine, but I still doesn't get how is this related to --start-group
and --end-group in regular ELF linkers. I'm just wondering... Could you
describe a bit?

On Tue, Oct 6, 2015 at 7:33 AM, Rafael Espindola via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: rafael
> Date: Tue Oct  6 09:33:58 2015
> New Revision: 249406
>
> URL: http://llvm.org/viewvc/llvm-project?rev=249406&view=rev
> Log:
> Handle strong undefined symbols fetching members after a weak undefined.
>
> This is a case that requires --start-group --end-group with regular ELF
> linkers. Fortunately it is still possible to handle it with lazy symbols
> without
> taking a second look at archives.
>
> Thanks to Michael Spencer for the bug report.
>
> Added:
>     lld/trunk/test/elf2/Inputs/archive3.s
>     lld/trunk/test/elf2/Inputs/archive4.s
> Modified:
>     lld/trunk/ELF/InputSection.cpp
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/ELF/OutputSections.h
>     lld/trunk/ELF/SymbolTable.cpp
>     lld/trunk/ELF/Symbols.h
>     lld/trunk/test/elf2/archive.s
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=249406&r1=249405&r2=249406&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Tue Oct  6 09:33:58 2015
> @@ -49,8 +49,7 @@ void InputSection<ELFT>::relocate(
>          continue;
>        SymVA = getLocalSymVA(Sym, File);
>      } else {
> -      const auto &Body =
> -          *cast<ELFSymbolBody<ELFT>>(File.getSymbolBody(SymIndex));
> +      SymbolBody &Body = *File.getSymbolBody(SymIndex);
>        SymVA = getSymVA<ELFT>(Body, BssSec);
>        if (Target->relocNeedsPlt(Type, Body)) {
>          SymVA = PltSec.getEntryAddr(Body);
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249406&r1=249405&r2=249406&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Tue Oct  6 09:33:58 2015
> @@ -349,13 +349,14 @@ void OutputSection<ELFT>::addSection(Inp
>
>  template <class ELFT>
>  typename ELFFile<ELFT>::uintX_t
> -lld::elf2::getSymVA(const ELFSymbolBody<ELFT> &S,
> -                    const OutputSection<ELFT> &BssSec) {
> +lld::elf2::getSymVA(const SymbolBody &S, const OutputSection<ELFT>
> &BssSec) {
>    switch (S.kind()) {
> -  case SymbolBody::DefinedSyntheticKind:
> -    return cast<DefinedSynthetic<ELFT>>(S).Section.getVA() +
> S.Sym.st_value;
> +  case SymbolBody::DefinedSyntheticKind: {
> +    auto &D = cast<DefinedSynthetic<ELFT>>(S);
> +    return D.Section.getVA() + D.Sym.st_value;
> +  }
>    case SymbolBody::DefinedAbsoluteKind:
> -    return S.Sym.st_value;
> +    return cast<DefinedAbsolute<ELFT>>(S).Sym.st_value;
>    case SymbolBody::DefinedRegularKind: {
>      const auto &DR = cast<DefinedRegular<ELFT>>(S);
>      const InputSection<ELFT> *SC = &DR.Section;
> @@ -368,9 +369,9 @@ lld::elf2::getSymVA(const ELFSymbolBody<
>    case SymbolBody::UndefinedKind:
>      return 0;
>    case SymbolBody::LazyKind:
> -    break;
> +    assert(S.isUsedInRegularObj() && "Lazy symbol reached writer");
> +    return 0;
>    }
> -  llvm_unreachable("Lazy symbol reached writer");
>  }
>
>  template <class ELFT>
> @@ -409,8 +410,6 @@ void StringTableSection<Is64Bits>::write
>  }
>
>  template <class ELFT> bool lld::elf2::includeInSymtab(const SymbolBody
> &B) {
> -  if (B.isLazy())
> -    return false;
>    if (!B.isUsedInRegularObj())
>      return false;
>
> @@ -521,21 +520,20 @@ void SymbolTableSection<ELFT>::writeGlob
>      if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
>        continue;
>
> -    const auto &EBody = *cast<ELFSymbolBody<ELFT>>(Body);
> -    const Elf_Sym &InputSym = EBody.Sym;
>      auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
>      Buf += sizeof(*ESym);
> +
>      ESym->st_name = StrTabSec.getFileOff(Name);
>
>      const OutputSection<ELFT> *Out = nullptr;
>      const InputSection<ELFT> *Section = nullptr;
>
> -    switch (EBody.kind()) {
> +    switch (Body->kind()) {
>      case SymbolBody::DefinedSyntheticKind:
>        Out = &cast<DefinedSynthetic<ELFT>>(Body)->Section;
>        break;
>      case SymbolBody::DefinedRegularKind:
> -      Section = &cast<DefinedRegular<ELFT>>(EBody).Section;
> +      Section = &cast<DefinedRegular<ELFT>>(Body)->Section;
>        break;
>      case SymbolBody::DefinedCommonKind:
>        Out = &BssSec;
> @@ -543,25 +541,33 @@ void SymbolTableSection<ELFT>::writeGlob
>      case SymbolBody::UndefinedKind:
>      case SymbolBody::DefinedAbsoluteKind:
>      case SymbolBody::SharedKind:
> -      break;
>      case SymbolBody::LazyKind:
> -      llvm_unreachable("Lazy symbol got to output symbol table!");
> +      break;
>      }
>
> -    unsigned char Binding = InputSym.getBinding();
> -    unsigned char Visibility = EBody.getMostConstrainingVisibility();
> +    unsigned char Binding = Body->isWeak() ? STB_WEAK : STB_GLOBAL;
> +    unsigned char Type = STT_NOTYPE;
> +    uintX_t Size = 0;
> +    if (const auto *EBody = dyn_cast<ELFSymbolBody<ELFT>>(Body)) {
> +      const Elf_Sym &InputSym = EBody->Sym;
> +      Binding = InputSym.getBinding();
> +      Type = InputSym.getType();
> +      Size = InputSym.st_size;
> +    }
> +
> +    unsigned char Visibility = Body->getMostConstrainingVisibility();
>      if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
>        Binding = STB_LOCAL;
>
> -    ESym->setBindingAndType(Binding, InputSym.getType());
> -    ESym->st_size = InputSym.st_size;
> +    ESym->setBindingAndType(Binding, Type);
> +    ESym->st_size = Size;
>      ESym->setVisibility(Visibility);
> -    ESym->st_value = getSymVA(EBody, BssSec);
> +    ESym->st_value = getSymVA(*Body, BssSec);
>
>      if (Section)
>        Out = Section->getOutputSection();
>
> -    if (InputSym.isAbsolute())
> +    if (isa<DefinedAbsolute<ELFT>>(Body))
>        ESym->st_shndx = SHN_ABS;
>      else if (Out)
>        ESym->st_shndx = Out->getSectionIndex();
> @@ -629,17 +635,14 @@ template class SymbolTableSection<ELF32B
>  template class SymbolTableSection<ELF64LE>;
>  template class SymbolTableSection<ELF64BE>;
>
> -template ELFFile<ELF32LE>::uintX_t
> -getSymVA(const ELFSymbolBody<ELF32LE> &, const OutputSection<ELF32LE> &);
> -
> -template ELFFile<ELF32BE>::uintX_t
> -getSymVA(const ELFSymbolBody<ELF32BE> &, const OutputSection<ELF32BE> &);
> -
> -template ELFFile<ELF64LE>::uintX_t
> -getSymVA(const ELFSymbolBody<ELF64LE> &, const OutputSection<ELF64LE> &);
> -
> -template ELFFile<ELF64BE>::uintX_t
> -getSymVA(const ELFSymbolBody<ELF64BE> &, const OutputSection<ELF64BE> &);
> +template ELFFile<ELF32LE>::uintX_t getSymVA(const SymbolBody &,
> +                                            const OutputSection<ELF32LE>
> &);
> +template ELFFile<ELF32BE>::uintX_t getSymVA(const SymbolBody &,
> +                                            const OutputSection<ELF32BE>
> &);
> +template ELFFile<ELF64LE>::uintX_t getSymVA(const SymbolBody &,
> +                                            const OutputSection<ELF64LE>
> &);
> +template ELFFile<ELF64BE>::uintX_t getSymVA(const SymbolBody &,
> +                                            const OutputSection<ELF64BE>
> &);
>
>  template ELFFile<ELF32LE>::uintX_t
>  getLocalSymVA(const ELFFile<ELF32LE>::Elf_Sym *, const
> ObjectFile<ELF32LE> &);
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=249406&r1=249405&r2=249406&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Tue Oct  6 09:33:58 2015
> @@ -34,7 +34,7 @@ template <class ELFT> class ELFSymbolBod
>
>  template <class ELFT>
>  typename llvm::object::ELFFile<ELFT>::uintX_t
> -getSymVA(const ELFSymbolBody<ELFT> &S, const OutputSection<ELFT> &BssSec);
> +getSymVA(const SymbolBody &S, const OutputSection<ELFT> &BssSec);
>
>  template <class ELFT>
>  typename llvm::object::ELFFile<ELFT>::uintX_t
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=249406&r1=249405&r2=249406&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Tue Oct  6 09:33:58 2015
> @@ -256,10 +256,23 @@ void SymbolTable::addLazy(Lazy *New) {
>    if (Sym->Body == New)
>      return;
>    SymbolBody *Existing = Sym->Body;
> -  if (Existing->isDefined() || Existing->isLazy() || Existing->isWeak())
> +  if (Existing->isDefined() || Existing->isLazy())
>      return;
>    Sym->Body = New;
>    assert(Existing->isUndefined() && "Unexpected symbol kind.");
> +
> +  // Weak undefined symbols should not fetch members from archives.
> +  // If we were to keep old symbol we would not know that an archive
> member was
> +  // available if a strong undefined symbol shows up afterwards in the
> link.
> +  // If a strong undefined symbol never shows up, this lazy symbol will
> +  // get to the end of the link and must be treated as the weak undefined
> one.
> +  // We set UsedInRegularObj in a similar way to what is done with shared
> +  // symbols and mark it as weak to reduce how many special cases are
> needed.
> +  if (Existing->isWeak()) {
> +    New->setUsedInRegularObj();
> +    New->setWeak();
> +    return;
> +  }
>    addMemberFile(New);
>  }
>
>
> Modified: lld/trunk/ELF/Symbols.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=249406&r1=249405&r2=249406&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Tue Oct  6 09:33:58 2015
> @@ -103,7 +103,7 @@ protected:
>    }
>
>    const unsigned SymbolKind : 8;
> -  const unsigned IsWeak : 1;
> +  unsigned IsWeak : 1;
>    unsigned MostConstrainingVisibility : 2;
>    unsigned IsUsedInRegularObj : 1;
>    unsigned IsUsedInDynamicReloc : 1;
> @@ -282,6 +282,9 @@ public:
>    // was already returned.
>    std::unique_ptr<InputFile> getMember();
>
> +  void setWeak() { IsWeak = true; }
> +  void setUsedInRegularObj() { IsUsedInRegularObj = true; }
> +
>  private:
>    ArchiveFile *File;
>    const llvm::object::Archive::Symbol Sym;
>
> Added: lld/trunk/test/elf2/Inputs/archive3.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/archive3.s?rev=249406&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf2/Inputs/archive3.s (added)
> +++ lld/trunk/test/elf2/Inputs/archive3.s Tue Oct  6 09:33:58 2015
> @@ -0,0 +1,2 @@
> +.global bar
> +bar:
>
> Added: lld/trunk/test/elf2/Inputs/archive4.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/archive4.s?rev=249406&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf2/Inputs/archive4.s (added)
> +++ lld/trunk/test/elf2/Inputs/archive4.s Tue Oct  6 09:33:58 2015
> @@ -0,0 +1 @@
> +.quad bar
>
> Modified: lld/trunk/test/elf2/archive.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/archive.s?rev=249406&r1=249405&r2=249406&view=diff
>
> ==============================================================================
> --- lld/trunk/test/elf2/archive.s (original)
> +++ lld/trunk/test/elf2/archive.s Tue Oct  6 09:33:58 2015
> @@ -1,8 +1,10 @@
>  # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
>  # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive.s
> -o %t2
>  # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive2.s
> -o %t3
> -# RUN: llvm-ar rcs %tar %t2 %t3
> -# RUN: lld -flavor gnu2 %t %tar -o %tout
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive3.s
> -o %t4
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive4.s
> -o %t5
> +# RUN: llvm-ar rcs %tar %t2 %t3 %t4
> +# RUN: lld -flavor gnu2 %t %tar %t5 -o %tout
>  # RUN: llvm-nm %tout | FileCheck %s
>  # REQUIRES: x86
>
> @@ -13,6 +15,11 @@
>  .weak foo
>  .quad foo
>
> -# CHECK: T _start
> -# CHECK: T end
> -# CHECK: w foo
> +.weak bar
> +.quad bar
> +
> +
> +# CHECK:      T _start
> +# CHECK-NEXT: T bar
> +# CHECK-NEXT: T end
> +# CHECK-NEXT: w foo
>
>
> _______________________________________________
> 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/20151006/a73fea87/attachment.html>


More information about the llvm-commits mailing list