//===- lib/ReaderWriter/MachO/GOTPass.cpp -----------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This linker pass transforms all GOT kind references to real references.
/// That is, in assembly you can write something like:
///     movq foo@GOTPCREL(%rip), %rax
/// which means you want to load a pointer to "foo" out of the GOT (global
/// Offsets Table). In the object file, the Atom containing this instruction
/// has a Reference whose target is an Atom named "foo" and the Reference
/// kind is a GOT load.  The linker needs to instantiate a pointer sized
/// GOT entry.  This is done be creating a GOT Atom to represent that pointer
/// sized data in this pass, and altering the Atom graph so the Reference now
/// points to the GOT Atom entry (corresponding to "foo") and changing the
/// Reference Kind to reflect it is now pointing to a GOT entry (rather
/// then needing a GOT entry).
///
/// There is one optimization the linker can do here.  If the target of the GOT
/// is in the same linkage unit and does not need to be interposable, and
/// the GOT use is just a load (not some other operation), this pass can
/// transform that load into an LEA (add).  This optimizes away one memory load
/// which at runtime that could stall the pipeline.  This optimization only
/// works for architectures in which a (GOT) load instruction can be change to
/// an LEA instruction that is the same size.  The method isGOTAccess() should
/// only return true for "canBypassGOT" if this optimization is supported.
///
//===----------------------------------------------------------------------===//

#include "ArchHandler.h"
#include "File.h"
#include "MachOPasses.h"
#include "lld/Common/LLVM.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
#include "lld/Core/Simple.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"

namespace lld {
namespace mach_o {

//
//  GOT Entry Atom created by the GOT pass.
//
class GOTEntryAtom : public SimpleDefinedAtom {
public:
  GOTEntryAtom(const File &file, bool is64, StringRef name)
    : SimpleDefinedAtom(file), _is64(is64), _name(name) { }

  ~GOTEntryAtom() override = default;

  ContentType contentType() const override {
    return DefinedAtom::typeGOT;
  }

  Alignment alignment() const override {
    return _is64 ? 8 : 4;
  }

  uint64_t size() const override {
    return _is64 ? 8 : 4;
  }

  ContentPermissions permissions() const override {
    return DefinedAtom::permRW_;
  }

  ArrayRef<uint8_t> rawContent() const override {
    static const uint8_t zeros[] =
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    return llvm::makeArrayRef(zeros, size());
  }

  StringRef slotName() const {
    return _name;
  }

private:
  const bool _is64;
  StringRef _name;
};

/// Pass for instantiating and optimizing GOT slots.
///
class GOTPass : public Pass {
public:
  GOTPass(const MachOLinkingContext &context)
      : _ctx(context), _archHandler(_ctx.archHandler()),
        _file(*_ctx.make_file<MachOFile>("<mach-o GOT Pass>")) {
    _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
  }

private:
  llvm::Error perform(SimpleFile &mergedFile) override {
    // Scan all references in all atoms.
    for (const DefinedAtom *atom : mergedFile.defined()) {
      for (const Reference *ref : *atom) {
        // Look at instructions accessing the GOT.
        bool canBypassGOT;
        if (!_archHandler.isGOTAccess(*ref, canBypassGOT))
          continue;
        const Atom *target = ref->target();
        assert(target != nullptr);

        if (!shouldReplaceTargetWithGOTAtom(target, canBypassGOT)) {
          // Update reference kind to reflect that target is a direct access.
          _archHandler.updateReferenceToGOT(ref, false);
        } else {
          // Replace the target with a reference to a GOT entry.
          const DefinedAtom *gotEntry = makeGOTEntry(target);
          const_cast<Reference *>(ref)->setTarget(gotEntry);
          // Update reference kind to reflect that target is now a GOT entry.
          _archHandler.updateReferenceToGOT(ref, true);
        }
      }
    }

    // Sort and add all created GOT Atoms to master file
    std::vector<const GOTEntryAtom *> entries;
    entries.reserve(_targetToGOT.size());
    for (auto &it : _targetToGOT)
      entries.push_back(it.second);
    std::sort(entries.begin(), entries.end(),
              [](const GOTEntryAtom *left, const GOTEntryAtom *right) {
      return (left->slotName().compare(right->slotName()) < 0);
    });
    for (const GOTEntryAtom *slot : entries)
      mergedFile.addAtom(*slot);

    return llvm::Error::success();
  }

  bool shouldReplaceTargetWithGOTAtom(const Atom *target, bool canBypassGOT) {
    // Accesses to shared library symbols must go through GOT.
    if (isa<SharedLibraryAtom>(target))
      return true;
    // Accesses to interposable symbols in same linkage unit must also go
    // through GOT.
    const DefinedAtom *defTarget = dyn_cast<DefinedAtom>(target);
    if (defTarget != nullptr &&
        defTarget->interposable() != DefinedAtom::interposeNo) {
      assert(defTarget->scope() != DefinedAtom::scopeTranslationUnit);
      return true;
    }
    // Target does not require indirection.  So, if instruction allows GOT to be
    // by-passed, do that optimization and don't create GOT entry.
    return !canBypassGOT;
  }

  const DefinedAtom *makeGOTEntry(const Atom *target) {
    auto pos = _targetToGOT.find(target);
    if (pos == _targetToGOT.end()) {
      auto *gotEntry = new (_file.allocator())
          GOTEntryAtom(_file, _ctx.is64Bit(), target->name());
      _targetToGOT[target] = gotEntry;
      const ArchHandler::ReferenceInfo &nlInfo = _archHandler.stubInfo().
                                                nonLazyPointerReferenceToBinder;
      gotEntry->addReference(Reference::KindNamespace::mach_o, nlInfo.arch,
                             nlInfo.kind, 0, target, 0);
      return gotEntry;
    }
    return pos->second;
  }

  const MachOLinkingContext &_ctx;
  mach_o::ArchHandler                             &_archHandler;
  MachOFile                                       &_file;
  llvm::DenseMap<const Atom*, const GOTEntryAtom*> _targetToGOT;
};

void addGOTPass(PassManager &pm, const MachOLinkingContext &ctx) {
  assert(ctx.needsGOTPass());
  pm.add(std::make_unique<GOTPass>(ctx));
}

} // end namespace mach_o
} // end namespace lld
