//===- lld/ReaderWriter/MachOLinkingContext.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_MACHO_LINKING_CONTEXT_H
#define LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H

#include "lld/Core/LinkingContext.h"
#include "lld/Core/Reader.h"
#include "lld/Core/Writer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Support/ErrorHandling.h"
#include <set>

using llvm::MachO::HeaderFileType;

namespace lld {

namespace mach_o {
class ArchHandler;
class MachODylibFile;
class MachOFile;
class SectCreateFile;
}

class MachOLinkingContext : public LinkingContext {
public:
  MachOLinkingContext();
  ~MachOLinkingContext() override;

  enum Arch {
    arch_unknown,
    arch_ppc,
    arch_x86,
    arch_x86_64,
    arch_armv6,
    arch_armv7,
    arch_armv7s,
    arch_arm64,
  };

  enum class OS {
    unknown,
    macOSX,
    iOS,
    iOS_simulator
  };

  enum class ExportMode {
    globals,    // Default, all global symbols exported.
    whiteList,  // -exported_symbol[s_list], only listed symbols exported.
    blackList   // -unexported_symbol[s_list], no listed symbol exported.
  };

  enum class DebugInfoMode {
    addDebugMap,    // Default
    noDebugMap      // -S option
  };

  enum class UndefinedMode {
    error,
    warning,
    suppress,
    dynamicLookup
  };

  enum ObjCConstraint {
    objc_unknown = 0,
    objc_supports_gc = 2,
    objc_gc_only = 4,
    // Image optimized by dyld = 8
    // GC compaction = 16
    objc_retainReleaseForSimulator = 32,
    objc_retainRelease
  };

  /// Initializes the context to sane default values given the specified output
  /// file type, arch, os, and minimum os version.  This should be called before
  /// other setXXX() methods.
  void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion,
                 bool exportDynamicSymbols);

  void addPasses(PassManager &pm) override;
  bool validateImpl(raw_ostream &diagnostics) override;
  std::string demangle(StringRef symbolName) const override;

  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;

  /// Creates a new file which is owned by the context.  Returns a pointer to
  /// the new file.
  template <class T, class... Args>
  typename std::enable_if<!std::is_array<T>::value, T *>::type
  make_file(Args &&... args) const {
    auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
    auto *filePtr = file.get();
    auto *ctx = const_cast<MachOLinkingContext *>(this);
    ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
    return filePtr;
  }

  uint32_t getCPUType() const;
  uint32_t getCPUSubType() const;

  bool addEntryPointLoadCommand() const;
  bool addUnixThreadLoadCommand() const;
  bool outputTypeHasEntry() const;
  bool is64Bit() const;

  virtual uint64_t pageZeroSize() const { return _pageZeroSize; }
  virtual uint64_t pageSize() const { return _pageSize; }

  mach_o::ArchHandler &archHandler() const;

  HeaderFileType outputMachOType() const { return _outputMachOType; }

  Arch arch() const { return _arch; }
  StringRef archName() const { return nameFromArch(_arch); }
  OS os() const { return _os; }

  ExportMode exportMode() const { return _exportMode; }
  void setExportMode(ExportMode mode) { _exportMode = mode; }
  void addExportSymbol(StringRef sym);
  bool exportRestrictMode() const { return _exportMode != ExportMode::globals; }
  bool exportSymbolNamed(StringRef sym) const;

  DebugInfoMode debugInfoMode() const { return _debugInfoMode; }
  void setDebugInfoMode(DebugInfoMode mode) {
    _debugInfoMode = mode;
  }

  void appendOrderedSymbol(StringRef symbol, StringRef filename);

