diff options
| author | Rafael Auler <rafaelauler@gmail.com> | 2014-10-08 18:54:26 +0000 |
|---|---|---|
| committer | Rafael Auler <rafaelauler@gmail.com> | 2014-10-08 18:54:26 +0000 |
| commit | ce1af1a201c8dc05c05fd1f36a731e0a0fc5b43d (patch) | |
| tree | 521b42d4afcee5557cc967700a372e40df2cdecd /lld/lib | |
| parent | e4320f5e6a1b4cd0f41bd58afb1f96849901333f (diff) | |
| download | bcm5719-llvm-ce1af1a201c8dc05c05fd1f36a731e0a0fc5b43d.tar.gz bcm5719-llvm-ce1af1a201c8dc05c05fd1f36a731e0a0fc5b43d.zip | |
[ELF] Implement --export-dynamic/-E
When creating a dynamic executable and receiving the -E flag, the linker should
export all globally visible symbols in its dynamic symbol table.
This commit also moves the logic that exports symbols in the dynamic symbol
table from OutputELFWriter to the ExecutableWriter class. It is not correct to
leave this at OutputELFWriter because DynamicLibraryWriter, another subclass of
OutputELFWriter, already exports all symbols, meaning we can potentially end up
with duplicated symbols in the dynamic symbol table when creating shared libs.
Reviewers: shankarke
http://reviews.llvm.org/D5585
llvm-svn: 219334
Diffstat (limited to 'lld/lib')
| -rw-r--r-- | lld/lib/Driver/GnuLdDriver.cpp | 4 | ||||
| -rw-r--r-- | lld/lib/Driver/GnuLdOptions.td | 6 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ExecutableWriter.h | 20 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 9 |
4 files changed, 30 insertions, 9 deletions
diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 683bf318ef5..ded0b70e0cd 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -372,6 +372,10 @@ bool GnuLdDriver::parse(int argc, const char *argv[], ctx->setAllowRemainingUndefines(true); break; + case OPT_export_dynamic: + ctx->setExportDynamic(true); + break; + case OPT_merge_strings: ctx->setMergeCommonStrings(true); break; diff --git a/lld/lib/Driver/GnuLdOptions.td b/lld/lib/Driver/GnuLdOptions.td index 08adcc4b6ab..590ce9509aa 100644 --- a/lld/lib/Driver/GnuLdOptions.td +++ b/lld/lib/Driver/GnuLdOptions.td @@ -139,6 +139,12 @@ defm rpath : dashEq<"rpath", "rpath", def rpath_link : Separate<["-"], "rpath-link">, HelpText<"Specifies the first set of directories to search">, Group<grp_dynlibexec>; +def export_dynamic : Flag<["--"], "export-dynamic">, + HelpText<"Add all symbols to the dynamic symbol table" + " when creating executables">, + Group<grp_main>; +def alias_export_dynamic: Flag<["-"], "E">, + Alias<export_dynamic>; //===----------------------------------------------------------------------===// /// Dynamic Library Options diff --git a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h index af780b687e0..a65e8f58729 100644 --- a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h @@ -30,6 +30,7 @@ public: _runtimeFile(new CRuntimeFile<ELFT>(context)) {} protected: + virtual void buildDynamicSymbolTable(const File &file); virtual void addDefaultAtoms(); virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &); virtual void finalizeDefaultAtomValues(); @@ -41,6 +42,25 @@ protected: //===----------------------------------------------------------------------===// // ExecutableWriter //===----------------------------------------------------------------------===// +template<class ELFT> +void ExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) { + for (auto sec : this->_layout.sections()) + if (auto section = dyn_cast<AtomSection<ELFT>>(sec)) + for (const auto &atom : section->atoms()) { + const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom); + if (!da) + continue; + if (da->dynamicExport() != DefinedAtom::dynamicExportAlways && + !this->_context.isDynamicallyExportedSymbol(da->name()) && + !(this->_context.shouldExportDynamic() && + da->scope() == Atom::Scope::scopeGlobal)) + continue; + this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), + atom->_virtualAddr, atom); + } + + OutputELFWriter<ELFT>::buildDynamicSymbolTable(file); +} /// \brief Add absolute symbols by default. These are linker added /// absolute symbols diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index e7a81cc9180..30b1e573a66 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -179,15 +179,6 @@ void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) { template <class ELFT> void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) { ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable"); - for (auto sec : this->_layout.sections()) - if (auto section = dyn_cast<AtomSection<ELFT>>(sec)) - for (const auto &atom : section->atoms()) { - const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom); - if (da && (da->dynamicExport() == DefinedAtom::dynamicExportAlways || - _context.isDynamicallyExportedSymbol(da->name()))) - _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), - atom->_virtualAddr, atom); - } for (const auto &sla : file.sharedLibrary()) { if (isDynSymEntryRequired(sla)) _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); |

