//===------ lib/ReaderWriter/MachO/LayoutPass.h - Handles Layout of atoms -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
#define LLD_READER_WRITER_MACHO_LAYOUT_PASS_H

#include "lld/Core/File.h"
#include "lld/Core/Pass.h"
#include "lld/Core/Reader.h"
#include "lld/Core/Simple.h"
#include "llvm/ADT/DenseMap.h"
#include <map>
#include <string>
#include <vector>

namespace lld {
class DefinedAtom;
class SimpleFile;

namespace mach_o {

/// This linker pass does the layout of the atoms. The pass is done after the
/// order their .o files were found on the command line, then by order of the
/// atoms (address) in the .o file.  But some atoms have a preferred location
/// in their section (such as pinned to the start or end of the section), so
/// the sort must take that into account too.
class LayoutPass : public Pass {
public:
  struct SortKey {
    SortKey(OwningAtomPtr<DefinedAtom> &&atom,
            const DefinedAtom *root, uint64_t override)
    : _atom(std::move(atom)), _root(root), _override(override) {}
    OwningAtomPtr<DefinedAtom> _atom;
    const DefinedAtom *_root;
    uint64_t _override;

    // Note, these are only here to appease MSVC bots which didn't like
    // the same methods being implemented/deleted in OwningAtomPtr.
    SortKey(SortKey &&key) : _atom(std::move(key._atom)), _root(key._root),
                             _override(key._override) {
      key._root = nullptr;
    }

    SortKey &operator=(SortKey &&key) {
      _atom = std::move(key._atom);
      _root = key._root;
      key._root = nullptr;
      _override = key._override;
      return *this;
    }

  private:
    SortKey(const SortKey &) = delete;
    void operator=(const SortKey&) = delete;
  };

  typedef std::function<bool (const DefinedAtom *left, const DefinedAtom *right,
                              bool &leftBeforeRight)> SortOverride;

  LayoutPass(const Registry &registry, SortOverride sorter);

  /// Sorts atoms in mergedFile by content type then by command line order.
  llvm::Error perform(SimpleFile &mergedFile) override;

  ~LayoutPass() override = default;

private:
  // Build the followOn atoms chain as specified by the kindLayoutAfter
  // reference type
  void buildFollowOnTable(const File::AtomRange<DefinedAtom> &range);

  // Build a map of Atoms to ordinals for sorting the atoms
  void buildOrdinalOverrideMap(const File::AtomRange<DefinedAtom> &range);

  const Registry &_registry;
  SortOverride _customSorter;

  typedef llvm::DenseMap<const DefinedAtom *, const DefinedAtom *> AtomToAtomT;
  typedef llvm::DenseMap<const DefinedAtom *, uint64_t> AtomToOrdinalT;

  // A map to be used to sort atoms. It represents the order of atoms in the
  // result; if Atom X is mapped to atom Y in this map, X will be located
  // immediately before Y in the output file. Y might be mapped to another
  // atom, constructing a follow-on chain. An atom cannot be mapped to more
  // than one atom unless all but one atom are of size zero.
  AtomToAtomT _followOnNexts;

  // A map to be used to sort atoms. It's a map from an atom to its root of
  // follow-on chain. A root atom is mapped to itself. If an atom is not in
  // _followOnNexts, the atom is not in this map, and vice versa.
  AtomToAtomT _followOnRoots;

  AtomToOrdinalT _ordinalOverrideMap;

  // Helper methods for buildFollowOnTable().
  const DefinedAtom *findAtomFollowedBy(const DefinedAtom *targetAtom);
  bool checkAllPrevAtomsZeroSize(const DefinedAtom *targetAtom);

  void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root);

  std::vector<SortKey> decorate(File::AtomRange<DefinedAtom> &atomRange) const;

  void undecorate(File::AtomRange<DefinedAtom> &atomRange,
                  std::vector<SortKey> &keys) const;

  // Check if the follow-on graph is a correct structure. For debugging only.
  void checkFollowonChain(const File::AtomRange<DefinedAtom> &range);
};

} // namespace mach_o
} // namespace lld

#endif // LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