  bool keepPrivateExterns() const { return _keepPrivateExterns; }
  void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; }
  bool demangleSymbols() const { return _demangle; }
  void setDemangleSymbols(bool d) { _demangle = d; }
  bool mergeObjCCategories() const { return _mergeObjCCategories; }
  void setMergeObjCCategories(bool v) { _mergeObjCCategories = v; }
  /// Create file at specified path which will contain a binary encoding
  /// of all input and output file paths.
  std::error_code createDependencyFile(StringRef path);
  void addInputFileDependency(StringRef path) const;
  void addInputFileNotFound(StringRef path) const;
  void addOutputFileDependency(StringRef path) const;

  bool minOS(StringRef mac, StringRef iOS) const;
  void setDoNothing(bool value) { _doNothing = value; }
  bool doNothing() const { return _doNothing; }
  bool printAtoms() const { return _printAtoms; }
  bool testingFileUsage() const { return _testingFileUsage; }
  const StringRefVector &searchDirs() const { return _searchDirs; }
  const StringRefVector &frameworkDirs() const { return _frameworkDirs; }
  void setSysLibRoots(const StringRefVector &paths);
  const StringRefVector &sysLibRoots() const { return _syslibRoots; }
  bool PIE() const { return _pie; }
  void setPIE(bool pie) { _pie = pie; }
  bool generateVersionLoadCommand() const {
    return _generateVersionLoadCommand;
  }
  void setGenerateVersionLoadCommand(bool v) {
    _generateVersionLoadCommand = v;
  }

  bool generateFunctionStartsLoadCommand() const {
    return _generateFunctionStartsLoadCommand;
  }
  void setGenerateFunctionStartsLoadCommand(bool v) {
    _generateFunctionStartsLoadCommand = v;
  }

  bool generateDataInCodeLoadCommand() const {
    return _generateDataInCodeLoadCommand;
  }
  void setGenerateDataInCodeLoadCommand(bool v) {
    _generateDataInCodeLoadCommand = v;
  }

  uint64_t stackSize() const { return _stackSize; }
  void setStackSize(uint64_t stackSize) { _stackSize = stackSize; }

  uint64_t baseAddress() const { return _baseAddress; }
  void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; }

  ObjCConstraint objcConstraint() const { return _objcConstraint; }

  uint32_t osMinVersion() const { return _osMinVersion; }

  uint32_t sdkVersion() const { return _sdkVersion; }
  void setSdkVersion(uint64_t v) { _sdkVersion = v; }

  uint64_t sourceVersion() const { return _sourceVersion; }
  void setSourceVersion(uint64_t v) { _sourceVersion = v; }

  uint32_t swiftVersion() const { return _swiftVersion; }

  /// \brief Checks whether a given path on the filesystem exists.
  ///
  /// When running in -test_file_usage mode, this method consults an
  /// internally maintained list of files that exist (provided by -path_exists)
  /// instead of the actual filesystem.
  bool pathExists(StringRef path) const;

  /// Like pathExists() but only used on files - not directories.
  bool fileExists(StringRef path) const;

  /// \brief Adds any library search paths derived from the given base, possibly
  /// modified by -syslibroots.
  ///
  /// The set of paths added consists of approximately all syslibroot-prepended
  /// versions of libPath that exist, or the original libPath if there are none
  /// for whatever reason. With various edge-cases for compatibility.
  void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false);

  /// \brief Determine whether -lFoo can be resolve within the given path, and
  /// return the filename if so.
  ///
  /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in
  /// that order, unless Foo ends in ".o", in which case only the exact file
  /// matches (e.g. -lfoo.o would only find foo.o).
  llvm::Optional<StringRef> searchDirForLibrary(StringRef path,
                                                StringRef libName) const;

  /// \brief Iterates through all search path entries looking for libName (as
  /// specified by -lFoo).
  llvm::Optional<StringRef> searchLibrary(StringRef libName) const;

  /// Add a framework search path.  Internally, this method may be prepended
  /// the path with syslibroot.
  void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false);

  /// \brief Iterates through all framework directories looking for
  /// Foo.framework/Foo (when fwName = "Foo").
  llvm::Optional<StringRef> findPathForFramework(StringRef fwName) const;

  /// \brief The dylib's binary compatibility version, in the raw uint32 format.
  ///
  /// When building a dynamic library, this is the compatibility version that
  /// gets embedded into the result. Other Mach-O binaries that link against
  /// this library will store the compatibility version in its load command. At
  /// runtime, the loader will verify that the binary is compatible with the
  /// installed dynamic library.
  uint32_t compatibilityVersion() const { return _compatibilityVersion; }

  /// \brief The dylib's current version, in the the raw uint32 format.
  ///
  /// When building a dynamic library, this is the current version that gets
  /// embedded into the result. Other Mach-O binaries that link against
  /// this library will store the compatibility version in its load command.
  uint32_t currentVersion() const { return _currentVersion; }

  /// \brief The dylib's install name.
  ///
  /// Binaries that link against the dylib will embed this path into the dylib
  /// load command. When loading the binaries at runtime, this is the location
  /// on disk that the loader will look for the dylib.
  StringRef installName() const { return _installName; }

  /// \brief Whether or not the dylib has side effects during initialization.
  ///
  /// Dylibs marked as being dead strippable provide the guarantee that loading
  /// the dylib has no side effects, allowing the linker to strip out the dylib
  /// when linking a binary that does not use any of its symbols.
  bool deadStrippableDylib() const { return _deadStrippableDylib; }

  /// \brief Whether or not to use flat namespace.
  ///
  /// MachO usually uses a two-level namespace, where each external symbol
  /// referenced by the target is associated with the dylib that will provide
  /// the symbol's definition at runtime. Using flat namespace overrides this
  /// behavior: the linker searches all dylibs on the command line and all
  /// dylibs those original dylibs depend on, but does not record which dylib
  /// an external symbol came from. At runtime dyld again searches all images
  /// and uses the first definition it finds. In addition, any undefines in
  /// loaded flat_namespace dylibs must be resolvable at build time.
  bool useFlatNamespace() const { return _flatNamespace; }

  /// \brief How to handle undefined symbols.
  ///
  /// Options are:
  ///  * error: Report an error and terminate linking.
  ///  * warning: Report a warning, but continue linking.
  ///  * suppress: Ignore and continue linking.
  ///  * dynamic_lookup: For use with -twolevel namespace: Records source dylibs
  ///    for symbols that are defined in a linked dylib at static link time.
  ///    Undefined symbols are handled by searching all loaded images at
  ///    runtime.
  UndefinedMode undefinedMode() const { return _undefinedMode; }

  /// \brief The path to the executable that will load the bundle at runtime.
  ///
  /// When building a Mach-O bundle, this executable will be examined if there
  /// are undefined symbols after the main link phase. It is expected that this
  /// binary will be loading the bundle at runtime and will provide the symbols
  /// at that point.
  StringRef bundleLoader() const { return _bundleLoader; }

  void setCompatibilityVersion(uint32_t vers) { _compatibilityVersion = vers; }
  void setCurrentVersion(uint32_t vers) { _currentVersion = vers; }
  void setInstallName(StringRef name) { _installName = name; }
  void setDeadStrippableDylib(bool deadStrippable) {
    _deadStrippableDylib = deadStrippable;
  }
  void setUseFlatNamespace(bool flatNamespace) {
    _flatNamespace = flatNamespace;
  }

  void setUndefinedMode(UndefinedMode undefinedMode) {
    _undefinedMode = undefinedMode;
  }

  void setBundleLoader(StringRef loader) { _bundleLoader = loader; }
  void setPrintAtoms(bool value=true) { _printAtoms = value; }
  void setTestingFileUsage(bool value = true) {
    _testingFileUsage = value;
  }
  void addExistingPathForDebug(StringRef path) {
    _existingPaths.insert(path);
  }

  void addRpath(StringRef rpath);
  const StringRefVector &rpaths() const { return _rpaths; }

  /// Add section alignment constraint on final layout.
  void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align);

  /// \brief Add a section based on a command-line sectcreate option.
  void addSectCreateSection(StringRef seg, StringRef sect,
                            std::unique_ptr<MemoryBuffer> content);

  /// Returns true if specified section had alignment constraints.
  bool sectionAligned(StringRef seg, StringRef sect, uint16_t &align) const;

  StringRef dyldPath() const { return "/usr/lib/dyld"; }

  /// Stub creation Pass should be run.
  bool needsStubsPass() const;

  // GOT creation Pass should be run.
  bool needsGOTPass() const;

  /// Pass to add TLV sections.
  bool needsTLVPass() const;

  /// Pass to transform __compact_unwind into __unwind_info should be run.
  bool needsCompactUnwindPass() const;

  /// Pass to add shims switching between thumb and arm mode.
  bool needsShimPass() const;

  /// Pass to add objc image info and optimized objc data.
  bool needsObjCPass() const;

  /// Magic symbol name stubs will need to help lazy bind.
  StringRef binderSymbolName() const;

  /// Used to keep track of direct and indirect dylibs.
  void registerDylib(mach_o::MachODylibFile *dylib, bool upward) const;

  // Reads a file from disk to memory. Returns only a needed chunk
  // if a fat binary.
  ErrorOr<std::unique_ptr<MemoryBuffer>> getMemoryBuffer(StringRef path);

  /// Used to find indirect dylibs. Instantiates a MachODylibFile if one
  /// has not already been made for the requested dylib.  Uses -L and -F
  /// search paths to allow indirect dylibs to be overridden.
  mach_o::MachODylibFile* findIndirectDylib(StringRef path);

  uint32_t dylibCurrentVersion(StringRef installName) const;

  uint32_t dylibCompatVersion(StringRef installName) const;

  ArrayRef<mach_o::MachODylibFile*> allDylibs() const {
    return _allDylibs;
  }

  /// Creates a copy (owned by this MachOLinkingContext) of a string.
  StringRef copy(StringRef str) { return str.copy(_allocator); }

  /// If the memoryBuffer is a fat file with a slice for the current arch,
  /// this method will return the offset and size of that slice.
  bool sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset, uint32_t &size);

  /// Returns if a command line option specified dylib is an upward link.
  bool isUpwardDylib(StringRef installName) const;

  static bool isThinObjectFile(StringRef path, Arch &arch);
  static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype);
  static Arch archFromName(StringRef archName);
  static StringRef nameFromArch(Arch arch);
  static uint32_t cpuTypeFromArch(Arch arch);
  static uint32_t cpuSubtypeFromArch(Arch arch);
  static bool is64Bit(Arch arch);
  static bool isHostEndian(Arch arch);
  static bool isBigEndian(Arch arch);

  /// Construct 32-bit value from string "X.Y.Z" where
  /// bits are xxxx.yy.zz.  Largest number is 65535.255.255
  static bool parsePackedVersion(StringRef str, uint32_t &result);

  /// Construct 64-bit value from string "A.B.C.D.E" where
  /// bits are aaaa.bb.cc.dd.ee.  Largest number is 16777215.1023.1023.1023.1023
  static bool parsePackedVersion(StringRef str, uint64_t &result);

  void finalizeInputFiles() override;

  llvm::Error handleLoadedFile(File &file) override;

  bool customAtomOrderer(const DefinedAtom *left, const DefinedAtom *right,
                         bool &leftBeforeRight) const;

  /// Return the 'flat namespace' file. This is the file that supplies
  /// atoms for otherwise undefined symbols when the -flat_namespace or
  /// -undefined dynamic_lookup options are used.
  File* flatNamespaceFile() const { return _flatNamespaceFile; }

