Index: include/lld/Core/LinkingContext.h =================================================================== --- include/lld/Core/LinkingContext.h +++ include/lld/Core/LinkingContext.h @@ -214,6 +214,11 @@ 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 @@ /// 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 @@ bool _allowShlibUndefines; OutputFileType _outputFileType; std::vector _deadStripRoots; + std::map _aliasSymbols; std::vector _llvmOptions; StringRefVector _initialUndefinedSymbols; std::unique_ptr _inputGraph; Index: include/lld/ReaderWriter/Alias.h =================================================================== --- /dev/null +++ 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 Index: include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/ELFLinkingContext.h +++ include/lld/ReaderWriter/ELFLinkingContext.h @@ -194,10 +194,6 @@ _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 @@ 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 @@ StringRefVector _rpathList; StringRefVector _rpathLinkList; std::map _absoluteSymbols; - std::map _aliasSymbols; }; } // end namespace lld Index: lib/Core/LinkingContext.cpp =================================================================== --- lib/Core/LinkingContext.cpp +++ 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 @@ 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) {} Index: lib/ReaderWriter/ELF/ELFLinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -41,70 +41,6 @@ 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 @@ 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); }