[lld] r249998 - ELF2: Implement --as-needed.
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 11 18:48:13 PDT 2015
There is something missing on the test. Everything still passes if I convert
if (Body && Body->isUndefined() && !Body->isWeak())
to just
if (Body)
Cheers,
Rafael
On 11 October 2015 at 16:59, Rui Ueyama via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: ruiu
> Date: Sun Oct 11 15:59:12 2015
> New Revision: 249998
>
> URL: http://llvm.org/viewvc/llvm-project?rev=249998&view=rev
> Log:
> ELF2: Implement --as-needed.
>
> This patch adds AsNeeded and IsUsed bool fields to SharedFile. AsNeeded bit
> is set if the DSO is enclosed with --as-needed and --no-as-needed. IsUsed
> bit is off by default. When we adds a symbol to the symbol table for dynamic
> linking, we set its SharedFile's IsUsed bit.
>
> If AsNeeded is set but IsUsed is not set, we don't want to write that
> file's SO name to DT_NEEDED field.
>
> http://reviews.llvm.org/D13579
>
> Added:
> lld/trunk/test/elf2/Inputs/shared2.s
> lld/trunk/test/elf2/Inputs/shared3.s
> lld/trunk/test/elf2/as-needed.s
> Modified:
> lld/trunk/ELF/Config.h
> lld/trunk/ELF/Driver.cpp
> lld/trunk/ELF/InputFiles.cpp
> lld/trunk/ELF/InputFiles.h
> lld/trunk/ELF/InputSection.cpp
> lld/trunk/ELF/LinkerScript.cpp
> lld/trunk/ELF/Options.td
> lld/trunk/ELF/OutputSections.cpp
> lld/trunk/ELF/Symbols.h
> lld/trunk/ELF/Writer.cpp
>
> Modified: lld/trunk/ELF/Config.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Config.h (original)
> +++ lld/trunk/ELF/Config.h Sun Oct 11 15:59:12 2015
> @@ -43,6 +43,7 @@ struct Configuration {
> std::string RPath;
> std::vector<llvm::StringRef> SearchPaths;
> bool AllowMultipleDefinition;
> + bool AsNeeded = false;
> bool DiscardAll;
> bool DiscardLocals;
> bool DiscardNone;
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Sun Oct 11 15:59:12 2015
> @@ -100,9 +100,12 @@ void LinkerDriver::addFile(StringRef Pat
> }
> Files.push_back(make_unique<ArchiveFile>(MBRef));
> return;
> - case file_magic::elf_shared_object:
> - Files.push_back(createELFFile<SharedFile>(MBRef));
> + case file_magic::elf_shared_object: {
> + std::unique_ptr<ELFFileBase> File = createELFFile<SharedFile>(MBRef);
> + cast<SharedFileBase>(File.get())->AsNeeded = Config->AsNeeded;
> + Files.push_back(std::move(File));
> return;
> + }
> default:
> Files.push_back(createELFFile<ObjectFile>(MBRef));
> }
> @@ -187,6 +190,12 @@ void LinkerDriver::createFiles(opt::Inpu
> case OPT_script:
> addFile(Arg->getValue());
> break;
> + case OPT_as_needed:
> + Config->AsNeeded = true;
> + break;
> + case OPT_no_as_needed:
> + Config->AsNeeded = false;
> + break;
> case OPT_Bstatic:
> Config->Static = true;
> break;
>
> Modified: lld/trunk/ELF/InputFiles.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.cpp (original)
> +++ lld/trunk/ELF/InputFiles.cpp Sun Oct 11 15:59:12 2015
> @@ -329,7 +329,7 @@ template <class ELFT> void SharedFile<EL
> error(NameOrErr.getError());
> StringRef Name = *NameOrErr;
>
> - SymbolBodies.emplace_back(Name, Sym);
> + SymbolBodies.emplace_back(this, Name, Sym);
> }
> }
>
>
> Modified: lld/trunk/ELF/InputFiles.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.h (original)
> +++ lld/trunk/ELF/InputFiles.h Sun Oct 11 15:59:12 2015
> @@ -146,7 +146,7 @@ public:
> uint32_t FirstNonLocal = this->Symtab->sh_info;
> if (SymbolIndex < FirstNonLocal)
> return nullptr;
> - return SymbolBodies[SymbolIndex - FirstNonLocal]->repl();
> + return SymbolBodies[SymbolIndex - FirstNonLocal];
> }
>
> Elf_Sym_Range getLocalSymbols();
> @@ -198,6 +198,11 @@ public:
> StringRef getSoName() const { return SoName; }
> virtual void parseSoName() = 0;
> virtual void parse() = 0;
> +
> + // Used for --as-needed
> + bool AsNeeded = false;
> + bool IsUsed = false;
> + bool isNeeded() const { return !AsNeeded || IsUsed; }
> };
>
> template <class ELFT>
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Sun Oct 11 15:59:12 2015
> @@ -46,7 +46,7 @@ void InputSection<ELFT>::relocate(
> continue;
> SymVA = getLocalSymVA(Sym, File);
> } else {
> - SymbolBody &Body = *File.getSymbolBody(SymIndex);
> + SymbolBody &Body = *File.getSymbolBody(SymIndex)->repl();
> SymVA = getSymVA<ELFT>(Body);
> if (Target->relocNeedsPlt(Type, Body)) {
> SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
>
> Modified: lld/trunk/ELF/LinkerScript.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.cpp (original)
> +++ lld/trunk/ELF/LinkerScript.cpp Sun Oct 11 15:59:12 2015
> @@ -155,12 +155,15 @@ void LinkerScript::addFile(StringRef S)
>
> void LinkerScript::readAsNeeded() {
> expect("(");
> + bool Orig = Config->AsNeeded;
> + Config->AsNeeded = true;
> for (;;) {
> StringRef Tok = next();
> if (Tok == ")")
> - return;
> + break;
> addFile(Tok);
> }
> + Config->AsNeeded = Orig;
> }
>
> void LinkerScript::readEntry() {
>
> Modified: lld/trunk/ELF/Options.td
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Options.td (original)
> +++ lld/trunk/ELF/Options.td Sun Oct 11 15:59:12 2015
> @@ -14,6 +14,8 @@ def allow_multiple_definition: Flag<["--
>
> def allow_shlib_undefined : Flag<["--", "-"], "allow-shlib-undefined">;
>
> +def as_needed : Flag<["--"], "as-needed">;
> +
> def disable_new_dtags : Flag<["--"], "disable-new-dtags">,
> HelpText<"Disable new dynamic tags">;
>
> @@ -52,6 +54,8 @@ def m : Separate<["-"], "m">,
>
> def no_allow_shlib_undefined : Flag<["--"], "no-allow-shlib-undefined">;
>
> +def no_as_needed : Flag<["--"], "no-as-needed">;
> +
> def no_whole_archive : Flag<["--"], "no-whole-archive">,
> HelpText<"Restores the default behavior of loading archive members">;
>
> @@ -111,14 +115,12 @@ def alias_undefined_u : Separate<["-"],
>
> // Options listed below are silently ignored now.
> def O3 : Flag<["-"], "O3">;
> -def as_needed : Flag<["--"], "as-needed">;
> def build_id : Flag<["--"], "build-id">;
> def eh_frame_hdr : Flag<["--"], "eh-frame-hdr">;
> def end_group : Flag<["--"], "end-group">;
> def gc_sections : Flag<["--"], "gc-sections">;
> def hash_style : Joined<["--"], "hash-style=">;
> def no_add_needed : Flag<["--"], "no-add-needed">;
> -def no_as_needed : Flag<["--"], "no-as-needed">;
> def no_fatal_warnings : Flag<["--"], "no-fatal-warnings">;
> def start_group : Flag<["--"], "start-group">;
> def strip_all : Flag<["--"], "strip-all">;
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Sun Oct 11 15:59:12 2015
> @@ -116,8 +116,10 @@ template <class ELFT> void RelocationSec
> OutputSection<ELFT> *OutSec = C.getOutputSection();
> uint32_t SymIndex = RI.getSymbol(IsMips64EL);
> const ObjectFile<ELFT> &File = *C.getFile();
> - const SymbolBody *Body = File.getSymbolBody(SymIndex);
> + SymbolBody *Body = File.getSymbolBody(SymIndex);
> const ELFFile<ELFT> &Obj = File.getObj();
> + if (Body)
> + Body = Body->repl();
>
> uint32_t Type = RI.getType(IsMips64EL);
>
> @@ -279,6 +281,8 @@ template <class ELFT> void DynamicSectio
> NumEntries += 2;
>
> for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles()) {
> + if (!F->isNeeded())
> + continue;
> Out<ELFT>::DynStrTab->add(F->getSoName());
> ++NumEntries;
> }
> @@ -356,7 +360,8 @@ template <class ELFT> void DynamicSectio
> WriteArray(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, FiniArraySec);
>
> for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles())
> - WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->getFileOff(F->getSoName()));
> + if (F->isNeeded())
> + WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->getFileOff(F->getSoName()));
>
> if (InitSym)
> WritePtr(DT_INIT, getSymVA<ELFT>(*InitSym));
>
> Modified: lld/trunk/ELF/Symbols.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Sun Oct 11 15:59:12 2015
> @@ -24,6 +24,7 @@ class InputFile;
> class SymbolBody;
> template <class ELFT> class ObjectFile;
> template <class ELFT> class OutputSection;
> +template <class ELFT> class SharedFile;
>
> // Initializes global objects defined in this file.
> // Called at the beginning of main().
> @@ -263,8 +264,10 @@ public:
> return S->kind() == Base::SharedKind;
> }
>
> - SharedSymbol(StringRef Name, const Elf_Sym &Sym)
> - : Defined<ELFT>(Base::SharedKind, Name, Sym) {}
> + SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)
> + : Defined<ELFT>(Base::SharedKind, Name, Sym), File(F) {}
> +
> + SharedFile<ELFT> *File;
> };
>
> // This class represents a symbol defined in an archive file. It is
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249998&r1=249997&r2=249998&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Sun Oct 11 15:59:12 2015
> @@ -174,6 +174,14 @@ void Writer<ELFT>::scanRelocs(
> uint32_t SymIndex = RI.getSymbol(IsMips64EL);
> SymbolBody *Body = File.getSymbolBody(SymIndex);
> uint32_t Type = RI.getType(IsMips64EL);
> +
> + // Set "used" bit for --as-needed.
> + if (Body && Body->isUndefined() && !Body->isWeak())
> + if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl()))
> + S->File->IsUsed = true;
> +
> + if (Body)
> + Body = Body->repl();
> if (Body) {
> if (Target->relocNeedsPlt(Type, *Body)) {
> if (Body->isInPlt())
> @@ -186,12 +194,13 @@ void Writer<ELFT>::scanRelocs(
> Out<ELFT>::Got->addEntry(Body);
> }
> }
> - if (canBePreempted(Body)) {
> +
> + bool CBP = canBePreempted(Body);
> + if (!CBP && (!Config->Shared || Target->isRelRelative(Type)))
> + continue;
> + if (CBP)
> Body->setUsedInDynamicReloc();
> - Out<ELFT>::RelaDyn->addReloc({C, RI});
> - } else if (Config->Shared && !Target->isRelRelative(Type)) {
> - Out<ELFT>::RelaDyn->addReloc({C, RI});
> - }
> + Out<ELFT>::RelaDyn->addReloc({C, RI});
> }
> }
>
>
> Added: lld/trunk/test/elf2/Inputs/shared2.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/shared2.s?rev=249998&view=auto
> ==============================================================================
> --- lld/trunk/test/elf2/Inputs/shared2.s (added)
> +++ lld/trunk/test/elf2/Inputs/shared2.s Sun Oct 11 15:59:12 2015
> @@ -0,0 +1,6 @@
> +.global bar2
> +.type bar2, @function
> +bar2:
> +
> +.global zed2
> +zed2:
>
> Added: lld/trunk/test/elf2/Inputs/shared3.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/shared3.s?rev=249998&view=auto
> ==============================================================================
> --- lld/trunk/test/elf2/Inputs/shared3.s (added)
> +++ lld/trunk/test/elf2/Inputs/shared3.s Sun Oct 11 15:59:12 2015
> @@ -0,0 +1,3 @@
> +.global baz
> +.type barz, @function
> +baz:
>
> Added: lld/trunk/test/elf2/as-needed.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/as-needed.s?rev=249998&view=auto
> ==============================================================================
> --- lld/trunk/test/elf2/as-needed.s (added)
> +++ lld/trunk/test/elf2/as-needed.s Sun Oct 11 15:59:12 2015
> @@ -0,0 +1,43 @@
> +// REQUIRES: x86
> +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
> +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
> +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared2.s -o %t3.o
> +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared3.s -o %t4.o
> +// RUN: ld.lld2 -shared %t2.o -soname shared1 -o %t2.so
> +// RUN: ld.lld2 -shared %t3.o -soname shared2 -o %t3.so
> +// RUN: ld.lld2 -shared %t4.o -soname shared3 -o %t4.so
> +
> +/// Check if --as-needed actually works.
> +
> +// RUN: ld.lld2 %t.o %t2.so %t3.so %t4.so -o %t2
> +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
> +
> +// RUN: ld.lld2 --as-needed %t.o %t2.so %t3.so %t4.so -o %t2
> +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
> +
> +// RUN: ld.lld2 --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2
> +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
> +
> +/// GROUP directive is the same as --as-needed.
> +
> +// RUN: echo "GROUP(" %t2.so %t3.so %t4.so ")" > %t.script
> +// RUN: ld.lld2 %t.o %t.script -o %t2
> +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
> +
> +// RUN: echo "GROUP(AS_NEEDED(" %t2.so %t3.so %t4.so "))" > %t.script
> +// RUN: ld.lld2 %t.o %t.script -o %t2
> +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
> +
> +// CHECK: NEEDED SharedLibrary (shared1)
> +// CHECK: NEEDED SharedLibrary (shared2)
> +// CHECK: NEEDED SharedLibrary (shared3)
> +
> +// CHECK2: NEEDED SharedLibrary (shared1)
> +// CHECK2-NOT: NEEDED SharedLibrary (shared2)
> +// CHECK2-NOT: NEEDED SharedLibrary (shared3)
> +
> +.global _start
> +_start:
> +.long bar
> +.long zed
> +.weak baz
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list