[llvm-commits] [lld] r152269 - in /lld/trunk: ./ include/lld/Core/ include/lld/Platform/ lib/ lib/Core/ lib/Passes/ test/ tools/lld-core/
Michael Spencer
bigcheesegs at gmail.com
Fri Mar 9 10:50:39 PST 2012
On Wed, Mar 7, 2012 at 4:18 PM, Nick Kledzik <kledzik at apple.com> wrote:
> Author: kledzik
> Date: Wed Mar 7 18:18:30 2012
> New Revision: 152269
>
> URL: http://llvm.org/viewvc/llvm-project?rev=152269&view=rev
> Log:
> Sources now require C++11 to build.
>
> Add first linker pass (StubsPass) which looks for calls to shared library
> symbols and replaces them with calls to a StubAtom. On ELF system, a "stub"
> is a PLT entry. Added a simple test case.
>
> Pass a Platform object to YAML reader and writer for converting fixup kinds
> between names and values.
>
> Change output of Resolver to be a File object instead of a vector of Atoms.
> Thus, passes operate on a File instead of just Atoms.
>
> Rework how to walk through a File's Atoms. Now iterator based instead of
> a method that visits each atom.
>
>
> Added:
> lld/trunk/include/lld/Core/Pass.h
> lld/trunk/lib/Passes/CMakeLists.txt
> lld/trunk/lib/Passes/StubsPass.cpp
> lld/trunk/test/pass-stubs-basic.objtxt
> Modified:
> lld/trunk/CMakeLists.txt
> lld/trunk/include/lld/Core/Atom.h
> lld/trunk/include/lld/Core/DefinedAtom.h
> lld/trunk/include/lld/Core/File.h
> lld/trunk/include/lld/Core/InputFiles.h
> lld/trunk/include/lld/Core/Resolver.h
> lld/trunk/include/lld/Core/YamlReader.h
> lld/trunk/include/lld/Core/YamlWriter.h
> lld/trunk/include/lld/Platform/Platform.h
> lld/trunk/lib/CMakeLists.txt
> lld/trunk/lib/Core/File.cpp
> lld/trunk/lib/Core/NativeReader.cpp
> lld/trunk/lib/Core/NativeWriter.cpp
> lld/trunk/lib/Core/Resolver.cpp
> lld/trunk/lib/Core/YamlKeyValues.cpp
> lld/trunk/lib/Core/YamlReader.cpp
> lld/trunk/lib/Core/YamlWriter.cpp
> lld/trunk/tools/lld-core/CMakeLists.txt
> lld/trunk/tools/lld-core/lld-core.cpp
>
> Modified: lld/trunk/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/CMakeLists.txt?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/CMakeLists.txt (original)
> +++ lld/trunk/CMakeLists.txt Wed Mar 7 18:18:30 2012
> @@ -1,6 +1,8 @@
> # If we are not building as a part of LLVM, build lld as a standalone project,
> # using LLVM as an external library.
>
> +
> +
> if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
> project(lld)
> cmake_minimum_required(VERSION 2.8)
> @@ -58,6 +60,20 @@
> "`CMakeFiles'. Please delete them.")
> endif()
>
> +#
> +# lld now requires C++11 to build
> +#
> +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
> +include(CheckCXXCompilerFlag)
> +check_cxx_compiler_flag("-std=c++11" SUPPORTS_CXX11_FLAG)
> +if( SUPPORTS_CXX11_FLAG )
> + message(STATUS "Building with -std=c++11")
> + set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
> +else( SUPPORTS_CXX11_FLAG )
> + message(WARNING "-std=c++11 not supported.")
> +endif()
> +
> +
> macro(add_lld_library name)
> llvm_process_sources(srcs ${ARGN})
> if (MSVC_IDE OR XCODE)
>
> Modified: lld/trunk/include/lld/Core/Atom.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/Atom.h (original)
> +++ lld/trunk/include/lld/Core/Atom.h Wed Mar 7 18:18:30 2012
> @@ -24,7 +24,7 @@
> class SharedLibraryAtom;
> class AbsoluteAtom;
>
> - ///
> +///
> /// The linker has a Graph Theory model of linking. An object file is seen
> /// as a set of Atoms with References to other Atoms. Each Atom is a node
> /// and each Reference is an edge. An Atom can be a DefinedAtom which has
>
> Modified: lld/trunk/include/lld/Core/DefinedAtom.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/DefinedAtom.h (original)
> +++ lld/trunk/include/lld/Core/DefinedAtom.h Wed Mar 7 18:18:30 2012
> @@ -195,13 +195,6 @@
> uint16_t modulus;
> };
>
> - /// for use iterating over this Atom's References
> - class ReferenceHandler {
> - public:
> - virtual ~ReferenceHandler() {}
> - virtual void doReference(const Reference &) = 0;
> - };
> -
> /// ordinal - returns a value for the order of this Atom within its file.
> /// This is used by the linker to order the layout of Atoms so that
> /// the resulting image is stable and reproducible.
> @@ -266,10 +259,43 @@
> /// rawContent - returns a reference to the raw (unrelocated) bytes of
> /// this Atom's content.
> virtual llvm::ArrayRef<uint8_t> rawContent() const = 0;
> +
> + /// This class abstracts iterating over the sequence of References
> + /// in an Atom. Concrete instances of DefinedAtom must implement
> + /// the derefIterator() and incrementIterator methods.
> + class reference_iterator {
> + public:
> + reference_iterator(const DefinedAtom& a, const void* it)
> + : _atom(a), _it(it) { }
>
> - /// iterator over this Atom's References
> - virtual void forEachReference(ReferenceHandler&) const = 0;
> + const Reference* operator*() const {
> + return _atom.derefIterator(_it);
> + }
> +
> + const Reference* operator->() const {
> + return _atom.derefIterator(_it);
> + }
> +
> + bool operator!=(const reference_iterator& other) const {
> + return (this->_it != other._it);
> + }
> +
> + reference_iterator& operator++() {
> + _atom.incrementIterator(_it);
> + return *this;
> + }
> + private:
> + const DefinedAtom& _atom;
> + const void* _it;
> + };
> +
> + /// Returns an iterator to the beginning of this Atom's References
> + virtual reference_iterator referencesBegin() const = 0;
>
> + /// Returns an iterator to the end of this Atom's References
> + virtual reference_iterator referencesEnd() const = 0;
> +
> +
> protected:
> /// DefinedAtom is an abstract base class.
> /// Only subclasses can access constructor.
> @@ -280,6 +306,15 @@
> /// delete on an Atom. In fact, some File objects may bulk allocate
> /// an array of Atoms, so they cannot be individually deleted by anyone.
> virtual ~DefinedAtom() {}
> +
> + /// Returns a pointer to the Reference object that the abstract
> + /// iterator "points" to.
> + virtual const Reference* derefIterator(const void* iter) const = 0;
> +
> + /// Adjusts the abstract iterator to "point" to the next Reference object
> + /// for this Atom.
> + virtual void incrementIterator(const void*& iter) const = 0;
> +
> };
>
> } // namespace lld
>
> Modified: lld/trunk/include/lld/Core/File.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/File.h (original)
> +++ lld/trunk/include/lld/Core/File.h Wed Mar 7 18:18:30 2012
> @@ -1,4 +1,4 @@
> -//===- Core/File.h - A Contaier of Atoms ----------------------------------===//
> +//===- Core/File.h - A Container of Atoms ---------------------------------===//
> //
> // The LLVM Linker
> //
> @@ -10,6 +10,8 @@
> #ifndef LLD_CORE_FILE_H_
> #define LLD_CORE_FILE_H_
>
> +#include <vector>
> +
> #include "llvm/ADT/StringRef.h"
>
> #include "lld/Core/DefinedAtom.h"
> @@ -19,31 +21,190 @@
>
> namespace lld {
>
> +
> +///
> +/// Every Atom is owned by some File. A common scenario is for a single
> +/// object file (.o) to be parsed by some reader and produce a single
> +/// File object that represents the content of that object file.
> +///
> +/// The File class has *begin() and *end() methods for use iterating through
> +/// the Atoms in a File object.
> +///
> +/// The Atom objects in a File are owned by the File object. The Atom objects
> +/// are destroyed when the File object is destroyed.
> +///
> class File {
> public:
> - File(llvm::StringRef p) : _path(p) {}
> virtual ~File();
>
> - class AtomHandler {
> - public:
> - virtual ~AtomHandler() {}
> - virtual void doDefinedAtom(const class DefinedAtom &) = 0;
> - virtual void doUndefinedAtom(const class UndefinedAtom &) = 0;
> - virtual void doSharedLibraryAtom(const class SharedLibraryAtom &) = 0;
> - virtual void doAbsoluteAtom(const class AbsoluteAtom &) = 0;
> - virtual void doFile(const class File &) = 0;
> - };
> -
> + /// For error messages and debugging, this returns the path to the file
> + /// which was used to create this object (e.g. "/tmp/foo.o").
> llvm::StringRef path() const {
> return _path;
> }
>
> - virtual bool forEachAtom(AtomHandler &) const = 0;
> - virtual bool justInTimeforEachAtom( llvm::StringRef name
> - , AtomHandler &) const = 0;
> + /// Returns the path of the source file used to create the object
> + /// file which this (File) object represents. This information is usually
> + /// parsed out of the DWARF debug information. If the source file cannot
> + /// be ascertained, this method returns the empty string.
> + virtual llvm::StringRef translationUnitSource() const;
>
> - virtual bool translationUnitSource(llvm::StringRef &path) const;
> +protected:
> + template <typename T> class atom_iterator; // forward reference
> +public:
> +
> + /// For use interating over DefinedAtoms in this File.
> + typedef atom_iterator<DefinedAtom> defined_iterator;
> +
> + /// For use interating over UndefinedAtoms in this File.
> + typedef atom_iterator<UndefinedAtom> undefined_iterator;
> +
> + /// For use interating over SharedLibraryAtoms in this File.
> + typedef atom_iterator<SharedLibraryAtom> shared_library_iterator;
> +
> + /// For use interating over AbsoluteAtoms in this File.
> + typedef atom_iterator<AbsoluteAtom> absolute_iterator;
> +
> + /// Returns an iterator to the beginning of this File's DefinedAtoms
> + defined_iterator definedAtomsBegin() const {
> + return defined().begin();
> + }
> +
> + /// Returns an iterator to the end of this File's DefinedAtoms
> + defined_iterator definedAtomsEnd() const {
> + return defined().end();
> + }
> +
> + /// Returns an iterator to the beginning of this File's DefinedAtoms
> + undefined_iterator undefinedAtomsBegin() const {
> + return undefined().begin();
> + }
> +
> + /// Returns an iterator to the end of this File's UndefinedAtoms
> + undefined_iterator undefinedAtomsEnd() const {
> + return undefined().end();
> + }
> +
> + /// Returns an iterator to the beginning of this File's SharedLibraryAtoms
> + shared_library_iterator sharedLibraryAtomsBegin() const {
> + return sharedLibrary().begin();
> + }
> +
> + /// Returns an iterator to the end of this File's SharedLibraryAtoms
> + shared_library_iterator sharedLibraryAtomsEnd() const {
> + return sharedLibrary().end();
> + }
> +
> + /// Returns an iterator to the beginning of this File's AbsoluteAtoms
> + absolute_iterator absoluteAtomsBegin() const {
> + return absolute().begin();
> + }
>
> + /// Returns an iterator to the end of this File's AbsoluteAtoms
> + absolute_iterator absoluteAtomsEnd() const {
> + return absolute().end();
> + }
> +
> + /// Note: this method is not const. All File objects instantiated by reading
> + /// an object file from disk are "const File*" objects and cannot be
> + /// modified. This method can only be used with temporay File objects
> + /// such as is seen by each Pass object when it runs.
> + /// This method is *not* safe to call while iterating through this File's
> + /// Atoms. A Pass should queue up any Atoms it want to add and then
> + /// call this method when no longer iterating over the File's Atoms.
> + virtual void addAtom(const Atom&) = 0;
> +
> +
> +
> +protected:
> + /// only subclasses of File can be instantiated
> + File(llvm::StringRef p) : _path(p) {}
> +
> +
> + /// Different object file readers may instantiate and manage atoms with
> + /// different data structures. This class is a collection abstraction.
> + /// Each concrete File instance must implement these atom_collection
> + /// methods to enable clients to interate the File's atoms.
> + template <typename T>
> + class atom_collection {
> + public:
> + virtual atom_iterator<T> begin() const = 0;
> + virtual atom_iterator<T> end() const = 0;
> + virtual const T* deref(const void* it) const = 0;
> + virtual void next(const void*& it) const = 0;
> + };
> +
> +
> + /// The class is the iterator type used to iterate through a File's Atoms.
> + /// This iterator delegates the work to the associated atom_collection object.
> + /// There are four kinds of Atoms, so this iterator is templated on
> + /// the four base Atom kinds.
> + template <typename T>
> + class atom_iterator {
> + public:
> + atom_iterator(const atom_collection<T>& c, const void* it)
> + : _collection(c), _it(it) { }
> +
> + const T* operator*() const {
> + return _collection.deref(_it);
> + }
> +
> + const T* operator->() const {
> + return _collection.deref(_it);
> + }
> +
> + bool operator!=(const atom_iterator<T>& other) const {
> + return (this->_it != other._it);
> + }
> +
> + atom_iterator<T>& operator++() {
> + _collection.next(_it);
> + return *this;
> + }
> + private:
> + const atom_collection<T>& _collection;
> + const void* _it;
> + };
> +
> + /// Must be implemented to return the atom_collection object for
> + /// all DefinedAtoms in this File.
> + virtual const atom_collection<DefinedAtom>& defined() const = 0;
> +
> + /// Must be implemented to return the atom_collection object for
> + /// all UndefinedAtomw in this File.
> + virtual const atom_collection<UndefinedAtom>& undefined() const = 0;
> +
> + /// Must be implemented to return the atom_collection object for
> + /// all SharedLibraryAtoms in this File.
> + virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const = 0;
> +
> + /// Must be implemented to return the atom_collection object for
> + /// all AbsoluteAtoms in this File.
> + virtual const atom_collection<AbsoluteAtom>& absolute() const = 0;
> +
> + /// This is a convenience class for File subclasses which manage their
> + /// atoms as a simple std::vector<>.
> + template <typename T>
> + class atom_collection_vector : public atom_collection<T> {
> + public:
> + virtual atom_iterator<T> begin() const {
> + return atom_iterator<T>(*this, reinterpret_cast<const void*>(&_atoms[0]));
> + }
> + virtual atom_iterator<T> end() const{
> + return atom_iterator<T>(*this, reinterpret_cast<const void*>
> + (&_atoms[_atoms.size()]));
> + }
> + virtual const T* deref(const void* it) const {
> + return *reinterpret_cast<const T* const*>(it);
> + }
> + virtual void next(const void*& it) const {
> + const T * const * p = reinterpret_cast<const T * const *>(it);
> + ++p;
> + it = reinterpret_cast<const void*>(p);
> + }
> + std::vector<const T*> _atoms;
> + };
> +
I find the use of void* and reinterpret_cast in the above concerning.
We could simply use LLVM's rtti and cast<T>. This has no runtime cost
in -asserts builds, and with assert builds we get runtime type
checking.
- Michael Spencer
> private:
> llvm::StringRef _path;
>
> Modified: lld/trunk/include/lld/Core/InputFiles.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputFiles.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/InputFiles.h (original)
> +++ lld/trunk/include/lld/Core/InputFiles.h Wed Mar 7 18:18:30 2012
> @@ -24,15 +24,26 @@
> /// The searchLibraries() method is used to lazily search libraries.
> class InputFiles {
> public:
> + class Handler {
> + public:
> + virtual ~Handler() {}
> + virtual void doFile(const class File &) = 0;
> + virtual void doDefinedAtom(const class DefinedAtom &) = 0;
> + virtual void doUndefinedAtom(const class UndefinedAtom &) = 0;
> + virtual void doSharedLibraryAtom(const class SharedLibraryAtom &) = 0;
> + virtual void doAbsoluteAtom(const class AbsoluteAtom &) = 0;
> + };
> +
> +
> /// @brief iterates all atoms in initial files
> - virtual void forEachInitialAtom(File::AtomHandler &) const = 0;
> + virtual void forEachInitialAtom(Handler &) const = 0;
>
> /// @brief searches libraries for name
> virtual bool searchLibraries( llvm::StringRef name
> , bool searchDylibs
> , bool searchArchives
> , bool dataSymbolOnly
> - , File::AtomHandler &) const = 0;
> + , Handler &) const = 0;
> };
>
> } // namespace lld
>
> Added: lld/trunk/include/lld/Core/Pass.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Pass.h?rev=152269&view=auto
> ==============================================================================
> --- lld/trunk/include/lld/Core/Pass.h (added)
> +++ lld/trunk/include/lld/Core/Pass.h Wed Mar 7 18:18:30 2012
> @@ -0,0 +1,65 @@
> +//===------ Core/Pass.h - Base class for linker passes --------------------===//
> +//
> +// The LLVM Linker
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLD_CORE_PASS_H_
> +#define LLD_CORE_PASS_H_
> +
> +#include <vector>
> +
> +#include "lld/Core/Atom.h"
> +#include "lld/Platform/Platform.h"
> +
> +namespace lld {
> +
> +
> +///
> +/// Once the core linking is done (which resolves references, coalesces atoms
> +/// and produces a complete Atom graph), the linker runs a series of passes
> +/// on the Atom graph. The graph is modeled as a File, which means the pass
> +/// has access to all the atoms and to File level attributes. Each pass does
> +/// a particular transformation to the Atom graph or to the File attributes.
> +///
> +/// This is the abstract base class for all passes. A Pass does its
> +/// actual work in it perform() method. It can iterator over Atoms in the
> +/// graph using the *begin()/*end() atom iterator of the File. It can add
> +/// new Atoms to the graph using the File's addAtom() method.
> +///
> +///
> +class Pass {
> +public:
> + /// Do the actual work of the Pass.
> + virtual void perform() = 0;
> +
> +protected:
> + // Only subclassess can be instantiated.
> + Pass(File& f, Platform& p) : _file(f), _platform(p) {}
> +
> +
> + File& _file;
> + Platform& _platform;
> +};
> +
> +
> +///
> +/// Pass for adding stubs (PLT entries) for calls to functions
> +/// outside the linkage unit.
> +///
> +class StubsPass : public Pass {
> +public:
> + StubsPass(File& f, Platform& p) : Pass(f, p) {}
> +
> + /// Scans all Atoms looking for call-site uses of SharedLibraryAtoms
> + /// and transfroms the call-site to call a stub instead.
> + virtual void perform();
> +};
> +
> +
> +} // namespace lld
> +
> +#endif // LLD_CORE_PASS_H_
>
> Modified: lld/trunk/include/lld/Core/Resolver.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/Resolver.h (original)
> +++ lld/trunk/include/lld/Core/Resolver.h Wed Mar 7 18:18:30 2012
> @@ -11,6 +11,7 @@
> #define LLD_CORE_RESOLVER_H_
>
> #include "lld/Core/File.h"
> +#include "lld/Core/InputFiles.h"
> #include "lld/Core/SymbolTable.h"
>
> #include "llvm/ADT/DenseSet.h"
> @@ -30,7 +31,7 @@
> ///
> /// All platform specific resolving is done by delegating to the
> /// Platform object specified.
> -class Resolver : public File::AtomHandler {
> +class Resolver : public InputFiles::Handler {
> public:
> Resolver(Platform &plat, const InputFiles &inputs)
> : _platform(plat)
> @@ -40,7 +41,7 @@
> , _addToFinalSection(false)
> , _completedInitialObjectFiles(false) {}
>
> - // AtomHandler methods
> + // InputFiles::Handler methods
> virtual void doDefinedAtom(const class DefinedAtom&);
> virtual void doUndefinedAtom(const class UndefinedAtom&);
> virtual void doSharedLibraryAtom(const class SharedLibraryAtom &);
> @@ -48,7 +49,11 @@
> virtual void doFile(const File&);
>
> /// @brief do work of merging and resolving and return list
> - std::vector<const Atom *> &resolve();
> + void resolve();
> +
> + File& resultFile() {
> + return _result;
> + }
>
> private:
> struct WhyLiveBackChain {
> @@ -73,31 +78,49 @@
> void addAtoms(const std::vector<const DefinedAtom *>&);
>
>
> - // helper to update targets for use with forEachReference()
> - class MarkLiveReferences : public DefinedAtom::ReferenceHandler {
> + class MergedFile : public File {
> public:
> - MarkLiveReferences(Resolver& resolver, WhyLiveBackChain* chain)
> - : _resolver(resolver), _chain(chain) { }
> + MergedFile() : File("<linker-internal>") { }
>
> - virtual void doReference(const Reference& ref) {
> - _resolver.markLive(*ref.target(), _chain);
> - }
> +
> +
> + virtual const atom_collection<DefinedAtom>& defined() const {
> + return _definedAtoms;
> + }
> + virtual const atom_collection<UndefinedAtom>& undefined() const {
> + return _undefinedAtoms;
> + }
> + virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
> + return _sharedLibraryAtoms;
> + }
> + virtual const atom_collection<AbsoluteAtom>& absolute() const {
> + return _absoluteAtoms;
> + }
> +
> + void addAtoms(std::vector<const Atom*>& atoms);
> +
> + virtual void addAtom(const Atom& atom);
>
> private:
> - Resolver& _resolver;
> - WhyLiveBackChain* _chain;
> + atom_collection_vector<DefinedAtom> _definedAtoms;
> + atom_collection_vector<UndefinedAtom> _undefinedAtoms;
> + atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
> + atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
> };
> -
> - Platform &_platform;
> - const InputFiles &_inputFiles;
> - SymbolTable _symbolTable;
> - std::vector<const Atom *> _atoms;
> - std::set<const Atom *> _deadStripRoots;
> - std::vector<const Atom *> _atomsWithUnresolvedReferences;
> - llvm::DenseSet<const Atom *> _liveAtoms;
> - bool _haveLLVMObjs;
> - bool _addToFinalSection;
> - bool _completedInitialObjectFiles;
> +
> +
> +
> + Platform& _platform;
> + const InputFiles& _inputFiles;
> + SymbolTable _symbolTable;
> + std::vector<const Atom *> _atoms;
> + std::set<const Atom *> _deadStripRoots;
> + std::vector<const Atom *> _atomsWithUnresolvedReferences;
> + llvm::DenseSet<const Atom *> _liveAtoms;
> + MergedFile _result;
> + bool _haveLLVMObjs;
> + bool _addToFinalSection;
> + bool _completedInitialObjectFiles;
> };
>
> } // namespace lld
>
> Modified: lld/trunk/include/lld/Core/YamlReader.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/YamlReader.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/YamlReader.h (original)
> +++ lld/trunk/include/lld/Core/YamlReader.h Wed Mar 7 18:18:30 2012
> @@ -10,8 +10,6 @@
> #ifndef LLD_CORE_YAML_READER_H_
> #define LLD_CORE_YAML_READER_H_
>
> -#include "lld/Core/File.h"
> -
> #include "llvm/Support/system_error.h"
>
> #include <vector>
> @@ -19,19 +17,25 @@
> namespace llvm { class MemoryBuffer; }
>
> namespace lld {
> +
> +class Platform;
> +class File;
> +
> namespace yaml {
>
> /// parseObjectTextFileOrSTDIN - Open the specified YAML file (use stdin if
> /// the path is "-") and parse into lld::File object(s) and append each to
> /// the specified vector<File*>.
> llvm::error_code parseObjectTextFileOrSTDIN(llvm::StringRef path
> - , std::vector<File *>&);
> + , Platform&
> + , std::vector<const File *>&);
>
>
> /// parseObjectText - Parse the specified YAML formatted MemoryBuffer
> /// into lld::File object(s) and append each to the specified vector<File*>.
> llvm::error_code parseObjectText(llvm::MemoryBuffer *mb
> - , std::vector<File *>&);
> + , Platform&
> + , std::vector<const File *>&);
>
> } // namespace yaml
> } // namespace lld
>
> Modified: lld/trunk/include/lld/Core/YamlWriter.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/YamlWriter.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Core/YamlWriter.h (original)
> +++ lld/trunk/include/lld/Core/YamlWriter.h Wed Mar 7 18:18:30 2012
> @@ -10,15 +10,18 @@
> #ifndef LLD_CORE_YAML_WRITER_H_
> #define LLD_CORE_YAML_WRITER_H_
>
> -#include "lld/Core/File.h"
> #include "llvm/Support/raw_ostream.h"
>
> namespace lld {
> +
> +class Platform;
> +class File;
> +
> namespace yaml {
>
> /// writeObjectText - writes the lld::File object as in YAML
> /// format to the specified stream.
> - void writeObjectText(const lld::File &, llvm::raw_ostream &);
> + void writeObjectText(const lld::File &, Platform &, llvm::raw_ostream &);
>
> } // namespace yaml
> } // namespace lld
>
> Modified: lld/trunk/include/lld/Platform/Platform.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Platform/Platform.h?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Platform/Platform.h (original)
> +++ lld/trunk/include/lld/Platform/Platform.h Wed Mar 7 18:18:30 2012
> @@ -12,10 +12,13 @@
>
> #include <vector>
>
> +#include "lld/Core/Reference.h"
> +
> namespace lld {
> class Atom;
> class DefinedAtom;
>
> +
> /// The Platform class encapsulated plaform specific linking knowledge.
> ///
> /// Much of what it does is driving by platform specific linker options.
> @@ -98,6 +101,26 @@
>
> /// @brief last chance for platform to tweak atoms
> virtual void postResolveTweaks(std::vector<const Atom *>& all) = 0;
> +
> + /// If the output being generated uses needs stubs for external calls
> + virtual bool outputUsesStubs() = 0;
> +
> + /// Converts a reference kind string to a in-memory numeric value.
> + /// For use with parsing YAML encoded object files.
> + virtual Reference::Kind kindFromString(llvm::StringRef) = 0;
> +
> + /// Converts an in-memory reference kind value to a string.
> + /// For use with writing YAML encoded object files.
> + virtual llvm::StringRef kindToString(Reference::Kind) = 0;
> +
> + /// If Reference is a branch instruction that might need to be changed
> + /// to target a stub (PLT entry).
> + virtual bool isBranch(const Reference*) = 0;
> +
> + /// Create a platform specific atom which contains a stub/PLT entry
> + /// targeting the specified shared library atom.
> + virtual const Atom* makeStub(const SharedLibraryAtom&, File&) = 0;
> +
> };
>
> } // namespace lld
>
> Modified: lld/trunk/lib/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/CMakeLists.txt?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/CMakeLists.txt (original)
> +++ lld/trunk/lib/CMakeLists.txt Wed Mar 7 18:18:30 2012
> @@ -1 +1,2 @@
> add_subdirectory(Core)
> +add_subdirectory(Passes)
>
> Modified: lld/trunk/lib/Core/File.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/File.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/File.cpp (original)
> +++ lld/trunk/lib/Core/File.cpp Wed Mar 7 18:18:30 2012
> @@ -13,8 +13,8 @@
>
> File::~File() {}
>
> -bool File::translationUnitSource(llvm::StringRef &path) const {
> - return false;
> +llvm::StringRef File::translationUnitSource() const {
> + return llvm::StringRef();
> }
>
>
>
> Modified: lld/trunk/lib/Core/NativeReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/NativeReader.cpp (original)
> +++ lld/trunk/lib/Core/NativeReader.cpp Wed Mar 7 18:18:30 2012
> @@ -92,9 +92,15 @@
> }
>
> virtual llvm::ArrayRef<uint8_t> rawContent() const;
> -
> - virtual void forEachReference(ReferenceHandler&) const;
> -
> +
> + virtual reference_iterator referencesBegin() const;
> +
> + virtual reference_iterator referencesEnd() const;
> +
> + virtual const Reference* derefIterator(const void*) const;
> +
> + virtual void incrementIterator(const void*& it) const;
> +
> private:
> const NativeAtomAttributesV1& attributes() const;
>
> @@ -299,53 +305,29 @@
> // the _definedAtoms array which was allocated to contain an array
> // of Atom objects. The atoms have empty destructors, so it is ok
> // to just delete the memory.
> - delete _definedAtoms.arrayStart;
> - delete _undefinedAtoms.arrayStart;
> - delete _sharedLibraryAtoms.arrayStart;
> - delete _absoluteAtoms.arrayStart;
> + delete _definedAtoms._arrayStart;
> + delete _undefinedAtoms._arrayStart;
> + delete _sharedLibraryAtoms._arrayStart;
> + delete _absoluteAtoms._arrayStart;
> delete _references.arrayStart;
> delete _targetsTable;
> }
>
> - // visits each atom in the file
> - virtual bool forEachAtom(AtomHandler& handler) const {
> - bool didSomething = false;
> - for(const uint8_t* p=_definedAtoms.arrayStart; p != _definedAtoms.arrayEnd;
> - p += _definedAtoms.elementSize) {
> - const DefinedAtom* atom = reinterpret_cast<const DefinedAtom*>(p);
> - handler.doDefinedAtom(*atom);
> - didSomething = true;
> - }
> - for(const uint8_t* p=_undefinedAtoms.arrayStart;
> - p != _undefinedAtoms.arrayEnd;
> - p += _undefinedAtoms.elementSize) {
> - const UndefinedAtom* atom = reinterpret_cast<const UndefinedAtom*>(p);
> - handler.doUndefinedAtom(*atom);
> - didSomething = true;
> - }
> - for(const uint8_t* p=_sharedLibraryAtoms.arrayStart;
> - p != _sharedLibraryAtoms.arrayEnd;
> - p += _sharedLibraryAtoms.elementSize) {
> - const SharedLibraryAtom* atom
> - = reinterpret_cast<const SharedLibraryAtom*>(p);
> - handler.doSharedLibraryAtom(*atom);
> - didSomething = true;
> - }
> - for(const uint8_t* p=_absoluteAtoms.arrayStart;
> - p != _absoluteAtoms.arrayEnd;
> - p += _absoluteAtoms.elementSize) {
> - const AbsoluteAtom* atom
> - = reinterpret_cast<const AbsoluteAtom*>(p);
> - handler.doAbsoluteAtom(*atom);
> - didSomething = true;
> - }
> - return didSomething;
> - }
> -
> - // not used
> - virtual bool justInTimeforEachAtom(llvm::StringRef name,
> - AtomHandler &) const {
> - return false;
> + virtual const atom_collection<DefinedAtom>& defined() const {
> + return _definedAtoms;
> + }
> + virtual const atom_collection<UndefinedAtom>& undefined() const {
> + return _undefinedAtoms;
> + }
> + virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
> + return _sharedLibraryAtoms;
> + }
> + virtual const atom_collection<AbsoluteAtom>& absolute() const {
> + return _absoluteAtoms;
> + }
> +
> + virtual void addAtom(const Atom&) {
> + assert(0 && "cannot add atoms to native .o files");
> }
>
> private:
> @@ -378,10 +360,10 @@
> new (atomAllocSpace) NativeDefinedAtomV1(*this, ivarData);
> ++ivarData;
> }
> - this->_definedAtoms.arrayStart = atomsStart;
> - this->_definedAtoms.arrayEnd = atomsEnd;
> - this->_definedAtoms.elementSize = atomSize;
> - this->_definedAtoms.elementCount = chunk->elementCount;
> + this->_definedAtoms._arrayStart = atomsStart;
> + this->_definedAtoms._arrayEnd = atomsEnd;
> + this->_definedAtoms._elementSize = atomSize;
> + this->_definedAtoms._elementCount = chunk->elementCount;
> return make_error_code(native_reader_error::success);
> }
>
> @@ -416,10 +398,10 @@
> new (atomAllocSpace) NativeUndefinedAtomV1(*this, ivarData);
> ++ivarData;
> }
> - this->_undefinedAtoms.arrayStart = atomsStart;
> - this->_undefinedAtoms.arrayEnd = atomsEnd;
> - this->_undefinedAtoms.elementSize = atomSize;
> - this->_undefinedAtoms.elementCount = chunk->elementCount;
> + this->_undefinedAtoms._arrayStart = atomsStart;
> + this->_undefinedAtoms._arrayEnd = atomsEnd;
> + this->_undefinedAtoms._elementSize = atomSize;
> + this->_undefinedAtoms._elementCount = chunk->elementCount;
> return make_error_code(native_reader_error::success);
> }
>
> @@ -447,10 +429,10 @@
> new (atomAllocSpace) NativeSharedLibraryAtomV1(*this, ivarData);
> ++ivarData;
> }
> - this->_sharedLibraryAtoms.arrayStart = atomsStart;
> - this->_sharedLibraryAtoms.arrayEnd = atomsEnd;
> - this->_sharedLibraryAtoms.elementSize = atomSize;
> - this->_sharedLibraryAtoms.elementCount = chunk->elementCount;
> + this->_sharedLibraryAtoms._arrayStart = atomsStart;
> + this->_sharedLibraryAtoms._arrayEnd = atomsEnd;
> + this->_sharedLibraryAtoms._elementSize = atomSize;
> + this->_sharedLibraryAtoms._elementCount = chunk->elementCount;
> return make_error_code(native_reader_error::success);
> }
>
> @@ -478,10 +460,10 @@
> new (atomAllocSpace) NativeAbsoluteAtomV1(*this, ivarData);
> ++ivarData;
> }
> - this->_absoluteAtoms.arrayStart = atomsStart;
> - this->_absoluteAtoms.arrayEnd = atomsEnd;
> - this->_absoluteAtoms.elementSize = atomSize;
> - this->_absoluteAtoms.elementCount = chunk->elementCount;
> + this->_absoluteAtoms._arrayStart = atomsStart;
> + this->_absoluteAtoms._arrayEnd = atomsEnd;
> + this->_absoluteAtoms._elementSize = atomSize;
> + this->_absoluteAtoms._elementCount = chunk->elementCount;
> return make_error_code(native_reader_error::success);
> }
>
> @@ -529,33 +511,33 @@
> this->_targetsTable = new const Atom*[chunk->elementCount];
> for (uint32_t i=0; i < chunk->elementCount; ++i) {
> const uint32_t index = targetIndexes[i];
> - if ( index < _definedAtoms.elementCount ) {
> - const uint8_t* p = _definedAtoms.arrayStart
> - + index * _definedAtoms.elementSize;
> + if ( index < _definedAtoms._elementCount ) {
> + const uint8_t* p = _definedAtoms._arrayStart
> + + index * _definedAtoms._elementSize;
> this->_targetsTable[i] = reinterpret_cast<const DefinedAtom*>(p);
> continue;
> }
> - const uint32_t undefIndex = index - _definedAtoms.elementCount;
> - if ( undefIndex < _undefinedAtoms.elementCount ) {
> - const uint8_t* p = _undefinedAtoms.arrayStart
> - + undefIndex * _undefinedAtoms.elementSize;
> + const uint32_t undefIndex = index - _definedAtoms._elementCount;
> + if ( undefIndex < _undefinedAtoms._elementCount ) {
> + const uint8_t* p = _undefinedAtoms._arrayStart
> + + undefIndex * _undefinedAtoms._elementSize;
> this->_targetsTable[i] = reinterpret_cast<const UndefinedAtom*>(p);
> continue;
> }
> - const uint32_t slIndex = index - _definedAtoms.elementCount
> - - _undefinedAtoms.elementCount;
> - if ( slIndex < _sharedLibraryAtoms.elementCount ) {
> - const uint8_t* p = _sharedLibraryAtoms.arrayStart
> - + slIndex * _sharedLibraryAtoms.elementSize;
> + const uint32_t slIndex = index - _definedAtoms._elementCount
> + - _undefinedAtoms._elementCount;
> + if ( slIndex < _sharedLibraryAtoms._elementCount ) {
> + const uint8_t* p = _sharedLibraryAtoms._arrayStart
> + + slIndex * _sharedLibraryAtoms._elementSize;
> this->_targetsTable[i] = reinterpret_cast<const SharedLibraryAtom*>(p);
> continue;
> }
> - const uint32_t abIndex = index - _definedAtoms.elementCount
> - - _undefinedAtoms.elementCount
> - - _sharedLibraryAtoms.elementCount;
> - if ( abIndex < _absoluteAtoms.elementCount ) {
> - const uint8_t* p = _absoluteAtoms.arrayStart
> - + slIndex * _absoluteAtoms.elementSize;
> + const uint32_t abIndex = index - _definedAtoms._elementCount
> + - _undefinedAtoms._elementCount
> + - _sharedLibraryAtoms._elementCount;
> + if ( abIndex < _absoluteAtoms._elementCount ) {
> + const uint8_t* p = _absoluteAtoms._arrayStart
> + + slIndex * _absoluteAtoms._elementSize;
> this->_targetsTable[i] = reinterpret_cast<const AbsoluteAtom*>(p);
> continue;
> }
> @@ -612,21 +594,13 @@
> assert((result+size) <= _contentEnd);
> return result;
> }
> -
> - void forEachReference(DefinedAtom::ReferenceHandler& handler,
> - uint32_t start, uint32_t count) const {
> - assert(start < _references.elementCount);
> - assert(start+count <= _references.elementCount);
> - const uint8_t* arrStart = _references.arrayStart
> - + start * _references.elementSize;
> - const uint8_t* arrEnd = arrStart + count * _references.elementSize;
> - for(const uint8_t* p=arrStart; p != arrEnd; p += _references.elementSize) {
> - const NativeReferenceV1* ref
> - = reinterpret_cast<const NativeReferenceV1*>(p);
> - handler.doReference(*ref);
> - }
> - }
>
> + const Reference* referenceByIndex(uintptr_t index) const {
> + assert(index < _references.elementCount);
> + const uint8_t* p = _references.arrayStart + index * _references.elementSize;
> + return reinterpret_cast<const NativeReferenceV1*>(p);
> + }
> +
> const Atom* target(uint32_t index) const {
> assert(index < _targetsTableCount);
> return _targetsTable[index];
> @@ -656,21 +630,52 @@
> (_buffer->getBufferStart());
> }
>
> + template <typename T>
> + class AtomArray : public File::atom_collection<T> {
> + public:
> + AtomArray() : _arrayStart(NULL), _arrayEnd(NULL),
> + _elementSize(0), _elementCount(0) { }
> +
> + virtual atom_iterator<T> begin() const {
> + return atom_iterator<T>(*this, reinterpret_cast<const void*>(_arrayStart));
> + }
> + virtual atom_iterator<T> end() const{
> + return atom_iterator<T>(*this, reinterpret_cast<const void*>(_arrayEnd));
> + }
> + virtual const T* deref(const void* it) const {
> + return reinterpret_cast<const T*>(it);
> + }
> + virtual void next(const void*& it) const {
> + const uint8_t* p = reinterpret_cast<const uint8_t*>(it);
> + p += _elementSize;
> + it = reinterpret_cast<const void*>(p);
> + }
> + const uint8_t* _arrayStart;
> + const uint8_t* _arrayEnd;
> + uint32_t _elementSize;
> + uint32_t _elementCount;
> + };
> +
> struct IvarArray {
> - IvarArray() : arrayStart(NULL), arrayEnd(NULL),
> - elementSize(0), elementCount(0) { }
> + IvarArray() :
> + arrayStart(NULL),
> + arrayEnd(NULL),
> + elementSize(0),
> + elementCount(0) { }
> +
> const uint8_t* arrayStart;
> const uint8_t* arrayEnd;
> uint32_t elementSize;
> uint32_t elementCount;
> - };
> + };
> +
>
> llvm::OwningPtr<llvm::MemoryBuffer> _buffer;
> const NativeFileHeader* _header;
> - IvarArray _definedAtoms;
> - IvarArray _undefinedAtoms;
> - IvarArray _sharedLibraryAtoms;
> - IvarArray _absoluteAtoms;
> + AtomArray<DefinedAtom> _definedAtoms;
> + AtomArray<UndefinedAtom> _undefinedAtoms;
> + AtomArray<SharedLibraryAtom> _sharedLibraryAtoms;
> + AtomArray<AbsoluteAtom> _absoluteAtoms;
> const uint8_t* _attributes;
> uint32_t _attributesMaxOffset;
> IvarArray _references;
> @@ -684,14 +689,14 @@
> const uint8_t* _contentEnd;
> };
>
> -
> +
> inline const class File& NativeDefinedAtomV1::file() const {
> return *_file;
> }
>
> inline uint64_t NativeDefinedAtomV1:: ordinal() const {
> const uint8_t* p = reinterpret_cast<const uint8_t*>(_ivarData);
> - return p - _file->_definedAtoms.arrayStart;
> + return p - _file->_definedAtoms._arrayStart;
> }
>
> inline llvm::StringRef NativeDefinedAtomV1::name() const {
> @@ -715,11 +720,27 @@
> return _file->string(offset);
> }
>
> -inline void NativeDefinedAtomV1::forEachReference(ReferenceHandler& hnd) const {
> - if ( _ivarData->referencesCount == 0 )
> - return;
> - _file->forEachReference(hnd, _ivarData->referencesStartIndex,
> - _ivarData->referencesCount);
> +DefinedAtom::reference_iterator NativeDefinedAtomV1::referencesBegin() const {
> + uintptr_t index = _ivarData->referencesStartIndex;
> + const void* it = reinterpret_cast<const void*>(index);
> + return reference_iterator(*this, it);
> +}
> +
> +DefinedAtom::reference_iterator NativeDefinedAtomV1::referencesEnd() const {
> + uintptr_t index = _ivarData->referencesStartIndex+_ivarData->referencesCount;
> + const void* it = reinterpret_cast<const void*>(index);
> + return reference_iterator(*this, it);
> +}
> +
> +const Reference* NativeDefinedAtomV1::derefIterator(const void* it) const {
> + uintptr_t index = reinterpret_cast<uintptr_t>(it);
> + return _file->referenceByIndex(index);
> +}
> +
> +void NativeDefinedAtomV1::incrementIterator(const void*& it) const {
> + uintptr_t index = reinterpret_cast<uintptr_t>(it);
> + ++index;
> + it = reinterpret_cast<const void*>(index);
> }
>
> inline const class File& NativeUndefinedAtomV1::file() const {
>
> Modified: lld/trunk/lib/Core/NativeWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/NativeWriter.cpp (original)
> +++ lld/trunk/lib/Core/NativeWriter.cpp Wed Mar 7 18:18:30 2012
> @@ -8,7 +8,6 @@
> //===----------------------------------------------------------------------===//
>
> #include <vector>
> -#include <map>
>
> #include "llvm/ADT/StringRef.h"
> #include "llvm/ADT/ArrayRef.h"
> @@ -26,15 +25,36 @@
> ///
> /// Class for writing native object files.
> ///
> -class NativeWriter : public File::AtomHandler,
> - public DefinedAtom::ReferenceHandler {
> +class NativeWriter {
> public:
> /// construct writer for an lld::File object
> NativeWriter(const lld::File& file) : _file(file) {
> // reserve first byte for unnamed atoms
> _stringPool.push_back('\0');
> // visit all atoms
> - _file.forEachAtom(*this);
> + for(File::defined_iterator it=file.definedAtomsBegin(),
> + end=file.definedAtomsEnd();
> + it != end; ++it) {
> + this->addIVarsForDefinedAtom(**it);
> + }
> + for(File::undefined_iterator it=file.undefinedAtomsBegin(),
> + end=file.undefinedAtomsEnd();
> + it != end; ++it) {
> + this->addIVarsForUndefinedAtom(**it);
> + }
> + for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(),
> + end=file.sharedLibraryAtomsEnd();
> + it != end; ++it) {
> + this->addIVarsForSharedLibraryAtom(**it);
> + }
> + for(File::absolute_iterator it=file.absoluteAtomsBegin(),
> + end=file.absoluteAtomsEnd();
> + it != end; ++it) {
> + this->addIVarsForAbsoluteAtom(**it);
> + }
> +
> +
> +
> // construct file header based on atom information accumulated
> makeHeader();
> }
> @@ -105,8 +125,7 @@
>
> private:
>
> - // visitor routine called by forEachAtom()
> - virtual void doDefinedAtom(const DefinedAtom& atom) {
> + void addIVarsForDefinedAtom(const DefinedAtom& atom) {
> _definedAtomIndex[&atom] = _definedAtomIvars.size();
> NativeDefinedAtomIvarsV1 ivar;
> unsigned refsCount;
> @@ -119,8 +138,7 @@
> _definedAtomIvars.push_back(ivar);
> }
>
> - // visitor routine called by forEachAtom()
> - virtual void doUndefinedAtom(const UndefinedAtom& atom) {
> + void addIVarsForUndefinedAtom(const UndefinedAtom& atom) {
> _undefinedAtomIndex[&atom] = _undefinedAtomIvars.size();
> NativeUndefinedAtomIvarsV1 ivar;
> ivar.nameOffset = getNameOffset(atom);
> @@ -128,8 +146,7 @@
> _undefinedAtomIvars.push_back(ivar);
> }
>
> - // visitor routine called by forEachAtom()
> - virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
> + void addIVarsForSharedLibraryAtom(const SharedLibraryAtom& atom) {
> _sharedLibraryAtomIndex[&atom] = _sharedLibraryAtomIvars.size();
> NativeSharedLibraryAtomIvarsV1 ivar;
> ivar.nameOffset = getNameOffset(atom);
> @@ -138,8 +155,7 @@
> _sharedLibraryAtomIvars.push_back(ivar);
> }
>
> - // visitor routine called by forEachAtom()
> - virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
> + void addIVarsForAbsoluteAtom(const AbsoluteAtom& atom) {
> _absoluteAtomIndex[&atom] = _absoluteAtomIvars.size();
> NativeAbsoluteAtomIvarsV1 ivar;
> ivar.nameOffset = getNameOffset(atom);
> @@ -148,10 +164,6 @@
> _absoluteAtomIvars.push_back(ivar);
> }
>
> - // visitor routine called by forEachAtom()
> - virtual void doFile(const File &) {
> - }
> -
> // fill out native file header and chunk directory
> void makeHeader() {
> const bool hasDefines = !_definedAtomIvars.empty();
> @@ -304,6 +316,7 @@
> return chunks[i];
> }
> assert(0 && "findChunk() signature not found");
> + static NativeChunk x; return x; // suppress warning
> }
>
> // append atom name to string pool and return offset
> @@ -403,23 +416,23 @@
> count = 0;
> size_t startRefSize = _references.size();
> uint32_t result = startRefSize;
> - atom.forEachReference(*this);
> + for (auto it=atom.referencesBegin(), end=atom.referencesEnd();
> + it != end; ++it) {
> + const Reference* ref = *it;
> + NativeReferenceIvarsV1 nref;
> + nref.offsetInAtom = ref->offsetInAtom();
> + nref.kind = ref->kind();
> + nref.targetIndex = this->getTargetIndex(ref->target());
> + nref.addendIndex = this->getAddendIndex(ref->addend());
> + _references.push_back(nref);
> + }
> count = _references.size() - startRefSize;
> if ( count == 0 )
> return 0;
> else
> return result;
> }
> -
> - void doReference(const Reference& ref) {
> - NativeReferenceIvarsV1 nref;
> - nref.offsetInAtom = ref.offsetInAtom();
> - nref.kind = ref.kind();
> - nref.targetIndex = this->getTargetIndex(ref.target());
> - nref.addendIndex = this->getAddendIndex(ref.addend());
> - _references.push_back(nref);
> - }
> -
> +
> uint32_t getTargetIndex(const Atom* target) {
> TargetToIndex::const_iterator pos = _targetsTableIndex.find(target);
> if ( pos != _targetsTableIndex.end() ) {
>
> Modified: lld/trunk/lib/Core/Resolver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/Resolver.cpp (original)
> +++ lld/trunk/lib/Core/Resolver.cpp Wed Mar 7 18:18:30 2012
> @@ -217,29 +217,18 @@
> }
> }
>
> -// helper to update targets for use with forEachReference()
> -class ReferenceUpdater : public DefinedAtom::ReferenceHandler {
> -public:
> - ReferenceUpdater(SymbolTable& sym) : _symbolTable(sym) { }
> -
> - virtual void doReference(const Reference& ref) {
> - const Atom* newTarget = _symbolTable.replacement(ref.target());
> - (const_cast<Reference*>(&ref))->setTarget(newTarget);
> - }
> -
> -private:
> - SymbolTable& _symbolTable;
> -};
> -
>
> // switch all references to undefined or coalesced away atoms
> // to the new defined atom
> void Resolver::updateReferences() {
> - ReferenceUpdater updater(_symbolTable);
> - for (std::vector<const Atom *>::iterator it = _atoms.begin();
> - it != _atoms.end(); ++it) {
> - if ( const DefinedAtom* defAtom = (*it)->definedAtom() ) {
> - defAtom->forEachReference(updater);
> + for (auto ait = _atoms.begin(); ait != _atoms.end(); ++ait) {
> + if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) {
> + for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd();
> + rit != end; ++rit) {
> + const Reference* ref = *rit;
> + const Atom* newTarget = _symbolTable.replacement(ref->target());
> + (const_cast<Reference*>(ref))->setTarget(newTarget);
> + }
> }
> }
> }
> @@ -272,8 +261,11 @@
> thisChain.previous = previous;
> thisChain.referer = &atom;
> if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
> - MarkLiveReferences markRefs(*this, &thisChain);
> - defAtom->forEachReference(markRefs);
> + for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd();
> + rit != end; ++rit) {
> + const Reference* ref = *rit;
> + this->markLive(*ref->target(), &thisChain);
> + }
> }
> }
>
> @@ -382,7 +374,7 @@
> // FIX ME
> }
>
> -std::vector<const Atom *> &Resolver::resolve() {
> +void Resolver::resolve() {
> this->initializeState();
> this->addInitialUndefines();
> this->buildInitialAtomList();
> @@ -394,7 +386,32 @@
> this->checkDylibSymbolCollisions();
> this->linkTimeOptimize();
> this->tweakAtoms();
> - return _atoms;
> + this->_result.addAtoms(_atoms);
> }
>
> +void Resolver::MergedFile::addAtom(const Atom& atom) {
> + if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
> + _definedAtoms._atoms.push_back(defAtom);
> + }
> + else if ( const UndefinedAtom* undefAtom = atom.undefinedAtom() ) {
> + _undefinedAtoms._atoms.push_back(undefAtom);
> + }
> + else if ( const SharedLibraryAtom* slAtom = atom.sharedLibraryAtom() ) {
> + _sharedLibraryAtoms._atoms.push_back(slAtom);
> + }
> + else if ( const AbsoluteAtom* abAtom = atom.absoluteAtom() ) {
> + _absoluteAtoms._atoms.push_back(abAtom);
> + }
> + else {
> + assert(0 && "atom has unknown definition kind");
> + }
> +}
> +
> +void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) {
> + for(std::vector<const Atom*>::iterator it=all.begin(); it != all.end(); ++it) {
> + this->addAtom(**it);
> + }
> +}
> +
> +
> } // namespace lld
>
> Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
> +++ lld/trunk/lib/Core/YamlKeyValues.cpp Wed Mar 7 18:18:30 2012
> @@ -137,6 +137,7 @@
> static const ContentTypeMapping typeMappings[] = {
> { "unknown", DefinedAtom::typeUnknown },
> { "code", DefinedAtom::typeCode },
> + { "stub", DefinedAtom::typeStub },
> { "resolver", DefinedAtom::typeResolver },
> { "constant", DefinedAtom::typeConstant },
> { "c-string", DefinedAtom::typeCString },
>
> Modified: lld/trunk/lib/Core/YamlReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/YamlReader.cpp (original)
> +++ lld/trunk/lib/Core/YamlReader.cpp Wed Mar 7 18:18:30 2012
> @@ -20,6 +20,8 @@
> #include "lld/Core/File.h"
> #include "lld/Core/Reference.h"
>
> +#include "lld/Platform/Platform.h"
> +
> #include "llvm/ADT/OwningPtr.h"
> #include "llvm/ADT/StringRef.h"
> #include "llvm/ADT/ArrayRef.h"
> @@ -297,10 +299,23 @@
> : File("path")
> , _lastRefIndex(0) {}
>
> - virtual bool forEachAtom(File::AtomHandler &) const;
> - virtual bool justInTimeforEachAtom(llvm::StringRef name,
> - File::AtomHandler &) const;
> + virtual const atom_collection<DefinedAtom>& defined() const {
> + return _definedAtoms;
> + }
> + virtual const atom_collection<UndefinedAtom>& undefined() const {
> + return _undefinedAtoms;
> + }
> + virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
> + return _sharedLibraryAtoms;
> + }
> + virtual const atom_collection<AbsoluteAtom>& absolute() const {
> + return _absoluteAtoms;
> + }
>
> + virtual void addAtom(const Atom&) {
> + assert(0 && "cannot add atoms to YAML files");
> + }
> +
> void bindTargetReferences();
> void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
> void addUndefinedAtom(UndefinedAtom* atom);
> @@ -314,13 +329,13 @@
> Atom* atom;
> };
>
> - std::vector<YAMLDefinedAtom*> _definedAtoms;
> - std::vector<UndefinedAtom*> _undefinedAtoms;
> - std::vector<SharedLibraryAtom*> _sharedLibraryAtoms;
> - std::vector<AbsoluteAtom*> _absoluteAtoms;
> - std::vector<YAMLReference> _references;
> - std::vector<NameAtomPair> _nameToAtomMapping;
> - unsigned int _lastRefIndex;
> + atom_collection_vector<DefinedAtom> _definedAtoms;
> + atom_collection_vector<UndefinedAtom> _undefinedAtoms;
> + atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
> + atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
> + std::vector<YAMLReference> _references;
> + std::vector<NameAtomPair> _nameToAtomMapping;
> + unsigned int _lastRefIndex;
> };
>
>
> @@ -434,14 +449,35 @@
> return _ord;
> }
>
> -
> - virtual void forEachReference(ReferenceHandler& handler) const {
> - for (uint32_t i=_refStartIndex; i < _refEndIndex; ++i) {
> - handler.doReference(_file._references[i]);
> - }
> + DefinedAtom::reference_iterator referencesBegin() const {
> + uintptr_t index = _refStartIndex;
> + const void* it = reinterpret_cast<const void*>(index);
> + return reference_iterator(*this, it);
> }
>
> - void bindTargetReferences() {
> + DefinedAtom::reference_iterator referencesEnd() const {
> + uintptr_t index = _refEndIndex;
> + const void* it = reinterpret_cast<const void*>(index);
> + return reference_iterator(*this, it);
> + }
> +
> + const Reference* derefIterator(const void* it) const {
> + uintptr_t index = reinterpret_cast<uintptr_t>(it);
> + assert(index >= _refStartIndex);
> + assert(index < _refEndIndex);
> + assert(index < _file._references.size());
> + return &_file._references[index];
> + }
> +
> + void incrementIterator(const void*& it) const {
> + uintptr_t index = reinterpret_cast<uintptr_t>(it);
> + ++index;
> + it = reinterpret_cast<const void*>(index);
> + }
> +
> +
> +
> + void bindTargetReferences() const {
> for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
> const char* targetName = _file._references[i]._targetName;
> Atom* targetAtom = _file.findAtom(targetName);
> @@ -559,40 +595,9 @@
>
>
>
> -
> -bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
> - handler.doFile(*this);
> - for (std::vector<YAMLDefinedAtom *>::const_iterator it = _definedAtoms.begin();
> - it != _definedAtoms.end(); ++it) {
> - handler.doDefinedAtom(**it);
> - }
> - for (std::vector<UndefinedAtom *>::const_iterator it = _undefinedAtoms.begin();
> - it != _undefinedAtoms.end(); ++it) {
> - handler.doUndefinedAtom(**it);
> - }
> - for (std::vector<SharedLibraryAtom *>::const_iterator
> - it = _sharedLibraryAtoms.begin();
> - it != _sharedLibraryAtoms.end(); ++it) {
> - handler.doSharedLibraryAtom(**it);
> - }
> - for (std::vector<AbsoluteAtom *>::const_iterator
> - it = _absoluteAtoms.begin();
> - it != _absoluteAtoms.end(); ++it) {
> - handler.doAbsoluteAtom(**it);
> - }
> -
> - return true;
> -}
> -
> -bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
> - File::AtomHandler &handler) const {
> - return false;
> -}
> -
> void YAMLFile::bindTargetReferences() {
> - for (std::vector<YAMLDefinedAtom *>::const_iterator
> - it = _definedAtoms.begin(); it != _definedAtoms.end(); ++it) {
> - YAMLDefinedAtom* atom = *it;
> + for (defined_iterator it = definedAtomsBegin(); it != definedAtomsEnd(); ++it) {
> + const YAMLDefinedAtom* atom = reinterpret_cast<const YAMLDefinedAtom*>(*it);
> atom->bindTargetReferences();
> }
> }
> @@ -607,31 +612,31 @@
> }
>
> void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName) {
> - _definedAtoms.push_back(atom);
> + _definedAtoms._atoms.push_back(atom);
> assert(refName != NULL);
> _nameToAtomMapping.push_back(NameAtomPair(refName, atom));
> }
>
> void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
> - _undefinedAtoms.push_back(atom);
> + _undefinedAtoms._atoms.push_back(atom);
> _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
> }
>
> void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom* atom) {
> - _sharedLibraryAtoms.push_back(atom);
> + _sharedLibraryAtoms._atoms.push_back(atom);
> _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
> }
>
> void YAMLFile::addAbsoluteAtom(AbsoluteAtom* atom) {
> - _absoluteAtoms.push_back(atom);
> + _absoluteAtoms._atoms.push_back(atom);
> _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
> }
>
>
> class YAMLAtomState {
> public:
> - YAMLAtomState();
> -
> + YAMLAtomState(Platform& platform);
> +
> void setName(const char *n);
> void setRefName(const char *n);
> void setAlign2(const char *n);
> @@ -642,6 +647,7 @@
>
> void makeAtom(YAMLFile&);
>
> + Platform& _platform;
> const char * _name;
> const char * _refName;
> const char * _sectionName;
> @@ -666,8 +672,9 @@
> };
>
>
> -YAMLAtomState::YAMLAtomState()
> - : _name(NULL)
> +YAMLAtomState::YAMLAtomState(Platform& platform)
> + : _platform(platform)
> + , _name(NULL)
> , _refName(NULL)
> , _sectionName(NULL)
> , _loadName(NULL)
> @@ -764,15 +771,7 @@
>
>
> void YAMLAtomState::setFixupKind(const char *s) {
> - if (strcmp(s, "pcrel32") == 0)
> - _ref._kind = 1;
> - else if (strcmp(s, "call32") == 0)
> - _ref._kind = 2;
> - else {
> - int k;
> - llvm::StringRef(s).getAsInteger(10, k);
> - _ref._kind = k;
> - }
> + _ref._kind = _platform.kindFromString(llvm::StringRef(s));
> }
>
> void YAMLAtomState::setFixupTarget(const char *s) {
> @@ -800,12 +799,13 @@
> /// parseObjectText - Parse the specified YAML formatted MemoryBuffer
> /// into lld::File object(s) and append each to the specified vector<File*>.
> llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
> - , std::vector<File *> &result) {
> + , Platform& platform
> + , std::vector<const File *> &result) {
> std::vector<const YAML::Entry *> entries;
> YAML::parse(mb, entries);
>
> YAMLFile *file = NULL;
> - YAMLAtomState atomState;
> + YAMLAtomState atomState(platform);
> bool inAtoms = false;
> bool inFixups = false;
> int depthForAtoms = -1;
> @@ -985,13 +985,14 @@
> // Fill in vector<File*> from path to input text file.
> //
> llvm::error_code parseObjectTextFileOrSTDIN(llvm::StringRef path
> - , std::vector<File*>& result) {
> + , Platform& platform
> + , std::vector<const File*>& result) {
> llvm::OwningPtr<llvm::MemoryBuffer> mb;
> llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
> if ( ec )
> return ec;
>
> - return parseObjectText(mb.get(), result);
> + return parseObjectText(mb.get(), platform, result);
> }
>
>
>
> Modified: lld/trunk/lib/Core/YamlWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/lib/Core/YamlWriter.cpp (original)
> +++ lld/trunk/lib/Core/YamlWriter.cpp Wed Mar 7 18:18:30 2012
> @@ -14,6 +14,8 @@
> #include "lld/Core/File.h"
> #include "lld/Core/Reference.h"
>
> +#include "lld/Platform/Platform.h"
> +
> #include "llvm/ADT/OwningPtr.h"
> #include "llvm/ADT/DenseMap.h"
> #include "llvm/ADT/StringExtras.h"
> @@ -41,44 +43,50 @@
> /// In that case referencing the function by name is ambiguous, so a unique
> /// ref-name is added.
> ///
> -class RefNameBuilder : public File::AtomHandler,
> - public DefinedAtom::ReferenceHandler {
> +class RefNameBuilder {
> public:
> - RefNameBuilder() { }
> -
> - virtual void doReference(const Reference& ref) {
> - // create refname for any unnamed reference target
> - if ( ref.target()->name().empty() ) {
> - char* buffer;
> - asprintf(&buffer, "L%03d", _unnamedCounter++);
> - _refNames[ref.target()] = buffer;
> + RefNameBuilder(const File& file)
> + : _collisionCount(0), _unnamedCounter(0) {
> + // visit all atoms
> + for(File::defined_iterator it=file.definedAtomsBegin(),
> + end=file.definedAtomsEnd();
> + it != end; ++it) {
> + const DefinedAtom* atom = *it;
> + // Build map of atoms names to detect duplicates
> + if ( ! atom->name().empty() )
> + buildDuplicateNameMap(*atom);
> +
> + // Find references to unnamed atoms and create ref-names for them.
> + for (auto rit=atom->referencesBegin(), rend=atom->referencesEnd();
> + rit != rend; ++rit) {
> + const Reference* ref = *rit;
> + // create refname for any unnamed reference target
> + if ( ref->target()->name().empty() ) {
> + char* buffer;
> + asprintf(&buffer, "L%03d", _unnamedCounter++);
> + _refNames[ref->target()] = buffer;
> + }
> + }
> + }
> + for(File::undefined_iterator it=file.undefinedAtomsBegin(),
> + end=file.undefinedAtomsEnd();
> + it != end; ++it) {
> + buildDuplicateNameMap(**it);
> + }
> + for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(),
> + end=file.sharedLibraryAtomsEnd();
> + it != end; ++it) {
> + buildDuplicateNameMap(**it);
> + }
> + for(File::absolute_iterator it=file.absoluteAtomsBegin(),
> + end=file.absoluteAtomsEnd();
> + it != end; ++it) {
> + buildDuplicateNameMap(**it);
> }
> - }
>
> - virtual void doFile(const File &) { }
> -
> - virtual void doDefinedAtom(const DefinedAtom& atom) {
> - // Build map of atoms names to detect duplicates
> - if ( ! atom.name().empty() )
> - buildDuplicateNameMap(atom);
> -
> - // Find references to unnamed atoms and create ref-names for them.
> - _unnamedCounter = 0;
> - atom.forEachReference(*this);
> - }
> -
> - virtual void doUndefinedAtom(const UndefinedAtom& atom) {
> - buildDuplicateNameMap(atom);
> - }
>
> - virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
> - buildDuplicateNameMap(atom);
> - }
> -
> - virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
> - buildDuplicateNameMap(atom);
> }
> -
> +
> void buildDuplicateNameMap(const Atom& atom) {
> assert(!atom.name().empty());
> NameToAtom::iterator pos = _nameMap.find(atom.name());
> @@ -131,27 +139,55 @@
> ///
> /// Helper class for writeObjectText() to write out atoms in yaml format.
> ///
> -class AtomWriter : public File::AtomHandler,
> - public DefinedAtom::ReferenceHandler {
> +class AtomWriter {
> public:
> - AtomWriter(RefNameBuilder& rnb, llvm::raw_ostream &out)
> - : _out(out), _rnb(rnb), _firstAtom(true) { }
> + AtomWriter(const File& file, Platform& platform, RefNameBuilder& rnb)
> + : _file(file), _platform(platform), _rnb(rnb), _firstAtom(true) { }
> +
> +
> + void write(llvm::raw_ostream& out) {
> + // write header
> + out << "---\n";
> +
> + // visit all atoms
> + for(File::defined_iterator it=_file.definedAtomsBegin(),
> + end=_file.definedAtomsEnd();
> + it != end; ++it) {
> + writeDefinedAtom(**it, out);
> + }
> + for(File::undefined_iterator it=_file.undefinedAtomsBegin(),
> + end=_file.undefinedAtomsEnd();
> + it != end; ++it) {
> + writeUndefinedAtom(**it, out);
> + }
> + for(File::shared_library_iterator it=_file.sharedLibraryAtomsBegin(),
> + end=_file.sharedLibraryAtomsEnd();
> + it != end; ++it) {
> + writeSharedLibraryAtom(**it, out);
> + }
> + for(File::absolute_iterator it=_file.absoluteAtomsBegin(),
> + end=_file.absoluteAtomsEnd();
> + it != end; ++it) {
> + writeAbsoluteAtom(**it, out);
> + }
> +
> + out << "...\n";
> + }
>
> - virtual void doFile(const class File &) { _firstAtom = true; }
>
> - virtual void doDefinedAtom(const class DefinedAtom &atom) {
> + void writeDefinedAtom(const DefinedAtom &atom, llvm::raw_ostream& out) {
> if ( _firstAtom ) {
> - _out << "atoms:\n";
> + out << "atoms:\n";
> _firstAtom = false;
> }
> else {
> // add blank line between atoms for readability
> - _out << "\n";
> + out << "\n";
> }
>
> bool hasDash = false;
> if ( !atom.name().empty() ) {
> - _out << " - "
> + out << " - "
> << KeyValues::nameKeyword
> << ":"
> << spacePadding(KeyValues::nameKeyword)
> @@ -161,7 +197,7 @@
> }
>
> if ( _rnb.hasRefName(&atom) ) {
> - _out << (hasDash ? " " : " - ")
> + out << (hasDash ? " " : " - ")
> << KeyValues::refNameKeyword
> << ":"
> << spacePadding(KeyValues::refNameKeyword)
> @@ -171,7 +207,7 @@
> }
>
> if ( atom.definition() != KeyValues::definitionDefault ) {
> - _out << (hasDash ? " " : " - ")
> + out << (hasDash ? " " : " - ")
> << KeyValues::definitionKeyword
> << ":"
> << spacePadding(KeyValues::definitionKeyword)
> @@ -181,7 +217,7 @@
> }
>
> if ( atom.scope() != KeyValues::scopeDefault ) {
> - _out << (hasDash ? " " : " - ")
> + out << (hasDash ? " " : " - ")
> << KeyValues::scopeKeyword
> << ":"
> << spacePadding(KeyValues::scopeKeyword)
> @@ -191,7 +227,7 @@
> }
>
> if ( atom.interposable() != KeyValues::interposableDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::interposableKeyword
> << ":"
> << spacePadding(KeyValues::interposableKeyword)
> @@ -200,7 +236,7 @@
> }
>
> if ( atom.merge() != KeyValues::mergeDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::mergeKeyword
> << ":"
> << spacePadding(KeyValues::mergeKeyword)
> @@ -209,7 +245,7 @@
> }
>
> if ( atom.contentType() != KeyValues::contentTypeDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::contentTypeKeyword
> << ":"
> << spacePadding(KeyValues::contentTypeKeyword)
> @@ -218,7 +254,7 @@
> }
>
> if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::deadStripKindKeyword
> << ":"
> << spacePadding(KeyValues::deadStripKindKeyword)
> @@ -227,14 +263,14 @@
> }
>
> if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::sectionChoiceKeyword
> << ":"
> << spacePadding(KeyValues::sectionChoiceKeyword)
> << KeyValues::sectionChoice(atom.sectionChoice())
> << "\n";
> assert( ! atom.customSectionName().empty() );
> - _out << " "
> + out << " "
> << KeyValues::sectionNameKeyword
> << ":"
> << spacePadding(KeyValues::sectionNameKeyword)
> @@ -243,7 +279,7 @@
> }
>
> if ( atom.isThumb() != KeyValues::isThumbDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::isThumbKeyword
> << ":"
> << spacePadding(KeyValues::isThumbKeyword)
> @@ -252,7 +288,7 @@
> }
>
> if ( atom.isAlias() != KeyValues::isAliasDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::isAliasKeyword
> << ":"
> << spacePadding(KeyValues::isAliasKeyword)
> @@ -262,7 +298,7 @@
>
> if ( (atom.contentType() != DefinedAtom::typeZeroFill)
> && (atom.size() != 0) ) {
> - _out << " "
> + out << " "
> << KeyValues::contentKeyword
> << ":"
> << spacePadding(KeyValues::contentKeyword)
> @@ -271,77 +307,77 @@
> bool needComma = false;
> for (unsigned int i=0; i < arr.size(); ++i) {
> if ( needComma )
> - _out << ", ";
> - _out << hexdigit(arr[i] >> 4);
> - _out << hexdigit(arr[i] & 0x0F);
> + out << ", ";
> + out << hexdigit(arr[i] >> 4);
> + out << hexdigit(arr[i] & 0x0F);
> needComma = true;
> }
> - _out << " ]\n";
> + out << " ]\n";
> }
>
> - _wroteFirstFixup = false;
> - atom.forEachReference(*this);
> - }
> -
> - virtual void doReference(const Reference& ref) {
> - if ( !_wroteFirstFixup ) {
> - _out << " fixups:\n";
> - _wroteFirstFixup = true;
> - }
> - _out << " - "
> - << KeyValues::fixupsOffsetKeyword
> - << ":"
> - << spacePadding(KeyValues::fixupsOffsetKeyword)
> - << ref.offsetInAtom()
> - << "\n";
> - _out << " "
> - << KeyValues::fixupsKindKeyword
> - << ":"
> - << spacePadding(KeyValues::fixupsKindKeyword)
> - << ref.kind()
> - << "\n";
> - const Atom* target = ref.target();
> - if ( target != NULL ) {
> - llvm::StringRef refName = target->name();
> - if ( _rnb.hasRefName(target) )
> - refName = _rnb.refName(target);
> - assert(!refName.empty());
> - _out << " "
> - << KeyValues::fixupsTargetKeyword
> - << ":"
> - << spacePadding(KeyValues::fixupsTargetKeyword)
> - << refName
> - << "\n";
> - }
> - if ( ref.addend() != 0 ) {
> - _out << " "
> - << KeyValues::fixupsAddendKeyword
> + bool wroteFirstFixup = false;
> + for (auto it=atom.referencesBegin(), end=atom.referencesEnd();
> + it != end; ++it) {
> + const Reference* ref = *it;
> + if ( !wroteFirstFixup ) {
> + out << " fixups:\n";
> + wroteFirstFixup = true;
> + }
> + out << " - "
> + << KeyValues::fixupsOffsetKeyword
> << ":"
> - << spacePadding(KeyValues::fixupsAddendKeyword)
> - << ref.addend()
> + << spacePadding(KeyValues::fixupsOffsetKeyword)
> + << ref->offsetInAtom()
> << "\n";
> + out << " "
> + << KeyValues::fixupsKindKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsKindKeyword)
> + << _platform.kindToString(ref->kind())
> + << "\n";
> + const Atom* target = ref->target();
> + if ( target != NULL ) {
> + llvm::StringRef refName = target->name();
> + if ( _rnb.hasRefName(target) )
> + refName = _rnb.refName(target);
> + assert(!refName.empty());
> + out << " "
> + << KeyValues::fixupsTargetKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsTargetKeyword)
> + << refName
> + << "\n";
> + }
> + if ( ref->addend() != 0 ) {
> + out << " "
> + << KeyValues::fixupsAddendKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsAddendKeyword)
> + << ref->addend()
> + << "\n";
> + }
> }
> }
> +
>
> -
> - virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
> + void writeUndefinedAtom(const UndefinedAtom &atom, llvm::raw_ostream& out) {
> if ( _firstAtom ) {
> - _out << "atoms:\n";
> + out << "atoms:\n";
> _firstAtom = false;
> }
> else {
> // add blank line between atoms for readability
> - _out << "\n";
> + out << "\n";
> }
>
> - _out << " - "
> + out << " - "
> << KeyValues::nameKeyword
> << ":"
> << spacePadding(KeyValues::nameKeyword)
> << atom.name()
> << "\n";
>
> - _out << " "
> + out << " "
> << KeyValues::definitionKeyword
> << ":"
> << spacePadding(KeyValues::definitionKeyword)
> @@ -349,7 +385,7 @@
> << "\n";
>
> if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
> - _out << " "
> + out << " "
> << KeyValues::canBeNullKeyword
> << ":"
> << spacePadding(KeyValues::canBeNullKeyword)
> @@ -358,24 +394,24 @@
> }
> }
>
> - virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
> + void writeSharedLibraryAtom(const SharedLibraryAtom& atom, llvm::raw_ostream& out) {
> if ( _firstAtom ) {
> - _out << "atoms:\n";
> + out << "atoms:\n";
> _firstAtom = false;
> }
> else {
> // add blank line between atoms for readability
> - _out << "\n";
> + out << "\n";
> }
>
> - _out << " - "
> + out << " - "
> << KeyValues::nameKeyword
> << ":"
> << spacePadding(KeyValues::nameKeyword)
> << atom.name()
> << "\n";
>
> - _out << " "
> + out << " "
> << KeyValues::definitionKeyword
> << ":"
> << spacePadding(KeyValues::definitionKeyword)
> @@ -383,7 +419,7 @@
> << "\n";
>
> if ( !atom.loadName().empty() ) {
> - _out << " "
> + out << " "
> << KeyValues::loadNameKeyword
> << ":"
> << spacePadding(KeyValues::loadNameKeyword)
> @@ -392,7 +428,7 @@
> }
>
> if ( atom.canBeNullAtRuntime() ) {
> - _out << " "
> + out << " "
> << KeyValues::canBeNullKeyword
> << ":"
> << spacePadding(KeyValues::canBeNullKeyword)
> @@ -401,37 +437,37 @@
> }
> }
>
> - virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
> + void writeAbsoluteAtom(const AbsoluteAtom& atom, llvm::raw_ostream& out) {
> if ( _firstAtom ) {
> - _out << "atoms:\n";
> + out << "atoms:\n";
> _firstAtom = false;
> }
> else {
> // add blank line between atoms for readability
> - _out << "\n";
> + out << "\n";
> }
>
> - _out << " - "
> + out << " - "
> << KeyValues::nameKeyword
> << ":"
> << spacePadding(KeyValues::nameKeyword)
> << atom.name()
> << "\n";
>
> - _out << " "
> + out << " "
> << KeyValues::definitionKeyword
> << ":"
> << spacePadding(KeyValues::definitionKeyword)
> << KeyValues::definition(atom.definition())
> << "\n";
>
> - _out << " "
> + out << " "
> << KeyValues::valueKeyword
> << ":"
> << spacePadding(KeyValues::valueKeyword)
> << "0x";
> - _out.write_hex(atom.value());
> - _out << "\n";
> + out.write_hex(atom.value());
> + out << "\n";
> }
>
>
> @@ -450,10 +486,10 @@
> return 'A' + nibble - 0x0A;
> }
>
> - llvm::raw_ostream& _out;
> - RefNameBuilder _rnb;
> + const File& _file;
> + Platform& _platform;
> + RefNameBuilder& _rnb;
> bool _firstAtom;
> - bool _wroteFirstFixup;
> };
>
> } // anonymous namespace
> @@ -464,16 +500,14 @@
> /// writeObjectText - writes the lld::File object as in YAML
> /// format to the specified stream.
> ///
> -void writeObjectText(const File &file, llvm::raw_ostream &out) {
> +void writeObjectText(const File& file, Platform& platform,
> + llvm::raw_ostream &out) {
> // Figure what ref-name labels are needed
> - RefNameBuilder rnb;
> - file.forEachAtom(rnb);
> + RefNameBuilder rnb(file);
>
> // Write out all atoms
> - AtomWriter h(rnb, out);
> - out << "---\n";
> - file.forEachAtom(h);
> - out << "...\n";
> + AtomWriter writer(file, platform, rnb);
> + writer.write(out);
> }
>
> } // namespace yaml
>
> Added: lld/trunk/lib/Passes/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/CMakeLists.txt?rev=152269&view=auto
> ==============================================================================
> --- lld/trunk/lib/Passes/CMakeLists.txt (added)
> +++ lld/trunk/lib/Passes/CMakeLists.txt Wed Mar 7 18:18:30 2012
> @@ -0,0 +1,3 @@
> +add_lld_library(lldPasses
> + StubsPass.cpp
> + )
>
> Added: lld/trunk/lib/Passes/StubsPass.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/StubsPass.cpp?rev=152269&view=auto
> ==============================================================================
> --- lld/trunk/lib/Passes/StubsPass.cpp (added)
> +++ lld/trunk/lib/Passes/StubsPass.cpp Wed Mar 7 18:18:30 2012
> @@ -0,0 +1,79 @@
> +//===- Passes/StubsPass.cpp - Adds stubs ----------------------------------===//
> +//
> +// The LLVM Linker
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +//
> +// This linker pass is
> +//
> +//
> +//
> +//
> +
> +
> +#include "llvm/ADT/DenseMap.h"
> +
> +#include "lld/Core/Pass.h"
> +#include "lld/Core/File.h"
> +#include "lld/Core/Reference.h"
> +#include "lld/Platform/Platform.h"
> +
> +
> +namespace lld {
> +
> +void StubsPass::perform() {
> + // Skip this pass if output format does not need stubs.
> + if ( !_platform.outputUsesStubs() )
> + return;
> +
> + // Use map so all call sites to same shlib symbol use same stub
> + llvm::DenseMap<const SharedLibraryAtom*, const Atom*> shlibToStub;
> +
> + // Scan all references in all atoms.
> + for(auto ait=_file.definedAtomsBegin(), aend=_file.definedAtomsEnd();
> + ait != aend; ++ait) {
> + const DefinedAtom* atom = *ait;
> + for (auto rit=atom->referencesBegin(), rend=atom->referencesEnd();
> + rit != rend; ++rit) {
> + const Reference* ref = *rit;
> + const Atom* target = ref->target();
> + assert(target != NULL);
> + // If the target of this reference is in a shared library
> + if ( const SharedLibraryAtom* shlbTarget = target->sharedLibraryAtom() ) {
> + // and this is a call to that shared library symbol.
> + if ( _platform.isBranch(ref) ) {
> + const Atom* stub;
> + // Replace the target with a reference to a stub
> + auto pos = shlibToStub.find(shlbTarget);
> + if ( pos == shlibToStub.end() ) {
> + // This is no existing stub. Create a new one.
> + stub = _platform.makeStub(*shlbTarget, _file);
> + shlibToStub[shlbTarget] = stub;
> + }
> + else {
> + // Reuse and existing stub
> + stub = pos->second;
> + }
> + assert(stub != NULL);
> + // Switch call site in atom to refrence stub instead of shlib atom.
> + (const_cast<Reference*>(ref))->setTarget(stub);
> + }
> + }
> + }
> + }
> +
> + // add all created stubs to file
> + for (auto it=shlibToStub.begin(), end=shlibToStub.end(); it != end; ++it) {
> + _file.addAtom(*it->second);
> + }
> +
> +
> +}
> +
> +
> +
> +}
>
> Added: lld/trunk/test/pass-stubs-basic.objtxt
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pass-stubs-basic.objtxt?rev=152269&view=auto
> ==============================================================================
> --- lld/trunk/test/pass-stubs-basic.objtxt (added)
> +++ lld/trunk/test/pass-stubs-basic.objtxt Wed Mar 7 18:18:30 2012
> @@ -0,0 +1,50 @@
> +# RUN: lld-core %s -stubs_pass | FileCheck %s
> +
> +#
> +# Test that stubs pass adds stubs and rebinds call sites to the stub
> +#
> +
> +---
> +atoms:
> + - name: foo
> + type: code
> + content: [ E8, 00, 00, 00, 00, E8, 00, 00, 00,
> + 00, 48 ,8B, 05, 00, 00, 00, 00 ]
> + fixups:
> + - offset: 1
> + kind: call32
> + target: malloc
> + - offset: 6
> + kind: call32
> + target: free
> + - offset: 13
> + kind: gotLoad32
> + target: malloc
> +
> + - name: malloc
> + definition: shared-library
> + load-name: libc.so
> +
> + - name: free
> + definition: shared-library
> + load-name: libc.so
> +
> +...
> +
> +# CHECK: name: foo
> +# CHECK: fixups:
> +# CHECK: kind: call32
> +# CHECK: target: L
> +# CHECK: kind: call32
> +# CHECK: target: L
> +# CHECK: kind: gotLoad32
> +# CHECK: target: malloc
> +# CHECK: name: L
> +# CHECK: type: stub
> +# CHECK: name: L
> +# CHECK: type: stub
> +# CHECK: name: malloc
> +# CHECK: definition: shared-library
> +# CHECK: name: free
> +# CHECK: definition: shared-library
> +# CHECK: ...
>
> Modified: lld/trunk/tools/lld-core/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/CMakeLists.txt?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/tools/lld-core/CMakeLists.txt (original)
> +++ lld/trunk/tools/lld-core/CMakeLists.txt Wed Mar 7 18:18:30 2012
> @@ -1,5 +1,6 @@
> set(LLVM_USED_LIBS
> lldCore
> + lldPasses
> )
>
> set(LLVM_LINK_COMPONENTS
>
> Modified: lld/trunk/tools/lld-core/lld-core.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=152269&r1=152268&r2=152269&view=diff
> ==============================================================================
> --- lld/trunk/tools/lld-core/lld-core.cpp (original)
> +++ lld/trunk/tools/lld-core/lld-core.cpp Wed Mar 7 18:18:30 2012
> @@ -11,6 +11,7 @@
> #include "lld/Core/Atom.h"
> #include "lld/Core/DefinedAtom.h"
> #include "lld/Core/UndefinedAtom.h"
> +#include "lld/Core/Pass.h"
> #include "lld/Core/Resolver.h"
> #include "lld/Core/YamlReader.h"
> #include "lld/Core/YamlWriter.h"
> @@ -22,6 +23,7 @@
> #include "llvm/ADT/StringRef.h"
> #include "llvm/ADT/SmallString.h"
> #include "llvm/ADT/Twine.h"
> +#include "llvm/Support/CommandLine.h"
> #include "llvm/Support/DataTypes.h"
> #include "llvm/Support/ManagedStatic.h"
> #include "llvm/Support/MemoryBuffer.h"
> @@ -49,15 +51,110 @@
> }
>
> namespace {
> -class LdCore : public InputFiles, public Platform {
> +
> +
> +//
> +// Simple atoms created by the stubs pass.
> +//
> +class TestingStubAtom : public DefinedAtom {
> public:
> - LdCore(std::vector<File *> &f) : _files(f) { }
> + TestingStubAtom(const File& f, const SharedLibraryAtom& shlib) :
> + _file(f), _shlib(shlib) {
> + static uint32_t lastOrdinal = 0;
> + _ordinal = lastOrdinal++;
> + }
>
> - // InputFiles interface
> - virtual void forEachInitialAtom(File::AtomHandler &) const;
> - virtual bool searchLibraries(llvm::StringRef name, bool searchDylibs,
> - bool searchArchives, bool dataSymbolOnly,
> - File::AtomHandler &) const;
> + virtual const File& file() const {
> + return _file;
> + }
> +
> + virtual llvm::StringRef name() const {
> + return llvm::StringRef();
> + }
> +
> + virtual uint64_t ordinal() const {
> + return _ordinal;
> + }
> +
> + virtual uint64_t size() const {
> + return 0;
> + }
> +
> + virtual Scope scope() const {
> + return DefinedAtom::scopeLinkageUnit;
> + }
> +
> + virtual Interposable interposable() const {
> + return DefinedAtom::interposeNo;
> + }
> +
> + virtual Merge merge() const {
> + return DefinedAtom::mergeNo;
> + }
> +
> + virtual ContentType contentType() const {
> + return DefinedAtom::typeStub;
> + }
> +
> + virtual Alignment alignment() const {
> + return Alignment(0,0);
> + }
> +
> + virtual SectionChoice sectionChoice() const {
> + return DefinedAtom::sectionBasedOnContent;
> + }
> +
> + virtual llvm::StringRef customSectionName() const {
> + return llvm::StringRef();
> + }
> + virtual DeadStripKind deadStrip() const {
> + return DefinedAtom::deadStripNormal;
> + }
> +
> + virtual ContentPermissions permissions() const {
> + return DefinedAtom::permR_X;
> + }
> +
> + virtual bool isThumb() const {
> + return false;
> + }
> +
> + virtual bool isAlias() const {
> + return false;
> + }
> +
> + virtual llvm::ArrayRef<uint8_t> rawContent() const {
> + return llvm::ArrayRef<uint8_t>();
> + }
> +
> + virtual reference_iterator referencesBegin() const {
> + return reference_iterator(*this, NULL);
> + }
> +
> + virtual reference_iterator referencesEnd() const {
> + return reference_iterator(*this, NULL);
> + }
> +
> + virtual const Reference* derefIterator(const void* iter) const {
> + return NULL;
> + }
> +
> + virtual void incrementIterator(const void*& iter) const {
> +
> + }
> +
> +private:
> + const File& _file;
> + const SharedLibraryAtom& _shlib;
> + uint32_t _ordinal;
> +};
> +
> +
> +//
> +// A simple platform for testing.
> +//
> +class TestingPlatform : public Platform {
> +public:
>
> virtual void initialize() { }
>
> @@ -155,97 +252,163 @@
> // last chance for platform to tweak atoms
> virtual void postResolveTweaks(std::vector<const Atom *> &all) {}
>
> -private:
> - std::vector<File *> &_files;
> -};
> -}
> + virtual bool outputUsesStubs() { return true; };
> +
> +
> + struct KindMapping {
> + const char* string;
> + Reference::Kind value;
> + bool isBranch;
> + };
>
> -void LdCore::forEachInitialAtom(File::AtomHandler &handler) const {
> - for (std::vector<File *>::iterator it = _files.begin();
> - it != _files.end(); ++it) {
> - const File *file = *it;
> - handler.doFile(*file);
> - file->forEachAtom(handler);
> + static const KindMapping _s_kindMappings[];
> +
> + virtual Reference::Kind kindFromString(llvm::StringRef kindName) {
> + for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
> + if ( kindName.equals(p->string) )
> + return p->value;
> + }
> + int k;
> + kindName.getAsInteger(0, k);
> + return k;
> + }
> +
> + virtual llvm::StringRef kindToString(Reference::Kind value) {
> + for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
> + if ( value == p->value)
> + return p->string;
> + }
> + return llvm::StringRef("???");
> }
> -}
>
> -bool LdCore::searchLibraries(llvm::StringRef name, bool searchDylibs,
> - bool searchArchives, bool dataSymbolOnly,
> - File::AtomHandler &) const {
> - return false;
> -}
>
> -namespace {
> -class MergedFile : public File {
> + virtual bool isBranch(const Reference* ref) {
> + Reference::Kind value = ref->kind();
> + for (const KindMapping* p = _s_kindMappings; p->string != NULL; ++p) {
> + if ( value == p->value )
> + return p->isBranch;
> + }
> + return false;
> + }
> +
> + virtual const Atom* makeStub(const SharedLibraryAtom& shlibAtom, File& file) {
> + return new TestingStubAtom(file, shlibAtom);
> + }
> +};
> +
> +
> +//
> +// Table of fixup kinds in YAML documents used for testing
> +//
> +const TestingPlatform::KindMapping TestingPlatform::_s_kindMappings[] = {
> + { "call32", 1, true },
> + { "pcrel32", 2, false },
> + { "gotLoad32", 3, false },
> + { NULL, 0, false }
> + };
> +
> +
> +//
> +// A simple input files wrapper for testing.
> +//
> +class TestingInputFiles : public InputFiles {
> public:
> - MergedFile(std::vector<const Atom *> &a)
> - : File("path"), _atoms(a) { }
> + TestingInputFiles(std::vector<const File*>& f) : _files(f) { }
>
> - virtual bool forEachAtom(File::AtomHandler &handler) const {
> - handler.doFile(*this);
> - // visit defined atoms
> - for (std::vector<const Atom *>::iterator it = _atoms.begin();
> - it != _atoms.end(); ++it) {
> - const DefinedAtom* atom = (*it)->definedAtom();
> - if ( atom )
> - handler.doDefinedAtom(*atom);
> - }
> - // visit undefined atoms
> - for (std::vector<const Atom *>::iterator it = _atoms.begin();
> - it != _atoms.end(); ++it) {
> - const UndefinedAtom* atom = (*it)->undefinedAtom();
> - if ( atom )
> - handler.doUndefinedAtom(*atom);
> - }
> - // visit shared library atoms
> - for (std::vector<const Atom *>::iterator it = _atoms.begin();
> - it != _atoms.end(); ++it) {
> - const SharedLibraryAtom* atom = (*it)->sharedLibraryAtom();
> - if ( atom )
> - handler.doSharedLibraryAtom(*atom);
> - }
> - // visit absolute atoms
> - for (std::vector<const Atom *>::iterator it = _atoms.begin();
> - it != _atoms.end(); ++it) {
> - const AbsoluteAtom* atom = (*it)->absoluteAtom();
> - if ( atom )
> - handler.doAbsoluteAtom(*atom);
> + // InputFiles interface
> + virtual void forEachInitialAtom(InputFiles::Handler& handler) const {
> + for (std::vector<const File *>::iterator fit = _files.begin();
> + fit != _files.end(); ++fit) {
> + const File* file = *fit;
> + handler.doFile(*file);
> + for(auto it=file->definedAtomsBegin(),end=file->definedAtomsEnd();
> + it != end; ++it) {
> + handler.doDefinedAtom(**it);
> + }
> + for(auto it=file->undefinedAtomsBegin(), end=file->undefinedAtomsEnd();
> + it != end; ++it) {
> + handler.doUndefinedAtom(**it);
> + }
> + for(auto it=file->sharedLibraryAtomsBegin(), end=file->sharedLibraryAtomsEnd();
> + it != end; ++it) {
> + handler.doSharedLibraryAtom(**it);
> + }
> + for(auto it=file->absoluteAtomsBegin(),end=file->absoluteAtomsEnd();
> + it != end; ++it) {
> + handler.doAbsoluteAtom(**it);
> + }
> }
> - return true;
> }
>
> - virtual bool justInTimeforEachAtom(llvm::StringRef name,
> - File::AtomHandler &) const {
> + virtual bool searchLibraries(llvm::StringRef name, bool searchDylibs,
> + bool searchArchives, bool dataSymbolOnly,
> + InputFiles::Handler &) const {
> return false;
> }
>
> +
> private:
> - std::vector<const Atom *> &_atoms;
> + std::vector<const File*>& _files;
> };
> -} //anonymous namespace
> +}
> +
> +
> +
>
>
> -int main(int argc, const char *argv[]) {
> +
> +llvm::cl::opt<std::string>
> +gInputFilePath(llvm::cl::Positional,
> + llvm::cl::desc("<input file>"),
> + llvm::cl::init("-"));
> +
> +llvm::cl::opt<std::string>
> +gOutputFilePath("o",
> + llvm::cl::desc("Specify output filename"),
> + llvm::cl::value_desc("filename"));
> +
> +llvm::cl::opt<bool>
> +gDoStubsPass("stubs_pass",
> + llvm::cl::desc("Run pass to create stub atoms"));
> +
> +
> +int main(int argc, char *argv[]) {
> // Print a stack trace if we signal out.
> llvm::sys::PrintStackTraceOnErrorSignal();
> llvm::PrettyStackTraceProgram X(argc, argv);
> llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
>
> + // parse options
> + llvm::cl::ParseCommandLineOptions(argc, argv);
> +
> + // create platform for testing
> + TestingPlatform testingPlatform;
> +
> // read input YAML doc into object file(s)
> - std::vector<File *> files;
> - if (error(yaml::parseObjectTextFileOrSTDIN(llvm::StringRef(argv[1]), files)))
> + std::vector<const File *> files;
> + if (error(yaml::parseObjectTextFileOrSTDIN(gInputFilePath,
> + testingPlatform, files))) {
> return 1;
> -
> + }
> +
> + // create object to mange input files
> + TestingInputFiles inputFiles(files);
> +
> // merge all atom graphs
> - LdCore core(files);
> - Resolver resolver(core, core);
> - std::vector<const Atom *> &mergedAtoms = resolver.resolve();
> - MergedFile outFile(mergedAtoms);
> + Resolver resolver(testingPlatform, inputFiles);
> + resolver.resolve();
>
> + // run passes
> + if ( gDoStubsPass ) {
> + StubsPass addStubs(resolver.resultFile(), testingPlatform);
> + addStubs.perform();
> + }
> +
> // write new atom graph out as YAML doc
> std::string errorInfo;
> - llvm::raw_fd_ostream out("-", errorInfo);
> -// yaml::writeObjectText(outFile, out);
> + const char* outPath = gOutputFilePath.empty() ? "-" : gOutputFilePath.c_str();
> + llvm::raw_fd_ostream out(outPath, errorInfo);
> +// yaml::writeObjectText(resolver.resultFile(), out);
>
> // make unique temp .o file to put generated object file
> int fd;
> @@ -254,7 +417,7 @@
> llvm::raw_fd_ostream binaryOut(fd, /*shouldClose=*/true);
>
> // write native file
> - writeNativeObjectFile(outFile, binaryOut);
> + writeNativeObjectFile(resolver.resultFile(), binaryOut);
> binaryOut.close(); // manually close so that file can be read next
>
> // out << "native file: " << tempPath.str() << "\n";
> @@ -265,7 +428,7 @@
> return 1;
>
> // write new atom graph out as YAML doc
> - yaml::writeObjectText(*natFile, out);
> + yaml::writeObjectText(*natFile, testingPlatform, out);
>
> // delete temp .o file
> bool existed;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list