summaryrefslogtreecommitdiffstats
path: root/lld/lib
diff options
context:
space:
mode:
authorRafael Auler <rafaelauler@gmail.com>2014-10-08 18:54:26 +0000
committerRafael Auler <rafaelauler@gmail.com>2014-10-08 18:54:26 +0000
commitce1af1a201c8dc05c05fd1f36a731e0a0fc5b43d (patch)
tree521b42d4afcee5557cc967700a372e40df2cdecd /lld/lib
parente4320f5e6a1b4cd0f41bd58afb1f96849901333f (diff)
downloadbcm5719-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.cpp4
-rw-r--r--lld/lib/Driver/GnuLdOptions.td6
-rw-r--r--lld/lib/ReaderWriter/ELF/ExecutableWriter.h20
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.h9
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);
OpenPOWER on IntegriCloud