From ba46cdb21ffbf9018c818220992dcc0494195348 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 22 May 2014 21:37:56 +0000 Subject: [PATCH] Move alias symbols from ELFLinkingContext to LinkingContext. Alias symbols are SimpleDefinedAtoms and are platform neutral. They don't have to belong ELF. This patch is to make it available to all platforms. No functionality change intended. Differential Revision: http://reviews.llvm.org/D3862 llvm-svn: 209475 --- lld/include/lld/Core/LinkingContext.h | 13 +++- lld/include/lld/ReaderWriter/Alias.h | 91 ++++++++++++++++++++++++ lld/include/lld/ReaderWriter/ELFLinkingContext.h | 9 --- lld/lib/Core/LinkingContext.cpp | 24 ++++++- lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 75 ------------------- 5 files changed, 124 insertions(+), 88 deletions(-) create mode 100644 lld/include/lld/ReaderWriter/Alias.h diff --git a/lld/include/lld/Core/LinkingContext.h b/lld/include/lld/Core/LinkingContext.h index 0c6e201..78e4e37 100644 --- a/lld/include/lld/Core/LinkingContext.h +++ b/lld/include/lld/Core/LinkingContext.h @@ -214,6 +214,11 @@ public: void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); } + void addAlias(StringRef from, StringRef to) { _aliasSymbols[from] = to; } + const std::map &getAliases() const { + return _aliasSymbols; + } + void setInputGraph(std::unique_ptr inputGraph) { _inputGraph = std::move(inputGraph); } @@ -307,14 +312,17 @@ protected: /// Abstract method to lazily instantiate the Writer. virtual Writer &writer() const = 0; - /// Method to create a internal file for the entry symbol + /// Method to create an internal file for the entry symbol virtual std::unique_ptr createEntrySymbolFile() const; std::unique_ptr createEntrySymbolFile(StringRef filename) const; - /// Method to create a internal file for an undefined symbol + /// Method to create an internal file for an undefined symbol virtual std::unique_ptr createUndefinedSymbolFile() const; std::unique_ptr createUndefinedSymbolFile(StringRef filename) const; + /// Method to create an internal file for alias symbols + std::unique_ptr createAliasSymbolFile() const; + StringRef _outputPath; StringRef _entrySymbolName; bool _deadStrip; @@ -330,6 +338,7 @@ protected: bool _allowShlibUndefines; OutputFileType _outputFileType; std::vector _deadStripRoots; + std::map _aliasSymbols; std::vector _llvmOptions; StringRefVector _initialUndefinedSymbols; std::unique_ptr _inputGraph; diff --git a/lld/include/lld/ReaderWriter/Alias.h b/lld/include/lld/ReaderWriter/Alias.h new file mode 100644 index 0000000..d7d44f2 --- /dev/null +++ b/lld/include/lld/ReaderWriter/Alias.h @@ -0,0 +1,91 @@ +//===- lld/ReaderWriter/Alias.h - Alias atoms -----------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Provide alias atoms. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLD_READER_WRITER_ALIAS_H +#define LLD_READER_WRITER_ALIAS_H + +#include "lld/Core/LLVM.h" +#include "lld/ReaderWriter/Simple.h" + +#include + +namespace lld { + +// An AliasAtom is a zero-size atom representing an alias for other atom. It has +// a LayoutAfter reference to the target atom, so that this atom and the target +// atom will be laid out at the same location in the final result. Initially +// the target atom is an undefined atom. Resolver will replace it with a defined +// one. +// +// It does not have attributes itself. Most member function calls are forwarded +// to the target atom. +class AliasAtom : public SimpleDefinedAtom { +public: + AliasAtom(const File &file, StringRef name) + : SimpleDefinedAtom(file), _target(nullptr), _name(name) {} + + StringRef name() const override { return _name; } + uint64_t size() const override { return 0; } + ArrayRef rawContent() const override { return ArrayRef(); } + + Scope scope() const override { + getTarget(); + return _target ? _target->scope() : scopeLinkageUnit; + } + + Merge merge() const override { + getTarget(); + return _target ? _target->merge() : mergeNo; + } + + ContentType contentType() const override { + getTarget(); + return _target ? _target->contentType() : typeUnknown; + } + + Interposable interposable() const override { + getTarget(); + return _target ? _target->interposable() : interposeNo; + } + + SectionChoice sectionChoice() const override { + getTarget(); + return _target ? _target->sectionChoice() : sectionBasedOnContent; + } + + StringRef customSectionName() const override { + getTarget(); + return _target ? _target->customSectionName() : StringRef(""); + } + +private: + void getTarget() const { + if (_target) + return; + for (const Reference *r : *this) { + if (r->kindNamespace() == lld::Reference::KindNamespace::all && + r->kindValue() == lld::Reference::kindLayoutAfter) { + _target = dyn_cast(r->target()); + return; + } + } + } + + mutable const DefinedAtom *_target; + std::string _name; +}; + +} // end namespace lld + +#endif diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index 4708d16..f551a3c 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -194,10 +194,6 @@ public: _absoluteSymbols[name] = addr; } - void addAlias(StringRef sym, StringRef target) { - _aliasSymbols[sym] = target; - } - /// Return the list of initializer symbols that are specified in the /// linker command line, using the -init option. range initFunctions() const { @@ -241,10 +237,6 @@ public: return _absoluteSymbols; } - const std::map &getAliases() const { - return _aliasSymbols; - } - /// \brief Helper function to allocate strings. StringRef allocateString(StringRef ref) const { char *x = _allocator.Allocate(ref.size() + 1); @@ -292,7 +284,6 @@ protected: StringRefVector _rpathList; StringRefVector _rpathLinkList; std::map _absoluteSymbols; - std::map _aliasSymbols; }; } // end namespace lld diff --git a/lld/lib/Core/LinkingContext.cpp b/lld/lib/Core/LinkingContext.cpp index 675de3e..56388e1 100644 --- a/lld/lib/Core/LinkingContext.cpp +++ b/lld/lib/Core/LinkingContext.cpp @@ -9,9 +9,9 @@ #include "lld/Core/LinkingContext.h" #include "lld/Core/Resolver.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/ReaderWriter/Alias.h" #include "lld/ReaderWriter/Simple.h" - +#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/Triple.h" namespace lld { @@ -71,12 +71,32 @@ LinkingContext::createUndefinedSymbolFile(StringRef filename) const { return std::move(undefinedSymFile); } +std::unique_ptr LinkingContext::createAliasSymbolFile() const { + if (getAliases().empty()) + return nullptr; + std::unique_ptr file(new SimpleFile("")); + for (const auto &i : getAliases()) { + StringRef from = i.first; + StringRef to = i.second; + SimpleDefinedAtom *fromAtom = new (_allocator) AliasAtom(*file, from); + UndefinedAtom *toAtom = new (_allocator) SimpleUndefinedAtom(*file, to); + fromAtom->addReference(Reference::KindNamespace::all, + Reference::KindArch::all, Reference::kindLayoutAfter, + 0, toAtom, 0); + file->addAtom(*fromAtom); + file->addAtom(*toAtom); + } + return std::move(file); +} + void LinkingContext::createInternalFiles( std::vector > &result) const { if (std::unique_ptr file = createEntrySymbolFile()) result.push_back(std::move(file)); if (std::unique_ptr file = createUndefinedSymbolFile()) result.push_back(std::move(file)); + if (std::unique_ptr file = createAliasSymbolFile()) + result.push_back(std::move(file)); } void LinkingContext::addPasses(PassManager &pm) {} diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index 430de66..89f5022 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -41,70 +41,6 @@ private: uint64_t _value; }; -// An AliasAtom is a zero-size atom representing an alias for other atom. It has -// a LayoutAfter reference to the target atom, so that this atom and the target -// atom will be laid out at the same location in the final result. Initially -// the target atom is an undefined atom. Resolver will replace it with a defined -// one. -// -// It does not have attributes itself. Most member function calls are forwarded -// to the target atom. -class AliasAtom : public SimpleDefinedAtom { -public: - AliasAtom(const File &file, StringRef name) - : SimpleDefinedAtom(file), _target(nullptr), _name(name) {} - - StringRef name() const override { return _name; } - uint64_t size() const override { return 0; } - ArrayRef rawContent() const override { return ArrayRef(); } - - Scope scope() const override { - getTarget(); - return _target ? _target->scope() : scopeLinkageUnit; - } - - Merge merge() const override { - getTarget(); - return _target ? _target->merge() : mergeNo; - } - - ContentType contentType() const override { - getTarget(); - return _target ? _target->contentType() : typeUnknown; - } - - Interposable interposable() const override { - getTarget(); - return _target ? _target->interposable() : interposeNo; - } - - SectionChoice sectionChoice() const override { - getTarget(); - return _target ? _target->sectionChoice() : sectionBasedOnContent; - } - - StringRef customSectionName() const override { - getTarget(); - return _target ? _target->customSectionName() : StringRef(""); - } - -private: - void getTarget() const { - if (_target) - return; - for (const Reference *r : *this) { - if (r->kindNamespace() == lld::Reference::KindNamespace::all && - r->kindValue() == lld::Reference::kindLayoutAfter) { - _target = dyn_cast(r->target()); - return; - } - } - } - - mutable const DefinedAtom *_target; - StringRef _name; -}; - class CommandLineUndefinedAtom : public SimpleUndefinedAtom { public: CommandLineUndefinedAtom(const File &f, StringRef name) @@ -279,17 +215,6 @@ void ELFLinkingContext::createInternalFiles( uint64_t val = i.second; file->addAtom(*(new (_allocator) CommandLineAbsoluteAtom(*file, sym, val))); } - for (auto &i : getAliases()) { - StringRef from = i.first; - StringRef to = i.second; - SimpleDefinedAtom *fromAtom = new (_allocator) AliasAtom(*file, from); - UndefinedAtom *toAtom = new (_allocator) SimpleUndefinedAtom(*file, to); - fromAtom->addReference(Reference::KindNamespace::all, - Reference::KindArch::all, Reference::kindLayoutAfter, - 0, toAtom, 0); - file->addAtom(*fromAtom); - file->addAtom(*toAtom); - } files.push_back(std::move(file)); LinkingContext::createInternalFiles(files); } -- 2.7.4