private:
  Writer &writer() const override;
  mach_o::MachODylibFile* loadIndirectDylib(StringRef path);
  void checkExportWhiteList(const DefinedAtom *atom) const;
  void checkExportBlackList(const DefinedAtom *atom) const;
  struct ArchInfo {
    StringRef                 archName;
    MachOLinkingContext::Arch arch;
    bool                      littleEndian;
    uint32_t                  cputype;
    uint32_t                  cpusubtype;
  };

  struct SectionAlign {
    StringRef segmentName;
    StringRef sectionName;
    uint16_t  align;
  };

  struct OrderFileNode {
    StringRef fileFilter;
    unsigned  order;
  };

  static bool findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
                             const DefinedAtom *atom, unsigned &ordinal);

  static ArchInfo _s_archInfos[];

  std::set<StringRef> _existingPaths; // For testing only.
  StringRefVector _searchDirs;
  StringRefVector _syslibRoots;
  StringRefVector _frameworkDirs;
  HeaderFileType _outputMachOType = llvm::MachO::MH_EXECUTE;
  bool _outputMachOTypeStatic = false; // Disambiguate static vs dynamic prog
  bool _doNothing = false;             // for -help and -v which just print info
  bool _pie = false;
  Arch _arch = arch_unknown;
  OS _os = OS::macOSX;
  uint32_t _osMinVersion = 0;
  uint32_t _sdkVersion = 0;
  uint64_t _sourceVersion = 0;
  uint64_t _pageZeroSize = 0;
  uint64_t _pageSize = 4096;
  uint64_t _baseAddress = 0;
  uint64_t _stackSize = 0;
  uint32_t _compatibilityVersion = 0;
  uint32_t _currentVersion = 0;
  ObjCConstraint _objcConstraint = objc_unknown;
  uint32_t _swiftVersion = 0;
  StringRef _installName;
  StringRefVector _rpaths;
  bool _flatNamespace = false;
  UndefinedMode _undefinedMode = UndefinedMode::error;
  bool _deadStrippableDylib = false;
  bool _printAtoms = false;
  bool _testingFileUsage = false;
  bool _keepPrivateExterns = false;
  bool _demangle = false;
  bool _mergeObjCCategories = true;
  bool _generateVersionLoadCommand = false;
  bool _generateFunctionStartsLoadCommand = false;
  bool _generateDataInCodeLoadCommand = false;
  StringRef _bundleLoader;
  mutable std::unique_ptr<mach_o::ArchHandler> _archHandler;
  mutable std::unique_ptr<Writer> _writer;
  std::vector<SectionAlign> _sectAligns;
  mutable llvm::StringMap<mach_o::MachODylibFile*> _pathToDylibMap;
  mutable std::vector<mach_o::MachODylibFile*> _allDylibs;
  mutable std::set<mach_o::MachODylibFile*> _upwardDylibs;
  mutable std::vector<std::unique_ptr<File>> _indirectDylibs;
  mutable std::mutex _dylibsMutex;
  ExportMode _exportMode = ExportMode::globals;
  llvm::StringSet<> _exportedSymbols;
  DebugInfoMode _debugInfoMode = DebugInfoMode::addDebugMap;
  std::unique_ptr<llvm::raw_fd_ostream> _dependencyInfo;
  llvm::StringMap<std::vector<OrderFileNode>> _orderFiles;
  unsigned _orderFileEntries = 0;
  File *_flatNamespaceFile = nullptr;
  mach_o::SectCreateFile *_sectCreateFile = nullptr;
};

} // end namespace lld

#endif // LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H
