[lld] r234641 - Remove the Native file format.

Rafael EspĂ­ndola rafael.espindola at gmail.com
Sun Apr 12 05:20:53 PDT 2015


Thank you so much!
On Apr 10, 2015 5:28 PM, "Rui Ueyama" <ruiu at google.com> wrote:

> Author: ruiu
> Date: Fri Apr 10 16:23:51 2015
> New Revision: 234641
>
> URL: http://llvm.org/viewvc/llvm-project?rev=234641&view=rev
> Log:
> Remove the Native file format.
>
> The Native file format was designed to be the fastest on-memory or
> on-disk file format for object files. The problem is that no one
> is working on that. No LLVM tools can produce object files in
> the Native, thus the feature of supporting the format is useless
> in the linker.
>
> This patch removes the Native file support. We can add it back
> if we really want it in future.
>
> Removed:
>     lld/trunk/lib/Core/TODO.txt
>     lld/trunk/lib/ReaderWriter/Native/CMakeLists.txt
>     lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
>     lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
>     lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
> Modified:
>     lld/trunk/docs/Readers.rst
>     lld/trunk/docs/design.rst
>     lld/trunk/docs/index.rst
>     lld/trunk/include/lld/Core/Error.h
>     lld/trunk/include/lld/Core/LinkingContext.h
>     lld/trunk/include/lld/Core/Reader.h
>     lld/trunk/include/lld/Core/TODO.txt
>     lld/trunk/include/lld/Core/Writer.h
>     lld/trunk/lib/Core/Error.cpp
>     lld/trunk/lib/Driver/CoreDriver.cpp
>     lld/trunk/lib/Driver/DarwinLdDriver.cpp
>     lld/trunk/lib/Driver/GnuLdDriver.cpp
>     lld/trunk/lib/Driver/GnuLdOptions.td
>     lld/trunk/lib/Driver/WinLinkDriver.cpp
>     lld/trunk/lib/ReaderWriter/CMakeLists.txt
>     lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
>     lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
>     lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
>
> Modified: lld/trunk/docs/Readers.rst
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/docs/Readers.rst?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/docs/Readers.rst (original)
> +++ lld/trunk/docs/Readers.rst Fri Apr 10 16:23:51 2015
> @@ -52,10 +52,9 @@ Where to start
>  --------------
>
>  The lld project already has a skeleton of source code for Readers for
> -``ELF``, ``PECOFF``, ``MachO``, and lld's native Atom graph format
> -(both binary ``Native`` and ``YAML`` representations).  If your file
> format
> -is a variant of one of those, you should modify the existing Reader to
> -support your variant. This is done by customizing the Options
> +``ELF``, ``PECOFF``, ``MachO``, and lld's native ``YAML`` graph format.
> +If your file format is a variant of one of those, you should modify the
> +existing Reader to support your variant. This is done by customizing the
> Options
>  class for the Reader and making appropriate changes to the ``.cpp`` file
> to
>  interpret those options and act accordingly.
>
>
> Modified: lld/trunk/docs/design.rst
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/docs/design.rst?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/docs/design.rst (original)
> +++ lld/trunk/docs/design.rst Fri Apr 10 16:23:51 2015
> @@ -300,60 +300,13 @@ and the ivars programmatically set.
>  lld::File representations
>  -------------------------
>
> -Just as LLVM has three representations of its IR model, lld has three
> +Just as LLVM has three representations of its IR model, lld has two
>  representations of its File/Atom/Reference model:
>
>   * In memory, abstract C++ classes (lld::Atom, lld::Reference, and
> lld::File).
>
>   * textual (in YAML)
>
> - * binary format ("native")
> -
> -Binary File Format
> -~~~~~~~~~~~~~~~~~~
> -
> -In theory, lld::File objects could be written to disk in an existing
> Object File
> -format standard (e.g. ELF).  Instead we choose to define a new binary file
> -format. There are two main reasons for this: fidelity and performance.
> In order
> -for lld to work as a linker on all platforms, its internal model must be
> rich
> -enough to model all CPU and OS linking features.  But if we choose an
> existing
> -Object File format as the lld binary format, that means an on going need
> to
> -retrofit each platform specific feature needed from alternate platforms
> into the
> -existing Object File format.  Having our own "native" binary format side
> steps
> -that issue.  We still need to be able to binary encode all the features,
> but
> -once the in-memory model can represent the feature, it is straight
> forward to
> -binary encode it.
> -
> -The reason to use a binary file format at all, instead of a textual file
> format,
> -is speed.  You want the binary format to be as fast as possible to read
> into the
> -in-memory model. Given that we control the in-memory model and the binary
> -format, the obvious way to make reading super fast it to make the file
> format be
> -basically just an array of atoms.  The reader just mmaps in the file and
> looks
> -at the header to see how many atoms there are and instantiate that many
> atom
> -objects with the atom attribute information coming from that array.  The
> trick
> -is designing this in a way that can be extended as the Atom mode evolves
> and new
> -attributes are added.
> -
> -The native object file format starts with a header that lists how many
> "chunks"
> -are in the file.  A chunk is an array of "ivar data".  The native file
> reader
> -instantiates an array of Atom objects (with one large malloc call).  Each
> atom
> -contains just a pointer to its vtable and a pointer to its ivar data.  All
> -methods on lld::Atom are virtual, so all the method implementations return
> -values based on the ivar data to which it has a pointer.  If a new linking
> -features is added which requires a change to the lld::Atom model, a new
> native
> -reader class (e.g. version 2) is defined which knows how to read the new
> feature
> -information from the new ivar data.  The old reader class (e.g. version
> 1) is
> -updated to do its best to model (the lack of the new feature) given the
> old ivar
> -data in existing native object files.
> -
> -With this model for the native file format, files can be read and turned
> -into the in-memory graph of lld::Atoms with just a few memory allocations.
> -And the format can easily adapt over time to new features.
> -
> -The binary file format follows the ReaderWriter patterns used in lld. The
> lld
> -library comes with the classes: ReaderNative and WriterNative.  So,
> switching
> -between file formats is as easy as switching which Reader subclass is
> used.
> -
>
>  Textual representations in YAML
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Modified: lld/trunk/docs/index.rst
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/docs/index.rst?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/docs/index.rst (original)
> +++ lld/trunk/docs/index.rst Fri Apr 10 16:23:51 2015
> @@ -26,8 +26,6 @@ lld is a new set of modular code for cre
>
>    * Extensive unit tests
>    * Internal linker model can be dumped/read to textual format
> -  * Internal linker model can be dumped/read to a new native format
> -  * Native format designed to be fast to read and write
>    * Additional linking features can be plugged in as "passes"
>    * OS specific and CPU specific code factored out
>
>
> Modified: lld/trunk/include/lld/Core/Error.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Error.h?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/Error.h (original)
> +++ lld/trunk/include/lld/Core/Error.h Fri Apr 10 16:23:51 2015
> @@ -19,22 +19,6 @@
>
>  namespace lld {
>
> -const std::error_category &native_reader_category();
> -
> -enum class NativeReaderError {
> -  success = 0,
> -  unknown_file_format,
> -  file_too_short,
> -  file_malformed,
> -  unknown_chunk_type,
> -  memory_error,
> -  conflicting_target_machine,
> -};
> -
> -inline std::error_code make_error_code(NativeReaderError e) {
> -  return std::error_code(static_cast<int>(e), native_reader_category());
> -}
> -
>  const std::error_category &YamlReaderCategory();
>
>  enum class YamlReaderError {
> @@ -72,8 +56,6 @@ std::error_code make_dynamic_error_code(
>  } // end namespace lld
>
>  namespace std {
> -template <>
> -struct is_error_code_enum<lld::NativeReaderError> : std::true_type {};
>  template <> struct is_error_code_enum<lld::YamlReaderError> :
> std::true_type {};
>  template <>
>  struct is_error_code_enum<lld::LinkerScriptReaderError> : std::true_type
> {};
>
> Modified: lld/trunk/include/lld/Core/LinkingContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/LinkingContext.h (original)
> +++ lld/trunk/include/lld/Core/LinkingContext.h Fri Apr 10 16:23:51 2015
> @@ -41,7 +41,6 @@ public:
>    enum class OutputFileType : uint8_t {
>      Default, // The default output type for this target
>      YAML,    // The output type is set to YAML
> -    Native   // The output file format is Native (Atoms)
>    };
>
>    virtual ~LinkingContext();
> @@ -273,13 +272,11 @@ public:
>    /// Set the various output file types that the linker would
>    /// create
>    bool setOutputFileType(StringRef outputFileType) {
> -    if (outputFileType.equals_lower("yaml"))
> +    if (outputFileType.equals_lower("yaml")) {
>        _outputFileType = OutputFileType::YAML;
> -    else if (outputFileType.equals_lower("native"))
> -      _outputFileType = OutputFileType::YAML;
> -    else
> -      return false;
> -    return true;
> +      return true;
> +    }
> +    return false;
>    }
>
>    /// Returns the output file type that that the linker needs to create.
>
> Modified: lld/trunk/include/lld/Core/Reader.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reader.h?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/Reader.h (original)
> +++ lld/trunk/include/lld/Core/Reader.h Fri Apr 10 16:23:51 2015
> @@ -36,7 +36,7 @@ class MachOLinkingContext;
>  /// \brief An abstract class for reading object files, library files, and
>  /// executable files.
>  ///
> -/// Each file format (e.g. ELF, mach-o, PECOFF, native, etc) have a
> concrete
> +/// Each file format (e.g. ELF, mach-o, PECOFF, etc) have a concrete
>  /// subclass of Reader.
>  class Reader {
>  public:
> @@ -115,7 +115,6 @@ public:
>    // as parameters to the addSupport*() method.
>    void addSupportArchives(bool logLoading);
>    void addSupportYamlFiles();
> -  void addSupportNativeObjects();
>    void addSupportCOFFObjects(PECOFFLinkingContext &);
>    void addSupportCOFFImportLibraries(PECOFFLinkingContext &);
>    void addSupportMachOObjects(MachOLinkingContext &);
>
> Modified: lld/trunk/include/lld/Core/TODO.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/TODO.txt?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/TODO.txt (original)
> +++ lld/trunk/include/lld/Core/TODO.txt Fri Apr 10 16:23:51 2015
> @@ -1,7 +1,7 @@
>  include/lld/Core
>  ~~~~~~~~~~~~~~~~
>
> -* The native/yaml reader/writer interfaces should be changed to return
> +* The yaml reader/writer interfaces should be changed to return
>    an explanatory string if there is an error.  The existing error_code
>    abstraction only works for returning low level OS errors.  It does not
>    work for describing formatting issues.
>
> Modified: lld/trunk/include/lld/Core/Writer.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Writer.h?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/Writer.h (original)
> +++ lld/trunk/include/lld/Core/Writer.h Fri Apr 10 16:23:51 2015
> @@ -23,7 +23,7 @@ class PECOFFLinkingContext;
>
>  /// \brief The Writer is an abstract class for writing object files,
> shared
>  /// library files, and executable files.  Each file format (e.g. ELF,
> mach-o,
> -/// PECOFF, native, etc) have a concrete subclass of Writer.
> +/// PECOFF, etc) have a concrete subclass of Writer.
>  class Writer {
>  public:
>    virtual ~Writer();
> @@ -44,7 +44,6 @@ protected:
>  std::unique_ptr<Writer> createWriterELF(const ELFLinkingContext &);
>  std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &);
>  std::unique_ptr<Writer> createWriterPECOFF(const PECOFFLinkingContext &);
> -std::unique_ptr<Writer> createWriterNative();
>  std::unique_ptr<Writer> createWriterYAML(const LinkingContext &);
>  } // end namespace lld
>
>
> Modified: lld/trunk/lib/Core/Error.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Error.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/Error.cpp (original)
> +++ lld/trunk/lib/Core/Error.cpp Fri Apr 10 16:23:51 2015
> @@ -16,39 +16,6 @@
>
>  using namespace lld;
>
> -class _NativeReaderErrorCategory : public std::error_category {
> -public:
> -  const char* name() const LLVM_NOEXCEPT override {
> -    return "lld.native.reader";
> -  }
> -
> -  std::string message(int ev) const override {
> -    switch (static_cast<NativeReaderError>(ev)) {
> -    case NativeReaderError::success:
> -      return "Success";
> -    case NativeReaderError::unknown_file_format:
> -      return "Unknown file format";
> -    case NativeReaderError::file_too_short:
> -      return "file truncated";
> -    case NativeReaderError::file_malformed:
> -      return "file malformed";
> -    case NativeReaderError::memory_error:
> -      return "out of memory";
> -    case NativeReaderError::unknown_chunk_type:
> -      return "unknown chunk type";
> -    case NativeReaderError::conflicting_target_machine:
> -      return "conflicting target machine";
> -    }
> -    llvm_unreachable("An enumerator of NativeReaderError does not have a "
> -                     "message defined.");
> -  }
> -};
> -
> -const std::error_category &lld::native_reader_category() {
> -  static _NativeReaderErrorCategory o;
> -  return o;
> -}
> -
>  class _YamlReaderErrorCategory : public std::error_category {
>  public:
>    const char* name() const LLVM_NOEXCEPT override {
>
> Removed: lld/trunk/lib/Core/TODO.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/TODO.txt?rev=234640&view=auto
>
> ==============================================================================
> --- lld/trunk/lib/Core/TODO.txt (original)
> +++ lld/trunk/lib/Core/TODO.txt (removed)
> @@ -1,18 +0,0 @@
> -lib/Core
> -~~~~~~~~
> -
> -* Add endianness support to the native reader and writer.
> -
> -* The NativeReader has lots of similar code for converting arrays of ivar
> -  data in mapped memory into arrays of objects.  The commonality can be
> -  factored out, maybe templatized.
> -
> -* The NativeFileFormat.h is old school C structs and constants.  We scope
> -  things better by defining constants used with a struct inside the struct
> -  declaration.
> -
> -* The native reader and writer currently just blast in memory enumeration
> -  values (e.g. DefinedAtom::Scope) into a byte in the disk format.  To
> support
> -  future changes to the enumerations, there should be a translation layer
> -  to map disk values to in-memory values.
> -
>
> Modified: lld/trunk/lib/Driver/CoreDriver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CoreDriver.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Driver/CoreDriver.cpp (original)
> +++ lld/trunk/lib/Driver/CoreDriver.cpp Fri Apr 10 16:23:51 2015
> @@ -77,7 +77,6 @@ bool CoreDriver::link(int argc, const ch
>    CoreLinkingContext ctx;
>
>    // Register possible input file parsers.
> -  ctx.registry().addSupportNativeObjects();
>    ctx.registry().addSupportYamlFiles();
>    ctx.registry().addKindTable(Reference::KindNamespace::testing,
>                                Reference::KindArch::all, coreKindStrings);
>
> Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
> +++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Fri Apr 10 16:23:51 2015
> @@ -544,7 +544,6 @@ bool DarwinLdDriver::parse(int argc, con
>    if (!ctx.doNothing()) {
>      ctx.registry().addSupportMachOObjects(ctx);
>      ctx.registry().addSupportArchives(ctx.logInputFiles());
> -    ctx.registry().addSupportNativeObjects();
>      ctx.registry().addSupportYamlFiles();
>    }
>
>
> Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
> +++ lld/trunk/lib/Driver/GnuLdDriver.cpp Fri Apr 10 16:23:51 2015
> @@ -645,7 +645,6 @@ bool GnuLdDriver::parse(int argc, const
>    ctx->registry().addSupportELFObjects(*ctx);
>    ctx->registry().addSupportArchives(ctx->logInputFiles());
>    ctx->registry().addSupportYamlFiles();
> -  ctx->registry().addSupportNativeObjects();
>    if (ctx->allowLinkWithDynamicLibraries())
>      ctx->registry().addSupportELFDynamicSharedObjects(*ctx);
>
> @@ -752,9 +751,6 @@ bool GnuLdDriver::parse(int argc, const
>      case LinkingContext::OutputFileType::YAML:
>        ctx->setOutputPath("-");
>        break;
> -    case LinkingContext::OutputFileType::Native:
> -      ctx->setOutputPath("a.native");
> -      break;
>      default:
>        ctx->setOutputPath("a.out");
>        break;
>
> Modified: lld/trunk/lib/Driver/GnuLdOptions.td
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdOptions.td?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Driver/GnuLdOptions.td (original)
> +++ lld/trunk/lib/Driver/GnuLdOptions.td Fri Apr 10 16:23:51 2015
> @@ -313,7 +313,7 @@ def stats : Flag<["--"], "stats">,
>  def grp_extns : OptionGroup<"opts">,
>       HelpText<"Extensions">;
>  def output_filetype: Separate<["--"], "output-filetype">,
> -      HelpText<"Specify what type of output file that lld creates,
> YAML/Native">,
> +      HelpText<"Specify yaml to create an output in YAML format">,
>        Group<grp_extns>;
>  def alias_output_filetype: Joined<["--"], "output-filetype=">,
>        Alias<output_filetype>;
>
> Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
> +++ lld/trunk/lib/Driver/WinLinkDriver.cpp Fri Apr 10 16:23:51 2015
> @@ -862,7 +862,6 @@ bool WinLinkDriver::linkPECOFF(int argc,
>    ctx.registry().addSupportCOFFObjects(ctx);
>    ctx.registry().addSupportCOFFImportLibraries(ctx);
>    ctx.registry().addSupportArchives(ctx.logInputFiles());
> -  ctx.registry().addSupportNativeObjects();
>    ctx.registry().addSupportYamlFiles();
>
>    std::vector<const char *> newargv = processLinkEnv(ctx, argc, argv);
>
> Modified: lld/trunk/lib/ReaderWriter/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/CMakeLists.txt?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/CMakeLists.txt (original)
> +++ lld/trunk/lib/ReaderWriter/CMakeLists.txt Fri Apr 10 16:23:51 2015
> @@ -1,6 +1,5 @@
>  add_subdirectory(ELF)
>  add_subdirectory(MachO)
> -add_subdirectory(Native)
>  add_subdirectory(PECOFF)
>  add_subdirectory(YAML)
>
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Fri Apr 10
> 16:23:51 2015
> @@ -75,9 +75,6 @@ bool ELFLinkingContext::validateImpl(raw
>    case LinkingContext::OutputFileType::YAML:
>      _writer = createWriterYAML(*this);
>      break;
> -  case LinkingContext::OutputFileType::Native:
> -    llvm_unreachable("Unimplemented");
> -    break;
>    default:
>      _writer = createWriterELF(*this);
>      break;
>
> Removed: lld/trunk/lib/ReaderWriter/Native/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/CMakeLists.txt?rev=234640&view=auto
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/Native/CMakeLists.txt (original)
> +++ lld/trunk/lib/ReaderWriter/Native/CMakeLists.txt (removed)
> @@ -1,7 +0,0 @@
> -add_llvm_library(lldNative
> -  ReaderNative.cpp
> -  WriterNative.cpp
> -  LINK_LIBS
> -    lldCore
> -    LLVMSupport
> -  )
>
> Removed: lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h?rev=234640&view=auto
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h (original)
> +++ lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h (removed)
> @@ -1,258 +0,0 @@
> -//===- lib/ReaderWriter/Native/NativeFileFormat.h
> -------------------------===//
> -//
> -//                             The LLVM Linker
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#ifndef LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
> -#define LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
> -
> -#include "llvm/Support/DataTypes.h"
> -#include <cstdint>
> -
> -namespace lld {
> -
> -//
> -// Overview:
> -//
> -// The number one design goal of this file format is enable the linker to
> -// read object files into in-memory Atom objects extremely quickly.
> -// The second design goal is to enable future modifications to the
> -// Atom attribute model.
> -//
> -// The llvm native object file format is not like traditional object file
> -// formats (e.g. ELF, COFF, mach-o).  There is no symbol table and no
> -// sections.  Instead the file is essentially an array of archived Atoms.
> -// It is *not* serialized Atoms which would require deserialization into
> -// in memory objects.  Instead it is an array of read-only info about each
> -// Atom.  The NativeReader bulk creates in-memory Atoms which just have
> -// an ivar which points to the read-only info for that Atom. No additional
> -// processing is done to construct the in-memory Atoms. All Atom attribute
> -// getter methods are virtual calls which dig up the info they need from
> the
> -// ivar data.
> -//
> -// To support the gradual evolution of Atom attributes, the Atom read-only
> -// data is versioned. The NativeReader chooses which in-memory Atom class
> -// to use based on the version. What this means is that if new attributes
> -// are added (or changed) in the Atom model, a new native atom class and
> -// read-only atom info struct needs to be defined.  Then, all the existing
> -// native reader atom classes need to be modified to do their best effort
> -// to map their old style read-only data to the new Atom model.  At some
> point
> -// some classes to support old versions may be dropped.
> -//
> -//
> -// Details:
> -//
> -// The native object file format consists of a header that specifies the
> -// endianness of the file and the architecture along with a list of
> "chunks"
> -// in the file.  A Chunk is simply a tagged range of the file.  There is
> -// one chunk for the array of atom infos.  There is another chunk for the
> -// string pool, and another for the content pool.
> -//
> -// It turns out there most atoms have very similar sets of attributes,
> only
> -// the name and content attribute vary. To exploit this fact to reduce
> the file
> -// size, the atom read-only info contains just the name and content info
> plus
> -// a reference to which attribute set it uses.  The attribute sets are
> stored
> -// in another chunk.
> -//
> -
> -
> -//
> -// An entry in the NativeFileHeader that describes one chunk of the file.
> -//
> -struct NativeChunk {
> -  uint32_t    signature;
> -  uint32_t    fileOffset;
> -  uint32_t    fileSize;
> -  uint32_t    elementCount;
> -};
> -
> -
> -//
> -// The header in a native object file
> -//
> -struct NativeFileHeader {
> -  uint8_t     magic[16];
> -  uint32_t    endian;
> -  uint32_t    architecture;
> -  uint32_t    fileSize;
> -  uint32_t    chunkCount;
> -  // NativeChunk chunks[]
> -};
> -
> -//
> -// Possible values for NativeChunk.signature field
> -//
> -enum NativeChunkSignatures {
> -  NCS_DefinedAtomsV1 = 1,
> -  NCS_AttributesArrayV1 = 2,
> -  NCS_AbsoluteAttributesV1 = 12,
> -  NCS_UndefinedAtomsV1 = 3,
> -  NCS_SharedLibraryAtomsV1 = 4,
> -  NCS_AbsoluteAtomsV1 = 5,
> -  NCS_Strings = 6,
> -  NCS_ReferencesArrayV1 = 7,
> -  NCS_ReferencesArrayV2 = 8,
> -  NCS_TargetsTable = 9,
> -  NCS_AddendsTable = 10,
> -  NCS_Content = 11,
> -};
> -
> -//
> -// The 16-bytes at the start of a native object file
> -//
> -#define NATIVE_FILE_HEADER_MAGIC "llvm nat obj v1 "
> -
> -//
> -// Possible values for the NativeFileHeader.endian field
> -//
> -enum {
> -  NFH_BigEndian     = 0x42696745,
> -  NFH_LittleEndian  = 0x4574696c
> -};
> -
> -
> -//
> -// Possible values for the NativeFileHeader.architecture field
> -//
> -enum {
> -  NFA_x86     = 1,
> -  NFA_x86_64  = 2,
> -  NFA_armv6   = 3,
> -  NFA_armv7   = 4,
> -};
> -
> -
> -//
> -// The NCS_DefinedAtomsV1 chunk contains an array of these structs
> -//
> -struct NativeDefinedAtomIvarsV1 {
> -  uint32_t  nameOffset;
> -  uint32_t  attributesOffset;
> -  uint32_t  referencesStartIndex;
> -  uint32_t  referencesCount;
> -  uint32_t  contentOffset;
> -  uint32_t  contentSize;
> -  uint64_t  sectionSize;
> -};
> -
> -
> -//
> -// The NCS_AttributesArrayV1 chunk contains an array of these structs
> -//
> -struct NativeAtomAttributesV1 {
> -  uint32_t  sectionNameOffset;
> -  uint16_t  align;
> -  uint16_t  alignModulus;
> -  uint8_t   scope;
> -  uint8_t   interposable;
> -  uint8_t   merge;
> -  uint8_t   contentType;
> -  uint8_t   sectionChoice;
> -  uint8_t   deadStrip;
> -  uint8_t   dynamicExport;
> -  uint8_t   permissions;
> -  uint8_t   alias;
> -  uint8_t   codeModel;
> -};
> -
> -
> -
> -//
> -// The NCS_UndefinedAtomsV1 chunk contains an array of these structs
> -//
> -struct NativeUndefinedAtomIvarsV1 {
> -  uint32_t  nameOffset;
> -  uint32_t  flags;
> -  uint32_t  fallbackNameOffset;
> -};
> -
> -
> -//
> -// The NCS_SharedLibraryAtomsV1 chunk contains an array of these structs
> -//
> -struct NativeSharedLibraryAtomIvarsV1 {
> -  uint64_t  size;
> -  uint32_t  nameOffset;
> -  uint32_t  loadNameOffset;
> -  uint32_t  type;
> -  uint32_t  flags;
> -};
> -
> -
> -
> -//
> -// The NCS_AbsoluteAtomsV1 chunk contains an array of these structs
> -//
> -struct NativeAbsoluteAtomIvarsV1 {
> -  uint32_t  nameOffset;
> -  uint32_t  attributesOffset;
> -  uint32_t  reserved;
> -  uint64_t  value;
> -};
> -
> -
> -
> -//
> -// The NCS_ReferencesArrayV1 chunk contains an array of these structs
> -//
> -struct NativeReferenceIvarsV1 {
> -  enum {
> -    noTarget = UINT16_MAX
> -  };
> -  uint32_t  offsetInAtom;
> -  uint16_t  kindValue;
> -  uint8_t   kindNamespace;
> -  uint8_t   kindArch;
> -  uint16_t  targetIndex;
> -  uint16_t  addendIndex;
> -};
> -
> -
> -//
> -// The NCS_ReferencesArrayV2 chunk contains an array of these structs
> -//
> -struct NativeReferenceIvarsV2 {
> -  enum : unsigned {
> -    noTarget = UINT32_MAX
> -  };
> -  uint64_t  offsetInAtom;
> -  int64_t   addend;
> -  uint16_t  kindValue;
> -  uint8_t   kindNamespace;
> -  uint8_t   kindArch;
> -  uint32_t  targetIndex;
> -  uint32_t  tag;
> -};
> -
> -
> -//
> -// The NCS_TargetsTable chunk contains an array of uint32_t entries.
> -// The C++ class Reference has a target() method that returns a
> -// pointer to another Atom.  We can't have pointers in object files,
> -// so instead  NativeReferenceIvarsV1 contains an index to the target.
> -// The index is into this NCS_TargetsTable of uint32_t entries.
> -// The values in this table are the index of the (target) atom in this
> file.
> -// For DefinedAtoms the value is from 0 to
> NCS_DefinedAtomsV1.elementCount.
> -// For UndefinedAtoms the value is from NCS_DefinedAtomsV1.elementCount to
> -// NCS_DefinedAtomsV1.elementCount+NCS_UndefinedAtomsV1.elementCount.
> -//
> -
> -
> -//
> -// The NCS_AddendsTable chunk contains an array of int64_t entries.
> -// If we allocated space for addends directly in NativeReferenceIvarsV1
> -// it would double the size of that struct.  But since addends are rare,
> -// we instead just keep a pool of addends and have NativeReferenceIvarsV1
> -// (if it needs an addend) just store the index (into the pool) of the
> -// addend it needs.
> -//
> -
> -
> -
> -} // namespace lld
> -
> -#endif // LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
>
> Removed: lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp?rev=234640&view=auto
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp (removed)
> @@ -1,881 +0,0 @@
> -//===- lib/ReaderWriter/Native/ReaderNative.cpp
> ---------------------------===//
> -//
> -//                             The LLVM Linker
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#include "NativeFileFormat.h"
> -#include "lld/Core/Atom.h"
> -#include "lld/Core/Error.h"
> -#include "lld/Core/File.h"
> -#include "lld/Core/Reader.h"
> -#include "lld/Core/Simple.h"
> -#include "llvm/ADT/ArrayRef.h"
> -#include "llvm/ADT/StringRef.h"
> -#include "llvm/Support/Debug.h"
> -#include "llvm/Support/ErrorHandling.h"
> -#include "llvm/Support/Format.h"
> -#include "llvm/Support/MemoryBuffer.h"
> -#include "llvm/Support/raw_ostream.h"
> -#include <memory>
> -#include <vector>
> -
> -namespace lld {
> -namespace native {
> -
> -// forward reference
> -class File;
> -
> -//
> -// An object of this class is instantied for each NativeDefinedAtomIvarsV1
> -// struct in the NCS_DefinedAtomsV1 chunk.
> -//
> -class NativeDefinedAtomV1 : public DefinedAtom {
> -public:
> -      NativeDefinedAtomV1(const File& f,
> -                          const NativeDefinedAtomIvarsV1* ivarData)
> -        : _file(&f), _ivarData(ivarData) { }
> -
> -  const lld::File& file() const override;
> -
> -  uint64_t ordinal() const override;
> -
> -  StringRef name() const override;
> -
> -  uint64_t size() const override { return _ivarData->contentSize; }
> -
> -  uint64_t sectionSize() const override { return _ivarData->sectionSize; }
> -
> -  DefinedAtom::Scope scope() const override {
> -    return (DefinedAtom::Scope)(attributes().scope);
> -  }
> -
> -  DefinedAtom::Interposable interposable() const override {
> -    return (DefinedAtom::Interposable)(attributes().interposable);
> -  }
> -
> -  DefinedAtom::Merge merge() const override {
> -    return (DefinedAtom::Merge)(attributes().merge);
> -  }
> -
> -  DefinedAtom::ContentType contentType() const override {
> -    const NativeAtomAttributesV1& attr = attributes();
> -    return (DefinedAtom::ContentType)(attr.contentType);
> -  }
> -
> -  DefinedAtom::Alignment alignment() const override {
> -    return DefinedAtom::Alignment(attributes().align,
> -                                  attributes().alignModulus);
> -  }
> -
> -  DefinedAtom::SectionChoice sectionChoice() const override {
> -    return (DefinedAtom::SectionChoice)(attributes().sectionChoice);
> -  }
> -
> -  StringRef customSectionName() const override;
> -
> -  DefinedAtom::DeadStripKind deadStrip() const override {
> -     return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
> -  }
> -
> -  DynamicExport dynamicExport() const override {
> -    return (DynamicExport)attributes().dynamicExport;
> -  }
> -
> -  DefinedAtom::CodeModel codeModel() const override {
> -    return DefinedAtom::CodeModel(attributes().codeModel);
> -  }
> -
> -  DefinedAtom::ContentPermissions permissions() const override {
> -     return (DefinedAtom::ContentPermissions)(attributes().permissions);
> -  }
> -
> -  ArrayRef<uint8_t> rawContent() const override;
> -
> -  reference_iterator begin() const override;
> -
> -  reference_iterator end() const override;
> -
> -  const Reference* derefIterator(const void*) const override;
> -
> -  void incrementIterator(const void*& it) const override;
> -
> -private:
> -  const NativeAtomAttributesV1& attributes() const;
> -
> -  const File                     *_file;
> -  const NativeDefinedAtomIvarsV1 *_ivarData;
> -};
> -
> -
> -
> -//
> -// An object of this class is instantied for each
> NativeUndefinedAtomIvarsV1
> -// struct in the NCS_UndefinedAtomsV1 chunk.
> -//
> -class NativeUndefinedAtomV1 : public UndefinedAtom {
> -public:
> -       NativeUndefinedAtomV1(const File& f,
> -                             const NativeUndefinedAtomIvarsV1* ivarData)
> -        : _file(&f), _ivarData(ivarData) { }
> -
> -  const lld::File& file() const override;
> -  StringRef name() const override;
> -
> -  CanBeNull canBeNull() const override {
> -    return (CanBeNull)(_ivarData->flags & 0x3);
> -  }
> -
> -  const UndefinedAtom *fallback() const override;
> -
> -private:
> -  const File                        *_file;
> -  const NativeUndefinedAtomIvarsV1  *_ivarData;
> -  mutable std::unique_ptr<const SimpleUndefinedAtom> _fallback;
> -};
> -
> -
> -//
> -// An object of this class is instantied for each
> NativeUndefinedAtomIvarsV1
> -// struct in the NCS_SharedLibraryAtomsV1 chunk.
> -//
> -class NativeSharedLibraryAtomV1 : public SharedLibraryAtom {
> -public:
> -       NativeSharedLibraryAtomV1(const File& f,
> -                             const NativeSharedLibraryAtomIvarsV1*
> ivarData)
> -        : _file(&f), _ivarData(ivarData) { }
> -
> -  const lld::File& file() const override;
> -  StringRef name() const override;
> -  StringRef loadName() const override;
> -
> -  bool canBeNullAtRuntime() const override {
> -    return (_ivarData->flags & 0x1);
> -  }
> -
> -  Type type() const override {
> -    return (Type)_ivarData->type;
> -  }
> -
> -  uint64_t size() const override {
> -    return _ivarData->size;
> -  }
> -
> -private:
> -  const File                           *_file;
> -  const NativeSharedLibraryAtomIvarsV1 *_ivarData;
> -};
> -
> -
> -//
> -// An object of this class is instantied for each
> NativeAbsoluteAtomIvarsV1
> -// struct in the NCS_AbsoluteAtomsV1 chunk.
> -//
> -class NativeAbsoluteAtomV1 : public AbsoluteAtom {
> -public:
> -       NativeAbsoluteAtomV1(const File& f,
> -                             const NativeAbsoluteAtomIvarsV1* ivarData)
> -        : _file(&f), _ivarData(ivarData) { }
> -
> -  const lld::File& file() const override;
> -  StringRef name() const override;
> -  Scope scope() const override {
> -    const NativeAtomAttributesV1& attr = absAttributes();
> -    return (Scope)(attr.scope);
> -  }
> -  uint64_t value() const override {
> -    return _ivarData->value;
> -  }
> -
> -private:
> -  const NativeAtomAttributesV1& absAttributes() const;
> -  const File                      *_file;
> -  const NativeAbsoluteAtomIvarsV1 *_ivarData;
> -};
> -
> -
> -//
> -// An object of this class is instantied for each NativeReferenceIvarsV1
> -// struct in the NCS_ReferencesArrayV1 chunk.
> -//
> -class NativeReferenceV1 : public Reference {
> -public:
> -  NativeReferenceV1(const File &f, const NativeReferenceIvarsV1 *ivarData)
> -      : Reference((KindNamespace)ivarData->kindNamespace,
> -                  (KindArch)ivarData->kindArch, ivarData->kindValue),
> -        _file(&f), _ivarData(ivarData) {}
> -
> -  uint64_t offsetInAtom() const override {
> -    return _ivarData->offsetInAtom;
> -  }
> -
> -  const Atom* target() const override;
> -  Addend addend() const override;
> -  void setTarget(const Atom* newAtom) override;
> -  void setAddend(Addend a) override;
> -
> -private:
> -  const File                    *_file;
> -  const NativeReferenceIvarsV1  *_ivarData;
> -};
> -
> -
> -//
> -// An object of this class is instantied for each NativeReferenceIvarsV1
> -// struct in the NCS_ReferencesArrayV1 chunk.
> -//
> -class NativeReferenceV2 : public Reference {
> -public:
> -  NativeReferenceV2(const File &f, const NativeReferenceIvarsV2 *ivarData)
> -      : Reference((KindNamespace)ivarData->kindNamespace,
> -                  (KindArch)ivarData->kindArch, ivarData->kindValue),
> -        _file(&f), _ivarData(ivarData) {}
> -
> -  uint64_t offsetInAtom() const override {
> -    return _ivarData->offsetInAtom;
> -  }
> -
> -  const Atom* target() const override;
> -  Addend addend() const override;
> -  void setTarget(const Atom* newAtom) override;
> -  void setAddend(Addend a) override;
> -  uint32_t tag() const override;
> -
> -private:
> -  const File                    *_file;
> -  const NativeReferenceIvarsV2  *_ivarData;
> -};
> -
> -
> -//
> -// lld::File object for native llvm object file
> -//
> -class File : public lld::File {
> -public:
> -  File(std::unique_ptr<MemoryBuffer> mb)
> -      : lld::File(mb->getBufferIdentifier(), kindObject),
> -        _mb(std::move(mb)), // Reader now takes ownership of buffer
> -        _header(nullptr), _targetsTable(nullptr), _targetsTableCount(0),
> -        _strings(nullptr), _stringsMaxOffset(0), _addends(nullptr),
> -        _addendsMaxIndex(0), _contentStart(nullptr), _contentEnd(nullptr)
> {
> -    _header =
> -        reinterpret_cast<const NativeFileHeader *>(_mb->getBufferStart());
> -  }
> -
> -  /// Parses a File object from a native object file.
> -  std::error_code doParse() override {
> -    const uint8_t *const base =
> -        reinterpret_cast<const uint8_t *>(_mb->getBufferStart());
> -    StringRef path(_mb->getBufferIdentifier());
> -    const NativeFileHeader *const header =
> -        reinterpret_cast<const NativeFileHeader *>(base);
> -    const NativeChunk *const chunks =
> -        reinterpret_cast<const NativeChunk *>(base +
> sizeof(NativeFileHeader));
> -    // make sure magic matches
> -    if (memcmp(header->magic, NATIVE_FILE_HEADER_MAGIC,
> -               sizeof(header->magic)) != 0)
> -      return make_error_code(NativeReaderError::unknown_file_format);
> -
> -    // make sure mapped file contains all needed data
> -    const size_t fileSize = _mb->getBufferSize();
> -    if (header->fileSize > fileSize)
> -      return make_error_code(NativeReaderError::file_too_short);
> -
> -    DEBUG_WITH_TYPE("ReaderNative",
> -                    llvm::dbgs() << " Native File Header:" << " fileSize="
> -                                 << header->fileSize << " chunkCount="
> -                                 << header->chunkCount << "\n");
> -
> -    // process each chunk
> -    for (uint32_t i = 0; i < header->chunkCount; ++i) {
> -      std::error_code ec;
> -      const NativeChunk* chunk = &chunks[i];
> -      // sanity check chunk is within file
> -      if ( chunk->fileOffset > fileSize )
> -        return make_error_code(NativeReaderError::file_malformed);
> -      if ( (chunk->fileOffset + chunk->fileSize) > fileSize)
> -        return make_error_code(NativeReaderError::file_malformed);
> -      // process chunk, based on signature
> -      switch ( chunk->signature ) {
> -        case NCS_DefinedAtomsV1:
> -          ec = processDefinedAtomsV1(base, chunk);
> -          break;
> -        case NCS_AttributesArrayV1:
> -          ec = processAttributesV1(base, chunk);
> -          break;
> -        case NCS_UndefinedAtomsV1:
> -          ec = processUndefinedAtomsV1(base, chunk);
> -          break;
> -        case NCS_SharedLibraryAtomsV1:
> -          ec = processSharedLibraryAtomsV1(base, chunk);
> -          break;
> -        case NCS_AbsoluteAtomsV1:
> -          ec = processAbsoluteAtomsV1(base, chunk);
> -          break;
> -        case NCS_AbsoluteAttributesV1:
> -          ec = processAbsoluteAttributesV1(base, chunk);
> -          break;
> -        case NCS_ReferencesArrayV1:
> -          ec = processReferencesV1(base, chunk);
> -          break;
> -        case NCS_ReferencesArrayV2:
> -          ec = processReferencesV2(base, chunk);
> -          break;
> -        case NCS_TargetsTable:
> -          ec = processTargetsTable(base, chunk);
> -          break;
> -        case NCS_AddendsTable:
> -          ec = processAddendsTable(base, chunk);
> -          break;
> -        case NCS_Content:
> -          ec = processContent(base, chunk);
> -          break;
> -        case NCS_Strings:
> -          ec = processStrings(base, chunk);
> -          break;
> -        default:
> -          return make_error_code(NativeReaderError::unknown_chunk_type);
> -      }
> -      if ( ec ) {
> -        return ec;
> -      }
> -    }
> -    // TO DO: validate enough chunks were used
> -
> -    DEBUG_WITH_TYPE("ReaderNative", {
> -      llvm::dbgs() << " ReaderNative DefinedAtoms:\n";
> -      for (const DefinedAtom *a : defined()) {
> -        llvm::dbgs() << llvm::format("    0x%09lX", a)
> -                     << ", name=" << a->name()
> -                     << ", size=" << a->size() << "\n";
> -        for (const Reference *r : *a) {
> -          llvm::dbgs() << "        offset="
> -                       << llvm::format("0x%03X", r->offsetInAtom())
> -                       << ", kind=" << r->kindValue()
> -                       << ", target=" << r->target() << "\n";
> -        }
> -      }
> -    });
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  virtual ~File() {
> -    // _mb is automatically deleted because of std::unique_ptr<>
> -
> -    // All other ivar pointers are pointers into the MemoryBuffer, except
> -    // 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 _referencesV1.arrayStart;
> -    delete _referencesV2.arrayStart;
> -    delete [] _targetsTable;
> -  }
> -
> -  const AtomVector<DefinedAtom> &defined() const override {
> -    return _definedAtoms;
> -  }
> -  const AtomVector<UndefinedAtom> &undefined() const override {
> -      return _undefinedAtoms;
> -  }
> -  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {
> -      return _sharedLibraryAtoms;
> -  }
> -  const AtomVector<AbsoluteAtom> &absolute() const override {
> -    return _absoluteAtoms;
> -  }
> -
> -private:
> -  friend NativeDefinedAtomV1;
> -  friend NativeUndefinedAtomV1;
> -  friend NativeSharedLibraryAtomV1;
> -  friend NativeAbsoluteAtomV1;
> -  friend NativeReferenceV1;
> -  friend NativeReferenceV2;
> -  template <typename T> class AtomArray;
> -
> -  // instantiate array of BASeT from IvarsT data in file
> -  template <typename BaseT, typename AtomT, typename IvarsT>
> -  std::error_code processAtoms(AtomVector<BaseT> &result, const uint8_t
> *base,
> -                               const NativeChunk *chunk) {
> -    std::vector<const BaseT *> vec(chunk->elementCount);
> -    const size_t ivarElementSize = chunk->fileSize / chunk->elementCount;
> -    if (ivarElementSize != sizeof(IvarsT))
> -      return make_error_code(NativeReaderError::file_malformed);
> -    auto *ivar = reinterpret_cast<const IvarsT *>(base +
> chunk->fileOffset);
> -    for (size_t i = 0; i < chunk->elementCount; ++i)
> -      vec[i] = new (_alloc) AtomT(*this, ivar++);
> -    result = std::move(vec);
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // instantiate array of DefinedAtoms from v1 ivar data in file
> -  std::error_code processDefinedAtomsV1(const uint8_t *base,
> -                                        const NativeChunk *chunk) {
> -    return processAtoms<DefinedAtom, NativeDefinedAtomV1,
> -                        NativeDefinedAtomIvarsV1>(this->_definedAtoms,
> base,
> -                                                  chunk);
> -  }
> -
> -  // set up pointers to attributes array
> -  std::error_code processAttributesV1(const uint8_t *base,
> -                                      const NativeChunk *chunk) {
> -    this->_attributes = base + chunk->fileOffset;
> -    this->_attributesMaxOffset = chunk->fileSize;
> -    DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
> -                    << " chunk AttributesV1:        "
> -                    << " count=" << chunk->elementCount
> -                    << " chunkSize=" << chunk->fileSize
> -                    << "\n");
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // set up pointers to attributes array
> -  std::error_code processAbsoluteAttributesV1(const uint8_t *base,
> -                                              const NativeChunk *chunk) {
> -    this->_absAttributes = base + chunk->fileOffset;
> -    this->_absAbsoluteMaxOffset = chunk->fileSize;
> -    DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
> -                    << " chunk AbsoluteAttributesV1:        "
> -                    << " count=" << chunk->elementCount
> -                    << " chunkSize=" << chunk->fileSize
> -                    << "\n");
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // instantiate array of UndefinedAtoms from v1 ivar data in file
> -  std::error_code processUndefinedAtomsV1(const uint8_t *base,
> -                                          const NativeChunk *chunk) {
> -    return processAtoms<UndefinedAtom, NativeUndefinedAtomV1,
> -
> NativeUndefinedAtomIvarsV1>(this->_undefinedAtoms, base,
> -                                                    chunk);
> -  }
> -
> -
> -  // instantiate array of ShareLibraryAtoms from v1 ivar data in file
> -  std::error_code processSharedLibraryAtomsV1(const uint8_t *base,
> -                                              const NativeChunk *chunk) {
> -    return processAtoms<SharedLibraryAtom, NativeSharedLibraryAtomV1,
> -                        NativeSharedLibraryAtomIvarsV1>(
> -        this->_sharedLibraryAtoms, base, chunk);
> -  }
> -
> -
> -   // instantiate array of AbsoluteAtoms from v1 ivar data in file
> -  std::error_code processAbsoluteAtomsV1(const uint8_t *base,
> -                                         const NativeChunk *chunk) {
> -    return processAtoms<AbsoluteAtom, NativeAbsoluteAtomV1,
> -                        NativeAbsoluteAtomIvarsV1>(this->_absoluteAtoms,
> base,
> -                                                   chunk);
> -  }
> -
> -  template <class T, class U>
> -  std::error_code
> -  processReferences(const uint8_t *base, const NativeChunk *chunk,
> -                    uint8_t *&refsStart, uint8_t *&refsEnd) const {
> -    if (chunk->elementCount == 0)
> -      return make_error_code(NativeReaderError::success);
> -    size_t refsArraySize = chunk->elementCount * sizeof(T);
> -    refsStart = reinterpret_cast<uint8_t *>(
> -        operator new(refsArraySize, std::nothrow));
> -    if (refsStart == nullptr)
> -      return make_error_code(NativeReaderError::memory_error);
> -    const size_t ivarElementSize = chunk->fileSize / chunk->elementCount;
> -    if (ivarElementSize != sizeof(U))
> -      return make_error_code(NativeReaderError::file_malformed);
> -    refsEnd = refsStart + refsArraySize;
> -    const U* ivarData = reinterpret_cast<const U *>(base +
> chunk->fileOffset);
> -    for (uint8_t *s = refsStart; s != refsEnd; s += sizeof(T),
> ++ivarData) {
> -      T *atomAllocSpace = reinterpret_cast<T *>(s);
> -      new (atomAllocSpace) T(*this, ivarData);
> -    }
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // instantiate array of References from v1 ivar data in file
> -  std::error_code processReferencesV1(const uint8_t *base,
> -                                      const NativeChunk *chunk) {
> -    uint8_t *refsStart, *refsEnd;
> -    if (std::error_code ec =
> -            processReferences<NativeReferenceV1, NativeReferenceIvarsV1>(
> -                base, chunk, refsStart, refsEnd))
> -      return ec;
> -    this->_referencesV1.arrayStart = refsStart;
> -    this->_referencesV1.arrayEnd = refsEnd;
> -    this->_referencesV1.elementSize = sizeof(NativeReferenceV1);
> -    this->_referencesV1.elementCount = chunk->elementCount;
> -    DEBUG_WITH_TYPE("ReaderNative", {
> -      llvm::dbgs() << " chunk ReferencesV1:        "
> -                   << " count=" << chunk->elementCount
> -                   << " chunkSize=" << chunk->fileSize << "\n";
> -    });
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // instantiate array of References from v2 ivar data in file
> -  std::error_code processReferencesV2(const uint8_t *base,
> -                                      const NativeChunk *chunk) {
> -    uint8_t *refsStart, *refsEnd;
> -    if (std::error_code ec =
> -            processReferences<NativeReferenceV2, NativeReferenceIvarsV2>(
> -                base, chunk, refsStart, refsEnd))
> -      return ec;
> -    this->_referencesV2.arrayStart = refsStart;
> -    this->_referencesV2.arrayEnd = refsEnd;
> -    this->_referencesV2.elementSize = sizeof(NativeReferenceV2);
> -    this->_referencesV2.elementCount = chunk->elementCount;
> -    DEBUG_WITH_TYPE("ReaderNative", {
> -      llvm::dbgs() << " chunk ReferencesV2:        "
> -                   << " count=" << chunk->elementCount
> -                   << " chunkSize=" << chunk->fileSize << "\n";
> -    });
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // set up pointers to target table
> -  std::error_code processTargetsTable(const uint8_t *base,
> -                                      const NativeChunk *chunk) {
> -    const uint32_t* targetIndexes = reinterpret_cast<const uint32_t*>
> -                                                  (base +
> chunk->fileOffset);
> -    this->_targetsTableCount = chunk->elementCount;
> -    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.size()) {
> -        this->_targetsTable[i] = _definedAtoms[index];
> -        continue;
> -      }
> -      const uint32_t undefIndex = index - _definedAtoms.size();
> -      if (undefIndex < _undefinedAtoms.size()) {
> -        this->_targetsTable[i] = _undefinedAtoms[index];
> -        continue;
> -      }
> -      const uint32_t slIndex = undefIndex - _undefinedAtoms.size();
> -      if (slIndex < _sharedLibraryAtoms.size()) {
> -        this->_targetsTable[i] = _sharedLibraryAtoms[slIndex];
> -        continue;
> -      }
> -      const uint32_t abIndex = slIndex - _sharedLibraryAtoms.size();
> -      if (abIndex < _absoluteAtoms.size()) {
> -        this->_targetsTable[i] = _absoluteAtoms[abIndex];
> -        continue;
> -      }
> -     return make_error_code(NativeReaderError::file_malformed);
> -    }
> -    DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
> -                    << " chunk Targets Table:       "
> -                    << " count=" << chunk->elementCount
> -                    << " chunkSize=" << chunk->fileSize
> -                    << "\n");
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -
> -  // set up pointers to addend pool in file
> -  std::error_code processAddendsTable(const uint8_t *base,
> -                                      const NativeChunk *chunk) {
> -    this->_addends = reinterpret_cast<const Reference::Addend*>
> -                                                  (base +
> chunk->fileOffset);
> -    this->_addendsMaxIndex = chunk->elementCount;
> -    DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
> -                    << " chunk Addends:             "
> -                    << " count=" << chunk->elementCount
> -                    << " chunkSize=" << chunk->fileSize
> -                    << "\n");
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // set up pointers to string pool in file
> -  std::error_code processStrings(const uint8_t *base,
> -                                 const NativeChunk *chunk) {
> -    this->_strings = reinterpret_cast<const char*>(base +
> chunk->fileOffset);
> -    this->_stringsMaxOffset = chunk->fileSize;
> -    DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
> -                    << " chunk Strings:             "
> -                    << " chunkSize=" << chunk->fileSize
> -                    << "\n");
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  // set up pointers to content area in file
> -  std::error_code processContent(const uint8_t *base,
> -                                 const NativeChunk *chunk) {
> -    this->_contentStart = base + chunk->fileOffset;
> -    this->_contentEnd = base + chunk->fileOffset + chunk->fileSize;
> -    DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
> -                    << " chunk content:             "
> -                    << " chunkSize=" << chunk->fileSize
> -                    << "\n");
> -    return make_error_code(NativeReaderError::success);
> -  }
> -
> -  StringRef string(uint32_t offset) const {
> -    assert(offset < _stringsMaxOffset);
> -    return StringRef(&_strings[offset]);
> -  }
> -
> -  Reference::Addend addend(uint32_t index) const {
> -    if ( index == 0 )
> -      return 0; // addend index zero is used to mean "no addend"
> -    assert(index <= _addendsMaxIndex);
> -    return _addends[index-1]; // one-based indexing
> -  }
> -
> -  const NativeAtomAttributesV1& attribute(uint32_t off) const {
> -    assert(off < _attributesMaxOffset);
> -    return *reinterpret_cast<const NativeAtomAttributesV1*>(_attributes +
> off);
> -  }
> -
> -  const NativeAtomAttributesV1& absAttribute(uint32_t off) const {
> -    assert(off < _absAbsoluteMaxOffset);
> -    return *reinterpret_cast<const
> NativeAtomAttributesV1*>(_absAttributes + off);
> -  }
> -
> -  const uint8_t* content(uint32_t offset, uint32_t size) const {
> -    const uint8_t* result = _contentStart + offset;
> -    assert((result+size) <= _contentEnd);
> -    return result;
> -  }
> -
> -  const Reference* referenceByIndex(uintptr_t index) const {
> -    if (index < _referencesV1.elementCount) {
> -      return reinterpret_cast<const NativeReferenceV1*>(
> -          _referencesV1.arrayStart + index * _referencesV1.elementSize);
> -    }
> -    assert(index < _referencesV2.elementCount);
> -    return reinterpret_cast<const NativeReferenceV2*>(
> -        _referencesV2.arrayStart + index * _referencesV2.elementSize);
> -  }
> -
> -  const Atom* targetV1(uint16_t index) const {
> -    if ( index == NativeReferenceIvarsV1::noTarget )
> -      return nullptr;
> -    assert(index < _targetsTableCount);
> -    return _targetsTable[index];
> -  }
> -
> -  void setTargetV1(uint16_t index, const Atom* newAtom) const {
> -    assert(index != NativeReferenceIvarsV1::noTarget);
> -    assert(index > _targetsTableCount);
> -    _targetsTable[index] = newAtom;
> -  }
> -
> -  const Atom* targetV2(uint32_t index) const {
> -    if (index == NativeReferenceIvarsV2::noTarget)
> -      return nullptr;
> -    assert(index < _targetsTableCount);
> -    return _targetsTable[index];
> -  }
> -
> -  void setTargetV2(uint32_t index, const Atom* newAtom) const {
> -    assert(index != NativeReferenceIvarsV2::noTarget);
> -    assert(index > _targetsTableCount);
> -    _targetsTable[index] = newAtom;
> -  }
> -
> -  struct IvarArray {
> -                      IvarArray() :
> -                        arrayStart(nullptr),
> -                        arrayEnd(nullptr),
> -                        elementSize(0),
> -                        elementCount(0) { }
> -
> -    const uint8_t*     arrayStart;
> -    const uint8_t*     arrayEnd;
> -    uint32_t           elementSize;
> -    uint32_t           elementCount;
> -  };
> -
> -  std::unique_ptr<MemoryBuffer>   _mb;
> -  const NativeFileHeader*         _header;
> -  AtomVector<DefinedAtom> _definedAtoms;
> -  AtomVector<UndefinedAtom> _undefinedAtoms;
> -  AtomVector<SharedLibraryAtom> _sharedLibraryAtoms;
> -  AtomVector<AbsoluteAtom> _absoluteAtoms;
> -  const uint8_t*                  _absAttributes;
> -  uint32_t                        _absAbsoluteMaxOffset;
> -  const uint8_t*                  _attributes;
> -  uint32_t                        _attributesMaxOffset;
> -  IvarArray                       _referencesV1;
> -  IvarArray                       _referencesV2;
> -  const Atom**                    _targetsTable;
> -  uint32_t                        _targetsTableCount;
> -  const char*                     _strings;
> -  uint32_t                        _stringsMaxOffset;
> -  const Reference::Addend*        _addends;
> -  uint32_t                        _addendsMaxIndex;
> -  const uint8_t                  *_contentStart;
> -  const uint8_t                  *_contentEnd;
> -  llvm::BumpPtrAllocator _alloc;
> -};
> -
> -inline const lld::File &NativeDefinedAtomV1::file() const {
> -  return *_file;
> -}
> -
> -inline uint64_t NativeDefinedAtomV1::ordinal() const {
> -  const uint8_t* p = reinterpret_cast<const uint8_t*>(_ivarData);
> -  auto *start = reinterpret_cast<const NativeDefinedAtomV1 *>(
> -      _file->_definedAtoms[0]);
> -  const uint8_t *startp = reinterpret_cast<const uint8_t
> *>(start->_ivarData);
> -  return p - startp;
> -}
> -
> -inline StringRef NativeDefinedAtomV1::name() const {
> -  return _file->string(_ivarData->nameOffset);
> -}
> -
> -inline const NativeAtomAttributesV1& NativeDefinedAtomV1::attributes()
> const {
> -  return _file->attribute(_ivarData->attributesOffset);
> -}
> -
> -inline ArrayRef<uint8_t> NativeDefinedAtomV1::rawContent() const {
> -  if (!occupiesDiskSpace())
> -    return ArrayRef<uint8_t>();
> -  const uint8_t* p = _file->content(_ivarData->contentOffset,
> -                                    _ivarData->contentSize);
> -  return ArrayRef<uint8_t>(p, _ivarData->contentSize);
> -}
> -
> -inline StringRef NativeDefinedAtomV1::customSectionName() const {
> -  uint32_t offset = attributes().sectionNameOffset;
> -  return _file->string(offset);
> -}
> -
> -DefinedAtom::reference_iterator NativeDefinedAtomV1::begin() const {
> -  uintptr_t index = _ivarData->referencesStartIndex;
> -  const void* it = reinterpret_cast<const void*>(index);
> -  return reference_iterator(*this, it);
> -}
> -
> -DefinedAtom::reference_iterator NativeDefinedAtomV1::end() 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 lld::File& NativeUndefinedAtomV1::file() const {
> -  return *_file;
> -}
> -
> -inline StringRef NativeUndefinedAtomV1::name() const {
> -  return _file->string(_ivarData->nameOffset);
> -}
> -
> -inline const UndefinedAtom *NativeUndefinedAtomV1::fallback() const {
> -  if (!_ivarData->fallbackNameOffset)
> -    return nullptr;
> -  if (!_fallback)
> -    _fallback.reset(new SimpleUndefinedAtom(
> -        *_file, _file->string(_ivarData->fallbackNameOffset)));
> -  return _fallback.get();
> -}
> -
> -inline const lld::File& NativeSharedLibraryAtomV1::file() const {
> -  return *_file;
> -}
> -
> -inline StringRef NativeSharedLibraryAtomV1::name() const {
> -  return _file->string(_ivarData->nameOffset);
> -}
> -
> -inline StringRef NativeSharedLibraryAtomV1::loadName() const {
> -  return _file->string(_ivarData->loadNameOffset);
> -}
> -
> -
> -
> -inline const lld::File& NativeAbsoluteAtomV1::file() const {
> -  return *_file;
> -}
> -
> -inline StringRef NativeAbsoluteAtomV1::name() const {
> -  return _file->string(_ivarData->nameOffset);
> -}
> -
> -inline const NativeAtomAttributesV1&
> NativeAbsoluteAtomV1::absAttributes() const {
> -  return _file->absAttribute(_ivarData->attributesOffset);
> -}
> -
> -inline const Atom* NativeReferenceV1::target() const {
> -  return _file->targetV1(_ivarData->targetIndex);
> -}
> -
> -inline Reference::Addend NativeReferenceV1::addend() const {
> -  return _file->addend(_ivarData->addendIndex);
> -}
> -
> -inline void NativeReferenceV1::setTarget(const Atom* newAtom) {
> -  return _file->setTargetV1(_ivarData->targetIndex, newAtom);
> -}
> -
> -inline void NativeReferenceV1::setAddend(Addend a) {
> -  // Do nothing if addend value is not being changed.
> -  if (addend() == a)
> -    return;
> -  llvm_unreachable("setAddend() not supported");
> -}
> -
> -inline const Atom* NativeReferenceV2::target() const {
> -  return _file->targetV2(_ivarData->targetIndex);
> -}
> -
> -inline Reference::Addend NativeReferenceV2::addend() const {
> -  return _ivarData->addend;
> -}
> -
> -inline void NativeReferenceV2::setTarget(const Atom* newAtom) {
> -  return _file->setTargetV2(_ivarData->targetIndex, newAtom);
> -}
> -
> -inline void NativeReferenceV2::setAddend(Addend a) {
> -  // Do nothing if addend value is not being changed.
> -  if (addend() == a)
> -    return;
> -  llvm_unreachable("setAddend() not supported");
> -}
> -
> -uint32_t NativeReferenceV2::tag() const { return _ivarData->tag; }
> -
> -} // end namespace native
> -
> -namespace {
> -
> -class NativeReader : public Reader {
> -public:
> -  bool canParse(file_magic magic, const MemoryBuffer &mb) const override {
> -    const NativeFileHeader *const header =
> -        reinterpret_cast<const NativeFileHeader *>(mb.getBufferStart());
> -    return (memcmp(header->magic, NATIVE_FILE_HEADER_MAGIC,
> -                   sizeof(header->magic)) == 0);
> -  }
> -
> -  virtual std::error_code
> -  loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &,
> -           std::vector<std::unique_ptr<File>> &result) const override {
> -    auto *file = new lld::native::File(std::move(mb));
> -    result.push_back(std::unique_ptr<File>(file));
> -    return std::error_code();
> -  }
> -};
> -
> -}
> -
> -void Registry::addSupportNativeObjects() {
> -  add(std::unique_ptr<Reader>(new NativeReader()));
> -}
> -
> -} // end namespace lld
>
> Removed: lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp?rev=234640&view=auto
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp (removed)
> @@ -1,566 +0,0 @@
> -//===- lib/ReaderWriter/Native/WriterNative.cpp
> ---------------------------===//
> -//
> -//                             The LLVM Linker
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#include "NativeFileFormat.h"
> -#include "lld/Core/File.h"
> -#include "lld/Core/LinkingContext.h"
> -#include "lld/Core/Writer.h"
> -#include "llvm/ADT/ArrayRef.h"
> -#include "llvm/ADT/DenseMap.h"
> -#include "llvm/ADT/StringRef.h"
> -#include "llvm/Support/raw_ostream.h"
> -#include <cstdint>
> -#include <set>
> -#include <system_error>
> -#include <vector>
> -
> -namespace lld {
> -namespace native {
> -
> -///
> -/// Class for writing native object files.
> -///
> -class Writer : public lld::Writer {
> -public:
> -  std::error_code writeFile(const lld::File &file, StringRef outPath)
> override {
> -    // reserve first byte for unnamed atoms
> -    _stringPool.push_back('\0');
> -    // visit all atoms
> -    for ( const DefinedAtom *defAtom : file.defined() ) {
> -      this->addIVarsForDefinedAtom(*defAtom);
> -      // We are trying to process all atoms, but the defined() iterator
> does not
> -      // return group children. So, when a group parent is found, we need
> to
> -      // handle each child atom.
> -      if (defAtom->isGroupParent()) {
> -        for (const Reference *r : *defAtom) {
> -          if (r->kindNamespace() != lld::Reference::KindNamespace::all)
> -            continue;
> -          if (r->kindValue() == lld::Reference::kindGroupChild) {
> -            const DefinedAtom *target =
> dyn_cast<DefinedAtom>(r->target());
> -            assert(target && "Internal Error: kindGroupChild references
> need "
> -                             "to be associated with Defined Atoms only");
> -            this->addIVarsForDefinedAtom(*target);
> -          }
> -        }
> -      }
> -    }
> -    for ( const UndefinedAtom *undefAtom : file.undefined() ) {
> -      this->addIVarsForUndefinedAtom(*undefAtom);
> -    }
> -    for ( const SharedLibraryAtom *shlibAtom : file.sharedLibrary() ) {
> -      this->addIVarsForSharedLibraryAtom(*shlibAtom);
> -    }
> -    for ( const AbsoluteAtom *absAtom : file.absolute() ) {
> -      this->addIVarsForAbsoluteAtom(*absAtom);
> -    }
> -
> -    maybeConvertReferencesToV1();
> -
> -    // construct file header based on atom information accumulated
> -    this->makeHeader();
> -
> -    std::error_code ec;
> -    llvm::raw_fd_ostream out(outPath, ec, llvm::sys::fs::F_None);
> -    if (ec)
> -      return ec;
> -
> -    this->write(out);
> -
> -    return std::error_code();
> -  }
> -
> -  virtual ~Writer() {
> -  }
> -
> -private:
> -
> -  // write the lld::File in native format to the specified stream
> -  void write(raw_ostream &out) {
> -    assert(out.tell() == 0);
> -    out.write((char*)_headerBuffer, _headerBufferSize);
> -
> -    writeChunk(out, _definedAtomIvars, NCS_DefinedAtomsV1);
> -    writeChunk(out, _attributes, NCS_AttributesArrayV1);
> -    writeChunk(out, _undefinedAtomIvars, NCS_UndefinedAtomsV1);
> -    writeChunk(out, _sharedLibraryAtomIvars, NCS_SharedLibraryAtomsV1);
> -    writeChunk(out, _absoluteAtomIvars, NCS_AbsoluteAtomsV1);
> -    writeChunk(out, _absAttributes, NCS_AbsoluteAttributesV1);
> -    writeChunk(out, _stringPool, NCS_Strings);
> -    writeChunk(out, _referencesV1, NCS_ReferencesArrayV1);
> -    writeChunk(out, _referencesV2, NCS_ReferencesArrayV2);
> -
> -    if (!_targetsTableIndex.empty()) {
> -      assert(out.tell() == findChunk(NCS_TargetsTable).fileOffset);
> -      writeTargetTable(out);
> -    }
> -
> -    if (!_addendsTableIndex.empty()) {
> -      assert(out.tell() == findChunk(NCS_AddendsTable).fileOffset);
> -      writeAddendTable(out);
> -    }
> -
> -    writeChunk(out, _contentPool, NCS_Content);
> -  }
> -
> -  template<class T>
> -  void writeChunk(raw_ostream &out, std::vector<T> &vector, uint32_t
> signature) {
> -    if (vector.empty())
> -      return;
> -    assert(out.tell() == findChunk(signature).fileOffset);
> -    out.write((char*)&vector[0], vector.size() * sizeof(T));
> -  }
> -
> -  void addIVarsForDefinedAtom(const DefinedAtom& atom) {
> -    _definedAtomIndex[&atom] = _definedAtomIvars.size();
> -    NativeDefinedAtomIvarsV1 ivar;
> -    unsigned refsCount;
> -    ivar.nameOffset = getNameOffset(atom);
> -    ivar.attributesOffset = getAttributeOffset(atom);
> -    ivar.referencesStartIndex = getReferencesIndex(atom, refsCount);
> -    ivar.referencesCount = refsCount;
> -    ivar.contentOffset = getContentOffset(atom);
> -    ivar.contentSize = atom.size();
> -    ivar.sectionSize = atom.sectionSize();
> -    _definedAtomIvars.push_back(ivar);
> -  }
> -
> -  void addIVarsForUndefinedAtom(const UndefinedAtom& atom) {
> -    _undefinedAtomIndex[&atom] = _undefinedAtomIvars.size();
> -    NativeUndefinedAtomIvarsV1 ivar;
> -    ivar.nameOffset = getNameOffset(atom);
> -    ivar.flags = (atom.canBeNull() & 0x03);
> -    ivar.fallbackNameOffset = 0;
> -    if (atom.fallback())
> -      ivar.fallbackNameOffset = getNameOffset(*atom.fallback());
> -    _undefinedAtomIvars.push_back(ivar);
> -  }
> -
> -  void addIVarsForSharedLibraryAtom(const SharedLibraryAtom& atom) {
> -    _sharedLibraryAtomIndex[&atom] = _sharedLibraryAtomIvars.size();
> -    NativeSharedLibraryAtomIvarsV1 ivar;
> -    ivar.size = atom.size();
> -    ivar.nameOffset = getNameOffset(atom);
> -    ivar.loadNameOffset = getSharedLibraryNameOffset(atom.loadName());
> -    ivar.type = (uint32_t)atom.type();
> -    ivar.flags = atom.canBeNullAtRuntime();
> -    _sharedLibraryAtomIvars.push_back(ivar);
> -  }
> -
> -  void addIVarsForAbsoluteAtom(const AbsoluteAtom& atom) {
> -    _absoluteAtomIndex[&atom] = _absoluteAtomIvars.size();
> -    NativeAbsoluteAtomIvarsV1 ivar;
> -    ivar.nameOffset = getNameOffset(atom);
> -    ivar.attributesOffset = getAttributeOffset(atom);
> -    ivar.reserved = 0;
> -    ivar.value = atom.value();
> -    _absoluteAtomIvars.push_back(ivar);
> -  }
> -
> -  void convertReferencesToV1() {
> -    for (const NativeReferenceIvarsV2 &v2 : _referencesV2) {
> -      NativeReferenceIvarsV1 v1;
> -      v1.offsetInAtom = v2.offsetInAtom;
> -      v1.kindNamespace = v2.kindNamespace;
> -      v1.kindArch = v2.kindArch;
> -      v1.kindValue = v2.kindValue;
> -      v1.targetIndex = (v2.targetIndex ==
> NativeReferenceIvarsV2::noTarget) ?
> -          (uint16_t)NativeReferenceIvarsV1::noTarget : v2.targetIndex;
> -      v1.addendIndex = this->getAddendIndex(v2.addend);
> -      _referencesV1.push_back(v1);
> -    }
> -    _referencesV2.clear();
> -  }
> -
> -  bool canConvertReferenceToV1(const NativeReferenceIvarsV2 &ref) {
> -    bool validOffset = (ref.offsetInAtom ==
> NativeReferenceIvarsV2::noTarget) ||
> -        ref.offsetInAtom < NativeReferenceIvarsV1::noTarget;
> -    return validOffset && ref.targetIndex < UINT16_MAX;
> -  }
> -
> -  // Convert vector of NativeReferenceIvarsV2 to NativeReferenceIvarsV1 if
> -  // possible.
> -  void maybeConvertReferencesToV1() {
> -    std::set<int64_t> addends;
> -    for (const NativeReferenceIvarsV2 &ref : _referencesV2) {
> -      if (!canConvertReferenceToV1(ref))
> -        return;
> -      addends.insert(ref.addend);
> -      if (addends.size() >= UINT16_MAX)
> -        return;
> -    }
> -    convertReferencesToV1();
> -  }
> -
> -  // fill out native file header and chunk directory
> -  void makeHeader() {
> -    const bool hasDefines = !_definedAtomIvars.empty();
> -    const bool hasUndefines = !_undefinedAtomIvars.empty();
> -    const bool hasSharedLibraries = !_sharedLibraryAtomIvars.empty();
> -    const bool hasAbsolutes = !_absoluteAtomIvars.empty();
> -    const bool hasReferencesV1 = !_referencesV1.empty();
> -    const bool hasReferencesV2 = !_referencesV2.empty();
> -    const bool hasTargetsTable = !_targetsTableIndex.empty();
> -    const bool hasAddendTable = !_addendsTableIndex.empty();
> -    const bool hasContent = !_contentPool.empty();
> -
> -    int chunkCount = 1; // always have string pool chunk
> -    if ( hasDefines ) chunkCount += 2;
> -    if ( hasUndefines ) ++chunkCount;
> -    if ( hasSharedLibraries ) ++chunkCount;
> -    if ( hasAbsolutes ) chunkCount += 2;
> -    if ( hasReferencesV1 ) ++chunkCount;
> -    if ( hasReferencesV2 ) ++chunkCount;
> -    if ( hasTargetsTable ) ++chunkCount;
> -    if ( hasAddendTable ) ++chunkCount;
> -    if ( hasContent ) ++chunkCount;
> -
> -    _headerBufferSize = sizeof(NativeFileHeader)
> -                         + chunkCount*sizeof(NativeChunk);
> -    _headerBuffer = reinterpret_cast<NativeFileHeader*>
> -                               (operator new(_headerBufferSize,
> std::nothrow));
> -    NativeChunk *chunks =
> -
> reinterpret_cast<NativeChunk*>(reinterpret_cast<char*>(_headerBuffer)
> -                                     + sizeof(NativeFileHeader));
> -    memcpy(_headerBuffer->magic, NATIVE_FILE_HEADER_MAGIC,
> -           sizeof(_headerBuffer->magic));
> -    _headerBuffer->endian = NFH_LittleEndian;
> -    _headerBuffer->architecture = 0;
> -    _headerBuffer->fileSize = 0;
> -    _headerBuffer->chunkCount = chunkCount;
> -
> -    // create chunk for defined atom ivar array
> -    int nextIndex = 0;
> -    uint32_t nextFileOffset = _headerBufferSize;
> -    if (hasDefines) {
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset,
> _definedAtomIvars,
> -                      NCS_DefinedAtomsV1);
> -
> -      // create chunk for attributes
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset, _attributes,
> -                      NCS_AttributesArrayV1);
> -    }
> -
> -    // create chunk for undefined atom array
> -    if (hasUndefines)
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset,
> _undefinedAtomIvars,
> -                      NCS_UndefinedAtomsV1);
> -
> -    // create chunk for shared library atom array
> -    if (hasSharedLibraries)
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset,
> -                      _sharedLibraryAtomIvars, NCS_SharedLibraryAtomsV1);
> -
> -     // create chunk for shared library atom array
> -    if (hasAbsolutes) {
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset,
> _absoluteAtomIvars,
> -                      NCS_AbsoluteAtomsV1);
> -
> -      // create chunk for attributes
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset, _absAttributes,
> -                      NCS_AbsoluteAttributesV1);
> -    }
> -
> -    // create chunk for symbol strings
> -    // pad end of string pool to 4-bytes
> -    while ((_stringPool.size() % 4) != 0)
> -      _stringPool.push_back('\0');
> -    fillChunkHeader(chunks[nextIndex++], nextFileOffset, _stringPool,
> -                    NCS_Strings);
> -
> -    // create chunk for referencesV2
> -    if (hasReferencesV1)
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset, _referencesV1,
> -                      NCS_ReferencesArrayV1);
> -
> -    // create chunk for referencesV2
> -    if (hasReferencesV2)
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset, _referencesV2,
> -                      NCS_ReferencesArrayV2);
> -
> -    // create chunk for target table
> -    if (hasTargetsTable) {
> -      NativeChunk& cht = chunks[nextIndex++];
> -      cht.signature = NCS_TargetsTable;
> -      cht.fileOffset = nextFileOffset;
> -      cht.fileSize = _targetsTableIndex.size() * sizeof(uint32_t);
> -      cht.elementCount = _targetsTableIndex.size();
> -      nextFileOffset = cht.fileOffset + cht.fileSize;
> -    }
> -
> -    // create chunk for addend table
> -    if (hasAddendTable) {
> -      NativeChunk& chad = chunks[nextIndex++];
> -      chad.signature = NCS_AddendsTable;
> -      chad.fileOffset = nextFileOffset;
> -      chad.fileSize = _addendsTableIndex.size() *
> sizeof(Reference::Addend);
> -      chad.elementCount = _addendsTableIndex.size();
> -      nextFileOffset = chad.fileOffset + chad.fileSize;
> -    }
> -
> -    // create chunk for content
> -    if (hasContent)
> -      fillChunkHeader(chunks[nextIndex++], nextFileOffset, _contentPool,
> -                      NCS_Content);
> -
> -    _headerBuffer->fileSize = nextFileOffset;
> -  }
> -
> -  template<class T>
> -  void fillChunkHeader(NativeChunk &chunk, uint32_t &nextFileOffset,
> -                       const std::vector<T> &data, uint32_t signature) {
> -    chunk.signature = signature;
> -    chunk.fileOffset = nextFileOffset;
> -    chunk.fileSize = data.size() * sizeof(T);
> -    chunk.elementCount = data.size();
> -    nextFileOffset = chunk.fileOffset + chunk.fileSize;
> -  }
> -
> -  // scan header to find particular chunk
> -  NativeChunk& findChunk(uint32_t signature) {
> -    const uint32_t chunkCount = _headerBuffer->chunkCount;
> -    NativeChunk* chunks =
> -
> reinterpret_cast<NativeChunk*>(reinterpret_cast<char*>(_headerBuffer)
> -                                     + sizeof(NativeFileHeader));
> -    for (uint32_t i=0; i < chunkCount; ++i) {
> -      if ( chunks[i].signature == signature )
> -        return chunks[i];
> -    }
> -    llvm_unreachable("findChunk() signature not found");
> -  }
> -
> -  // append atom name to string pool and return offset
> -  uint32_t getNameOffset(const Atom& atom) {
> -    return this->getNameOffset(atom.name());
> -  }
> -
> -  // check if name is already in pool or append and return offset
> -  uint32_t getSharedLibraryNameOffset(StringRef name) {
> -    assert(!name.empty());
> -    // look to see if this library name was used by another atom
> -    for (auto &it : _sharedLibraryNames)
> -      if (name.equals(it.first))
> -        return it.second;
> -    // first use of this library name
> -    uint32_t result = this->getNameOffset(name);
> -    _sharedLibraryNames.push_back(std::make_pair(name, result));
> -    return result;
> -  }
> -
> -  // append atom name to string pool and return offset
> -  uint32_t getNameOffset(StringRef name) {
> -    if ( name.empty() )
> -      return 0;
> -    uint32_t result = _stringPool.size();
> -    _stringPool.insert(_stringPool.end(), name.begin(), name.end());
> -    _stringPool.push_back(0);
> -    return result;
> -  }
> -
> -  // append atom cotent to content pool and return offset
> -  uint32_t getContentOffset(const DefinedAtom& atom) {
> -    if (!atom.occupiesDiskSpace())
> -      return 0;
> -    uint32_t result = _contentPool.size();
> -    ArrayRef<uint8_t> cont = atom.rawContent();
> -    _contentPool.insert(_contentPool.end(), cont.begin(), cont.end());
> -    return result;
> -  }
> -
> -  // reuse existing attributes entry or create a new one and return offet
> -  uint32_t getAttributeOffset(const DefinedAtom& atom) {
> -    NativeAtomAttributesV1 attrs = computeAttributesV1(atom);
> -    return getOrPushAttribute(_attributes, attrs);
> -  }
> -
> -  uint32_t getAttributeOffset(const AbsoluteAtom& atom) {
> -    NativeAtomAttributesV1 attrs = computeAbsoluteAttributes(atom);
> -    return getOrPushAttribute(_absAttributes, attrs);
> -  }
> -
> -  uint32_t getOrPushAttribute(std::vector<NativeAtomAttributesV1> &dest,
> -                              const NativeAtomAttributesV1 &attrs) {
> -    for (size_t i = 0, e = dest.size(); i < e; ++i) {
> -      if (!memcmp(&dest[i], &attrs, sizeof(attrs))) {
> -        // found that this set of attributes already used, so re-use
> -        return i * sizeof(attrs);
> -      }
> -    }
> -    // append new attribute set to end
> -    uint32_t result = dest.size() * sizeof(attrs);
> -    dest.push_back(attrs);
> -    return result;
> -  }
> -
> -  uint32_t sectionNameOffset(const DefinedAtom& atom) {
> -    // if section based on content, then no custom section name available
> -    if (atom.sectionChoice() == DefinedAtom::sectionBasedOnContent)
> -      return 0;
> -    StringRef name = atom.customSectionName();
> -    assert(!name.empty());
> -    // look to see if this section name was used by another atom
> -    for (auto &it : _sectionNames)
> -      if (name.equals(it.first))
> -        return it.second;
> -    // first use of this section name
> -    uint32_t result = this->getNameOffset(name);
> -    _sectionNames.push_back(std::make_pair(name, result));
> -    return result;
> -  }
> -
> -  NativeAtomAttributesV1 computeAttributesV1(const DefinedAtom& atom) {
> -    NativeAtomAttributesV1 attrs;
> -    attrs.sectionNameOffset = sectionNameOffset(atom);
> -    attrs.align             = atom.alignment().value;
> -    attrs.alignModulus      = atom.alignment().modulus;
> -    attrs.scope             = atom.scope();
> -    attrs.interposable      = atom.interposable();
> -    attrs.merge             = atom.merge();
> -    attrs.contentType       = atom.contentType();
> -    attrs.sectionChoice     = atom.sectionChoice();
> -    attrs.deadStrip         = atom.deadStrip();
> -    attrs.dynamicExport     = atom.dynamicExport();
> -    attrs.codeModel         = atom.codeModel();
> -    attrs.permissions       = atom.permissions();
> -    return attrs;
> -  }
> -
> -  NativeAtomAttributesV1 computeAbsoluteAttributes(const AbsoluteAtom&
> atom) {
> -    NativeAtomAttributesV1 attrs;
> -    attrs.scope = atom.scope();
> -    return attrs;
> -  }
> -
> -  // add references for this atom in a contiguous block in
> NCS_ReferencesArrayV2
> -  uint32_t getReferencesIndex(const DefinedAtom& atom, unsigned&
> refsCount) {
> -    size_t startRefSize = _referencesV2.size();
> -    uint32_t result = startRefSize;
> -    for (const Reference *ref : atom) {
> -      NativeReferenceIvarsV2 nref;
> -      nref.offsetInAtom = ref->offsetInAtom();
> -      nref.kindNamespace = (uint8_t)ref->kindNamespace();
> -      nref.kindArch = (uint8_t)ref->kindArch();
> -      nref.kindValue = ref->kindValue();
> -      nref.targetIndex = this->getTargetIndex(ref->target());
> -      nref.addend = ref->addend();
> -      nref.tag = ref->tag();
> -      _referencesV2.push_back(nref);
> -    }
> -    refsCount = _referencesV2.size() - startRefSize;
> -    return (refsCount == 0) ? 0 : result;
> -  }
> -
> -  uint32_t getTargetIndex(const Atom* target) {
> -    if ( target == nullptr )
> -      return NativeReferenceIvarsV2::noTarget;
> -    TargetToIndex::const_iterator pos = _targetsTableIndex.find(target);
> -    if ( pos != _targetsTableIndex.end() ) {
> -      return pos->second;
> -    }
> -    uint32_t result = _targetsTableIndex.size();
> -    _targetsTableIndex[target] = result;
> -    return result;
> -  }
> -
> -  void writeTargetTable(raw_ostream &out) {
> -    // Build table of target indexes
> -    uint32_t maxTargetIndex = _targetsTableIndex.size();
> -    assert(maxTargetIndex > 0);
> -    std::vector<uint32_t> targetIndexes(maxTargetIndex);
> -    for (auto &it : _targetsTableIndex) {
> -      const Atom* atom = it.first;
> -      uint32_t targetIndex = it.second;
> -      assert(targetIndex < maxTargetIndex);
> -
> -      TargetToIndex::iterator pos = _definedAtomIndex.find(atom);
> -      if (pos != _definedAtomIndex.end()) {
> -        targetIndexes[targetIndex] = pos->second;
> -        continue;
> -      }
> -      uint32_t base = _definedAtomIvars.size();
> -
> -      pos = _undefinedAtomIndex.find(atom);
> -      if (pos != _undefinedAtomIndex.end()) {
> -        targetIndexes[targetIndex] = pos->second + base;
> -        continue;
> -      }
> -      base += _undefinedAtomIndex.size();
> -
> -      pos = _sharedLibraryAtomIndex.find(atom);
> -      if (pos != _sharedLibraryAtomIndex.end()) {
> -        targetIndexes[targetIndex] = pos->second + base;
> -        continue;
> -      }
> -      base += _sharedLibraryAtomIndex.size();
> -
> -      pos = _absoluteAtomIndex.find(atom);
> -      assert(pos != _absoluteAtomIndex.end());
> -      targetIndexes[targetIndex] = pos->second + base;
> -    }
> -    // write table
> -    out.write((char*)&targetIndexes[0], maxTargetIndex *
> sizeof(uint32_t));
> -  }
> -
> -  uint32_t getAddendIndex(Reference::Addend addend) {
> -    if ( addend == 0 )
> -      return 0; // addend index zero is used to mean "no addend"
> -    AddendToIndex::const_iterator pos = _addendsTableIndex.find(addend);
> -    if ( pos != _addendsTableIndex.end() ) {
> -      return pos->second;
> -    }
> -    uint32_t result = _addendsTableIndex.size() + 1; // one-based index
> -    _addendsTableIndex[addend] = result;
> -    return result;
> -  }
> -
> -  void writeAddendTable(raw_ostream &out) {
> -    // Build table of addends
> -    uint32_t maxAddendIndex = _addendsTableIndex.size();
> -    std::vector<Reference::Addend> addends(maxAddendIndex);
> -    for (auto &it : _addendsTableIndex) {
> -      Reference::Addend addend = it.first;
> -      uint32_t index = it.second;
> -      assert(index <= maxAddendIndex);
> -      addends[index-1] = addend;
> -    }
> -    // write table
> -    out.write((char*)&addends[0],
> maxAddendIndex*sizeof(Reference::Addend));
> -  }
> -
> -  typedef std::vector<std::pair<StringRef, uint32_t>> NameToOffsetVector;
> -
> -  typedef llvm::DenseMap<const Atom*, uint32_t> TargetToIndex;
> -  typedef llvm::DenseMap<Reference::Addend, uint32_t> AddendToIndex;
> -
> -  NativeFileHeader*                       _headerBuffer;
> -  size_t                                  _headerBufferSize;
> -  std::vector<char>                       _stringPool;
> -  std::vector<uint8_t>                    _contentPool;
> -  std::vector<NativeDefinedAtomIvarsV1>   _definedAtomIvars;
> -  std::vector<NativeAtomAttributesV1>     _attributes;
> -  std::vector<NativeAtomAttributesV1>     _absAttributes;
> -  std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;
> -  std::vector<NativeSharedLibraryAtomIvarsV1> _sharedLibraryAtomIvars;
> -  std::vector<NativeAbsoluteAtomIvarsV1>  _absoluteAtomIvars;
> -  std::vector<NativeReferenceIvarsV1>     _referencesV1;
> -  std::vector<NativeReferenceIvarsV2>     _referencesV2;
> -  TargetToIndex                           _targetsTableIndex;
> -  TargetToIndex                           _definedAtomIndex;
> -  TargetToIndex                           _undefinedAtomIndex;
> -  TargetToIndex                           _sharedLibraryAtomIndex;
> -  TargetToIndex                           _absoluteAtomIndex;
> -  AddendToIndex                           _addendsTableIndex;
> -  NameToOffsetVector                      _sectionNames;
> -  NameToOffsetVector                      _sharedLibraryNames;
> -};
> -} // end namespace native
> -
> -std::unique_ptr<Writer> createWriterNative() {
> -  return std::unique_ptr<Writer>(new native::Writer());
> -}
> -} // end namespace lld
>
> Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Fri Apr 10 16:23:51
> 2015
> @@ -312,11 +312,10 @@ std::error_code FileCOFF::doParse() {
>
>    if (getMachineType() != llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
>        getMachineType() != _ctx.getMachineType()) {
> -    llvm::errs() << "module machine type '"
> -                 << getMachineName(getMachineType())
> -                 << "' conflicts with target machine type '"
> -                 << getMachineName(_ctx.getMachineType()) << "'\n";
> -    return NativeReaderError::conflicting_target_machine;
> +    return make_dynamic_error_code(Twine("module machine type '") +
> +                                   getMachineName(getMachineType()) +
> +                                   "' conflicts with target machine type
> '" +
> +                                   getMachineName(_ctx.getMachineType())
> + "'");
>    }
>
>    if (std::error_code ec = getReferenceArch(_referenceArch))
>
> Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp?rev=234641&r1=234640&r2=234641&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp Fri Apr 10
> 16:23:51 2015
> @@ -257,7 +257,7 @@ public:
>
>      // Check if the total size is valid.
>      if (std::size_t(end - buf) != sizeof(COFF::ImportHeader) + dataSize)
> -      return make_error_code(NativeReaderError::unknown_file_format);
> +      return make_dynamic_error_code(StringRef("Broken import library"));
>
>      uint16_t hint = read16le(buf + offsetof(COFF::ImportHeader,
> OrdinalHint));
>      StringRef symbolName(buf + sizeof(COFF::ImportHeader));
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150412/a32ed380/attachment.html>


More information about the llvm-commits mailing list